Resources/js/d/dascyllus.js
changeset 0 80c32ef237c6
child 1 b3419d05eabb
equal deleted inserted replaced
-1:000000000000 0:80c32ef237c6
       
     1 
       
     2 /*######################################################################
       
     3 ### D A S C Y L L U S   N A M E S P A C E
       
     4 ######################################################################*/
       
     5 var D = {
       
     6 
       
     7 	// Versions
       
     8 	platform:     Ti.getPlatform(),
       
     9 	name:         Ti.API.Application.getName(),
       
    10 	version:      Ti.API.Application.getVersion(),
       
    11 	ti_version:   Ti.getVersion(),
       
    12 	architecture: Ti.Platform.getArchitecture(),
       
    13 
       
    14 	// Declared windows, for easy referencing
       
    15 	window: {},
       
    16 
       
    17 	// Very first run of Dasycllus?
       
    18 	firstrun: false,
       
    19 
       
    20 	// Persistent storage DB handle.
       
    21 	db: null,
       
    22 
       
    23 	// The current TF server we'll be connected to;
       
    24 	//     uri: http://localhost:8080/
       
    25 	//     version: Thingfish 0.5.0 (build ...)
       
    26 	//
       
    27 	tf: null,
       
    28 
       
    29 
       
    30 	// Open a handle to the local database, initializing it
       
    31 	// if necessary and performing rudamentary upwards migrations.
       
    32 	//
       
    33 	initDB: function() {
       
    34 		this.db = Ti.Database.openFile(
       
    35 			Ti.Filesystem.getFile(
       
    36 				Ti.Filesystem.getApplicationDataDirectory(), 'dascyllus.db'
       
    37 			)
       
    38 		);
       
    39 
       
    40 		var rv = this.db.execute( 'PRAGMA user_version' );
       
    41 		var schema_version = parseInt( rv.fieldByName('user_version') );
       
    42 
       
    43 		var schemas_dir = Ti.Filesystem.getFile(
       
    44 				Ti.Filesystem.getApplicationDirectory(), 'sql' );
       
    45 		var current_version = schemas_dir.getDirectoryListing().length;
       
    46 
       
    47 		if ( schema_version == 0 ) {
       
    48 			this.notify( 'Welcome!', 'Dascyllus defaults installed.' );
       
    49 			this.firstrun = true;
       
    50 		}
       
    51 
       
    52 		if ( schema_version != current_version ) {
       
    53 			console.log( 'Dascyllus DB at version ' + schema_version +
       
    54 					', needs to be upgraded to ' + current_version + '.' );
       
    55 
       
    56 			while ( schema_version != current_version ) {
       
    57 				var update_version = schema_version + 1;
       
    58 				console.log( '  updating to version ' + update_version );
       
    59 
       
    60 				var line;
       
    61 				var schema_file = Ti.Filesystem.getFileStream(
       
    62 						Ti.Filesystem.getApplicationDirectory(), 'sql', update_version + '.sql' );
       
    63 				schema_file.open();
       
    64 
       
    65 				this.db.execute( 'BEGIN' );
       
    66 				while ( line = schema_file.readLine() ) this.db.execute( line.toString() );
       
    67 
       
    68 				this.db.execute( 'PRAGMA user_version = ' + update_version  );
       
    69 				this.db.execute( 'COMMIT' );
       
    70 
       
    71 				schema_version = update_version;
       
    72 				schema_file.close();
       
    73 			}
       
    74 		}
       
    75 
       
    76 		return this.db;
       
    77 	},
       
    78 
       
    79 
       
    80 	// Return a preference's current value, or null if nonexistent.
       
    81 	//
       
    82 	getPref: function( pref ) {
       
    83 		var row = this.db.execute( "SELECT val FROM prefs WHERE key=?", pref );
       
    84 		if ( ! row.isValidRow() ) return null;
       
    85 
       
    86 		var value = row.fieldByName( 'val' );
       
    87 		row.close();
       
    88 
       
    89 		return value;
       
    90 	},
       
    91 
       
    92 
       
    93 	// Return a preference's current value as a boolean.
       
    94 	//
       
    95 	getBoolPref: function( pref ) {
       
    96 		return this.getPref( pref ) == '1'
       
    97 	},
       
    98 
       
    99 
       
   100 	// Insert or update a preference value.
       
   101 	//
       
   102 	setPref: function( pref, value ) {
       
   103 		this.db.execute( 'BEGIN' );
       
   104 
       
   105 		// Row already exists, remove it first.
       
   106 		if ( this.getPref( pref ) != null )
       
   107 			this.db.execute( 'DELETE FROM prefs WHERE key=?', pref );
       
   108 
       
   109 		this.db.execute( 'INSERT INTO prefs VALUES ( ?, ? )', pref, value );
       
   110 		this.db.execute( 'COMMIT' );
       
   111 	},
       
   112 
       
   113 
       
   114 	// Set a bool preference value.
       
   115 	//
       
   116 	setBoolPref: function( pref, value ) {
       
   117 		this.setPref( pref, (value ? '1' : '0') );
       
   118 	},
       
   119 
       
   120 
       
   121 	// Generic delayed callback that returns the timer handle.
       
   122 	//
       
   123 	delay: (function() {
       
   124 		var timer = null;
       
   125 		return function( callback, ms, clear_previous ) {
       
   126 			if ( clear_previous) clearTimeout( timer );
       
   127 			timer = setTimeout( callback, ms );
       
   128 			return timer;
       
   129 		};
       
   130 	})(),
       
   131 
       
   132 
       
   133 	// Create and show a new notification.
       
   134 	//
       
   135 	notify: function( title, message, callback ) {
       
   136 		if ( ! callback ) callback = function(){};
       
   137 
       
   138 		var notification = Ti.Notification.createNotification({
       
   139 			'title' : title,
       
   140 			'message' : message,
       
   141 			'timeout' : 10,
       
   142 			'callback' : callback,
       
   143 		});
       
   144 
       
   145 		notification.show();
       
   146 		return notification;
       
   147 	},
       
   148 
       
   149 
       
   150 	// Attempt a connection to a remote Thingfish server, and
       
   151 	// populate the D.tf variable.
       
   152 	//
       
   153 	checkServer: function( uri ) {
       
   154 		this.tf = null;
       
   155 
       
   156 		var serverOk = function( data, status, xhr ) {
       
   157 			var info = xhr.getResponseHeader( 'x-thingfish' );
       
   158 			if ( info ) {
       
   159 				D.tf = {
       
   160 					uri: uri,
       
   161 					version: data.version
       
   162 				};
       
   163 				D.notify( 'Connected.', info );
       
   164 			}
       
   165 			else {
       
   166 				D.notify( 'Unable to connect.', 'Not a Thingfish server?' );
       
   167 			}
       
   168 		};
       
   169 
       
   170 		$.ajax({
       
   171 			url:      uri,
       
   172 			sync:     false,
       
   173 			success:  serverOk,
       
   174 			error:    function( xhr, status, err ) {
       
   175 				D.notify( 'Unable to connect.', err );
       
   176 			},
       
   177 			dataType: 'json'
       
   178 		});
       
   179 	},
       
   180 
       
   181 
       
   182 	// Build the main menu.
       
   183 	//
       
   184 	setupMenu: function() {
       
   185 		var menu  = Ti.UI.createMenu();
       
   186 		var yep   = Ti.UI.createMenuItem( 'Yep' );
       
   187 
       
   188 		yep.addItem( 'About', function() {
       
   189 			if ( D.window.about && D.window.about.isVisible() ) {
       
   190 				D.window.about.focus();
       
   191 			}
       
   192 			else {
       
   193 				D.window.about = D.window.main.createWindow( 'app://window/about.html' );
       
   194 				D.window.about.setTopMost( true );
       
   195 				D.window.about.open();
       
   196 			}
       
   197 		});
       
   198 
       
   199 		yep.addItem( 'Preferences', function() {
       
   200 			if ( D.window.prefs && D.window.prefs.isVisible() ) {
       
   201 				D.window.prefs.focus();
       
   202 			}
       
   203 			else {
       
   204 				D.window.prefs = D.window.main.createWindow( 'app://window/prefs.html' );
       
   205 				D.window.prefs.open();
       
   206 			}
       
   207 		});
       
   208 
       
   209 		yep.addItem( 'Toggle Full Screen', function() {
       
   210 			D.window.main.setFullscreen( ! D.window.main.isFullscreen() );
       
   211 		});
       
   212 
       
   213 		menu.appendItem( yep );
       
   214 		Ti.UI.setMenu( menu );
       
   215 	},
       
   216 
       
   217 
       
   218 	/*######################################################################
       
   219 	### M O D E L S
       
   220 	######################################################################*/
       
   221 
       
   222 	// A Thingfish asset.
       
   223 	//
       
   224 	initModel: function() {
       
   225 		D.Asset = can.Model({
       
   226 			id     : 'oid',
       
   227 			findAll: 'GET '    + D.tf.uri + '/',
       
   228 			findOne: 'GET '    + D.tf.uri + '/{oid}',
       
   229 			create : 'POST '   + D.tf.uri + '/',
       
   230 			update : 'PUT '    + D.tf.uri + '/{oid}',
       
   231 			destroy: 'DELETE ' + D.tf.uri + '/{oid}',
       
   232 
       
   233 			// TODO: other metadata hooks?  diff model?
       
   234 			metadata: 'GET ' + D.tf.uri + '/{oid}/metadata',
       
   235 
       
   236 		}, {}).
       
   237 			bind( 'created', function( ev, asset ) {
       
   238 				console.debug( "Created a new asset " + asset.id );
       
   239 			}).
       
   240 			bind( 'updated', function( ev, asset ) {
       
   241 				console.debug( "Updated asset " + asset.id );
       
   242 			}).
       
   243 			bind( 'destroyed', function( ev, asset ) {
       
   244 				console.debug( "Removed asset " + asset.id );
       
   245 			}
       
   246 		);
       
   247 	},
       
   248 };
       
   249 
       
   250 
       
   251 // Initialization.
       
   252 //
       
   253 D.window.main = Ti.UI.getMainWindow();
       
   254 D.setupMenu();
       
   255 D.initDB();
       
   256