diff --git a/Resources/drupal/db.insert.js b/Resources/drupal/db.insert.js index aa8d4a9..dc7dd99 100644 --- a/Resources/drupal/db.insert.js +++ b/Resources/drupal/db.insert.js @@ -14,62 +14,57 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ - // Declaring variables to prevent implied global error in jslint var Drupal, Ti; -Drupal.db.InsertQuery = function(table, connection) { - /** - * The table on which to insert. - * - * @var string - */ - this.table = table; +Drupal.db.InsertQuery = function (table, connection) { + /** + * The table on which to insert. + * + * @var string + */ + this.table = table; - Drupal.db.Query.apply(this, [connection]); + Drupal.db.Query.apply(this, [connection]); - /** - * An array of fields on which to insert. - * - * @var array - */ - this.insertFields = []; + /** + * An array of fields on which to insert. + * + * @var array + */ + this.insertFields = []; - /** - * An array of fields that should be set to their database-defined defaults. - * - * @var array - */ - this.defaultFields = []; + /** + * An array of fields that should be set to their database-defined defaults. + * + * @var array + */ + this.defaultFields = []; - /** - * A nested array of values to insert. - * - * insertValues is an array of arrays. Each sub-array is either an - * associative array whose keys are field names and whose values are field - * values to insert, or a non-associative array of values in the same order - * as insertFields. - * - * Whether multiple insert sets will be run in a single query or multiple - * queries is left to individual drivers to implement in whatever manner is - * most appropriate. The order of values in each sub-array must match the - * order of fields in insertFields. - * - * @var array - */ - this.insertValues = []; + /** + * A nested array of values to insert. + * + * insertValues is an array of arrays. Each sub-array is either an + * associative array whose keys are field names and whose values are field + * values to insert, or a non-associative array of values in the same order + * as insertFields. + * + * Whether multiple insert sets will be run in a single query or multiple + * queries is left to individual drivers to implement in whatever manner is + * most appropriate. The order of values in each sub-array must match the + * order of fields in insertFields. + * + * @var array + */ + this.insertValues = []; - /** - * A SelectQuery object to fetch the rows that should be inserted. - * - * @var SelectQueryInterface - */ - this.fromQuery = null; + /** + * A SelectQuery object to fetch the rows that should be inserted. + * + * @var SelectQueryInterface + */ + this.fromQuery = null; }; - -// This defines the "parent" class, kinda. It has to happen after the -// constructor definition because otherwise Drupal.db.InsertQuery doesn't -// exist yet. Drupal.db.InsertQuery.prototype = Drupal.constructPrototype(Drupal.db.Query); @@ -93,36 +88,36 @@ Drupal.db.InsertQuery.prototype = Drupal.constructPrototype(Drupal.db.Query); * @return Drupal.db.InsertQuery * The called object. */ -Drupal.db.InsertQuery.prototype.fields = function(fields, values) { - if (this.insertFields.length === 0) { - if (!values) { - // If fields is an array, then we're specifying only the fields, not values. - // If it's not an array then it must be an object, in which case we're - // specifying both the fields and values at once. - if (!Array.isArray(fields)) { - var keys = []; - var arrValues = []; - for (var prop in fields) { - if (Codestrong.isAndroid() || fields.hasOwnProperty(prop)) { - keys.push(prop); - arrValues.push(fields[prop]); - } +Drupal.db.InsertQuery.prototype.fields = function (fields, values) { + if (this.insertFields.length === 0) { + if (!values) { + // If fields is an array, then we're specifying only the fields, not values. + // If it's not an array then it must be an object, in which case we're + // specifying both the fields and values at once. + if (!Array.isArray(fields)) { + var keys = []; + var arrValues = []; + for (var prop in fields) { + if (Codestrong.isAndroid() || fields.hasOwnProperty(prop)) { + keys.push(prop); + arrValues.push(fields[prop]); + } + } + if (arrValues.length) { + values = arrValues; + } + + fields = keys; + } } - if(arrValues.length) { - values = arrValues; + + this.insertFields = fields; + if (values) { + this.insertValues.push(values); } - - fields = keys; - } - } - - this.insertFields = fields; - if (values) { - this.insertValues.push(values); } - } - return this; + return this; }; /** @@ -139,22 +134,21 @@ Drupal.db.InsertQuery.prototype.fields = function(fields, values) { * @return Drupal.db.InsertQuery * The called object. */ -Drupal.db.InsertQuery.prototype.values = function(values) { - if (Array.isArray(values)) { - this.insertValues.push(values); - } - else { - // Reorder the submitted values to match the fields array. - // For consistency, the values array is always numerically indexed. - var insertValues = []; - for (var key in this.insertFields) { - if (this.insertFields.hasOwnProperty(key)) { - insertValues.push(values[this.insertFields[key]]); - } +Drupal.db.InsertQuery.prototype.values = function (values) { + if (Array.isArray(values)) { + this.insertValues.push(values); + } else { + // Reorder the submitted values to match the fields array. + // For consistency, the values array is always numerically indexed. + var insertValues = []; + for (var key in this.insertFields) { + if (this.insertFields.hasOwnProperty(key)) { + insertValues.push(values[this.insertFields[key]]); + } + } + this.insertValues.push(insertValues); } - this.insertValues.push(insertValues); - } - return this; + return this; }; /** @@ -176,9 +170,9 @@ Drupal.db.InsertQuery.prototype.values = function(values) { * @return Drupal.db.InsertQuery * The called object. */ -Drupal.db.InsertQuery.prototype.useDefaults = function(fields) { - this.defaultFields = fields; - return this; +Drupal.db.InsertQuery.prototype.useDefaults = function (fields) { + this.defaultFields = fields; + return this; }; /** @@ -190,37 +184,19 @@ Drupal.db.InsertQuery.prototype.useDefaults = function(fields) { * @throws FieldsOverlapException * @throws NoFieldsException */ -Drupal.db.InsertQuery.prototype.preExecute = function() { - // @todo Port this to Javascript, however you'd do that. - // Confirm that the user did not try to specify an identical - // field and default field. - //if (array_intersect($this->insertFields, $this->defaultFields)) { - // throw new FieldsOverlapException('You may not specify the same field to have a value and a schema-default value.'); - //} - - // @todo Port this to Javascript, however you'd do that. - //if (!empty($this->fromQuery)) { - // We have to assume that the used aliases match the insert fields. - // Regular fields are added to the query before expressions, maintain the - // same order for the insert fields. - // This behavior can be overridden by calling fields() manually as only the - // first call to fields() does have an effect. - // $this->fields(array_merge(array_keys($this->fromQuery->getFields()), array_keys($this->fromQuery->getExpressions()))); - //} - - // Don't execute query without fields. - if ((this.insertFields.length + this.defaultFields.length) === 0) { - Ti.API.error('ERROR: There are no fields available to insert with.'); - throw new Error('There are no fields available to insert with.'); - } +Drupal.db.InsertQuery.prototype.preExecute = function () { + if ((this.insertFields.length + this.defaultFields.length) === 0) { + Ti.API.error('ERROR: There are no fields available to insert with.'); + throw new Error('There are no fields available to insert with.'); + } - // If no values have been added, silently ignore this query. This can happen - // if values are added conditionally, so we don't want to throw an - // exception. - if (!this.insertValues[0] && this.insertFields.length > 0 && !this.fromQuery) { - return false; - } - return true; + // If no values have been added, silently ignore this query. This can happen + // if values are added conditionally, so we don't want to throw an + // exception. + if (!this.insertValues[0] && this.insertFields.length > 0 && !this.fromQuery) { + return false; + } + return true; }; /** @@ -232,91 +208,61 @@ Drupal.db.InsertQuery.prototype.preExecute = function() { * undefined. If no fields are specified, this method will do nothing and * return NULL. That makes it safe to use in multi-insert loops. */ -Drupal.db.InsertQuery.prototype.execute = function() { - // If validation fails, simply return NULL. Note that validation routines - // in preExecute() may throw exceptions instead. - //Ti.API.debug('In InsertQuery.execute()'); - if (!this.preExecute()) { - return null; - } - - //Ti.API.debug('InsertQuery.preExecute() passed all tests.'); - - if (!this.insertFields) { - return this.connection.query('INSERT INTO ' + this.table + ' DEFAULT VALUES'); - } - - // @todo Port this to Javascript, however we'd do that. - // If we're selecting from a SelectQuery, finish building the query and - // pass it back, as any remaining options are irrelevant. - //if (!empty($this->fromQuery)) { - // $sql = (string) $this; - // // The SelectQuery may contain arguments, load and pass them through. - // return $this->connection->query($sql, $this->fromQuery->getArguments(), $this->queryOptions); - //} - - // @todo Handle transactions, somehow. - // Each insert happens in its own query in the degenerate case. However, - // we wrap it in a transaction so that it is atomic where possible. On many - // databases, such as SQLite, this is also a notable performance boost. - //$transaction = $this->connection->startTransaction(); +Drupal.db.InsertQuery.prototype.execute = function () { + // If validation fails, simply return NULL. Note that validation routines + // in preExecute() may throw exceptions instead. + //Ti.API.debug('In InsertQuery.execute()'); + if (!this.preExecute()) { + return null; + } - try { - var sql = this.sqlString(); - for (var i = 0; i < this.insertValues.length; i++) { - //Ti.API.debug('About to call query()....'); - this.connection.query(sql, this.insertValues[i]); + //Ti.API.debug('InsertQuery.preExecute() passed all tests.'); + if (!this.insertFields) { + return this.connection.query('INSERT INTO ' + this.table + ' DEFAULT VALUES'); } - } - catch (e) { - // One of the INSERTs failed, rollback the whole batch. - //$transaction->rollback(); - // Rethrow the exception for the calling code. - Ti.API.error(e.toString()); - throw e; - } - // Re-initialize the values array so that we can re-use this query. - this.insertValues = []; + try { + var sql = this.sqlString(); + for (var i = 0; i < this.insertValues.length; i++) { + //Ti.API.debug('About to call query()....'); + this.connection.query(sql, this.insertValues[i]); + } + } catch (e) { + Ti.API.error(e.toString()); + throw e; + } - // Transaction commits here where $transaction looses scope. + // Re-initialize the values array so that we can re-use this query. + this.insertValues = []; }; /** * Convert this query to a SQL string. */ -Drupal.db.InsertQuery.prototype.sqlString = function() { - // Create a comments string to prepend to the query. - var comments = (this.comments.length) ? '/* ' + this.comments.join('; ') + ' */ ' : ''; +Drupal.db.InsertQuery.prototype.sqlString = function () { + // Create a comments string to prepend to the query. + var comments = (this.comments.length) ? '/* ' + this.comments.join('; ') + ' */ ' : ''; - // Produce as many generic placeholders as necessary. - var placeholders = []; - var length = this.insertFields.length; - for (var i = 0; i < length; i++) { - placeholders.push('?'); - } - - // @todo Restore this once we figure out how to do INSERT FROM queries. - // If we're selecting from a SelectQuery, finish building the query and - // pass it back, as any remaining options are irrelevant. - //if (this.fromQuery) { - //return comments + 'INSERT INTO {' + $this->table + '} (' + implode(', ', $this->insertFields) + ') ' + (string)$this->fromQuery; - //} + // Produce as many generic placeholders as necessary. + var placeholders = []; + var length = this.insertFields.length; + for (var i = 0; i < length; i++) { + placeholders.push('?'); + } - return comments + 'INSERT INTO ' + this.table + ' (' + this.insertFields.join(', ') + ') VALUES (' + placeholders.join(', ') + ')'; + return comments + 'INSERT INTO ' + this.table + ' (' + this.insertFields.join(', ') + ') VALUES (' + placeholders.join(', ') + ')'; }; -Drupal.getObjectProperties = function(o) { - var properties = []; - var values = []; - for (var prop in o) { - if (o.hasOwnProperty(prop)) { - properties.push(prop); - values.push(o[prop]); +Drupal.getObjectProperties = function (o) { + var properties = []; + var values = []; + for (var prop in o) { + if (o.hasOwnProperty(prop)) { + properties.push(prop); + values.push(o[prop]); + } } - } - - return properties; -}; + return properties; +}; \ No newline at end of file diff --git a/Resources/drupal/drupal.js b/Resources/drupal/drupal.js index 3ee7aef..c80b318 100644 --- a/Resources/drupal/drupal.js +++ b/Resources/drupal/drupal.js @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ - /** * Main Drupal factory. * @@ -22,41 +21,41 @@ */ var Drupal = { - /** - * Sets default values for an object. - * - * This is similar to jQuery.extend() or PHP's += for arrays, and can be - * used for much the same purpose. - * - * @param settings - * The object on which to set default values. Note that this object will - * be modified directly. - * @param defaults - * The default values to use for each key if the settings object does not - * yet have a value for that key. - * @returns - * The settings object. - */ - setDefaults: function(settings, defaults) { - if (!settings) { - settings = {}; - } - for (var key in defaults) { - if (defaults.hasOwnProperty(key) && settings[key] === undefined) { - settings[key] = defaults[key]; - } + /** + * Sets default values for an object. + * + * This is similar to jQuery.extend() or PHP's += for arrays, and can be + * used for much the same purpose. + * + * @param settings + * The object on which to set default values. Note that this object will + * be modified directly. + * @param defaults + * The default values to use for each key if the settings object does not + * yet have a value for that key. + * @returns + * The settings object. + */ + setDefaults: function (settings, defaults) { + if (!settings) { + settings = {}; + } + for (var key in defaults) { + if (defaults.hasOwnProperty(key) && settings[key] === undefined) { + settings[key] = defaults[key]; + } + } + return settings; } - return settings; - } }; /** * For fancy-schmancy inheritance building. */ -Drupal.constructPrototype = function(o) { - var f = function() {}; - f.prototype = o.prototype; - return new f(); +Drupal.constructPrototype = function (o) { + var f = function () {}; + f.prototype = o.prototype; + return new f(); }; /** @@ -74,128 +73,114 @@ Drupal.constructPrototype = function(o) { * @return {string} * The ISO formatted version of the date object. */ -Drupal.getISODate = function(date, utc) { - - function pad(n) {return n < 10 ? '0' + n : n;} - - if (utc) { - return date.getUTCFullYear() + '-' - + pad(date.getUTCMonth() + 1) + '-' - + pad(date.getUTCDate()) + 'T' - + pad(date.getUTCHours()) + ':' - + pad(date.getUTCMinutes()) + ':' - + pad(date.getUTCSeconds()); - } - else { - return date.getFullYear() + '-' - + pad(date.getMonth() + 1) + '-' - + pad(date.getDate()) + 'T' - + pad(date.getHours()) + ':' - + pad(date.getMinutes()) + ':' - + pad(date.getSeconds()); - } -}; - - - -Drupal.getObjectProperties = function(o) { - var properties = []; - var values = []; - var prop; +Drupal.getISODate = function (date, utc) { - // Apparently hasOwnProperty() is sometimes missing from objects in Titanium. - // My best guess is that it's on objects deserialized from JSON, but I'm not - // really sure. At this point I no longer care. - if(o.hasOwnProperty) { - for (prop in o) { - if (o.hasOwnProperty(prop)) { - properties.push(prop); - values.push(o[prop]); - } + function pad(n) { + return n < 10 ? '0' + n : n; } - } - else { - for (prop in o) { - properties.push(prop); - values.push(o[prop]); + + if (utc) { + return date.getUTCFullYear() + '-' + pad(date.getUTCMonth() + 1) + '-' + pad(date.getUTCDate()) + 'T' + pad(date.getUTCHours()) + ':' + pad(date.getUTCMinutes()) + ':' + pad(date.getUTCSeconds()); + } else { + return date.getFullYear() + '-' + pad(date.getMonth() + 1) + '-' + pad(date.getDate()) + 'T' + pad(date.getHours()) + ':' + pad(date.getMinutes()) + ':' + pad(date.getSeconds()); } - } - return properties; }; -(function() { - - Drupal.createNoticeDialog = function(message) { - return new Drupal.NoticeDialog(message); - }; - - Drupal.NoticeDialog = function(message) { - - var messageWin = Titanium.UI.createWindow({ - height:30, - width:250, - bottom:70, - borderRadius:10, - border: 1, - touchEnabled:false, - orientationModes : [ - Titanium.UI.PORTRAIT, - Titanium.UI.UPSIDE_PORTRAIT, - Titanium.UI.LANDSCAPE_LEFT, - Titanium.UI.LANDSCAPE_RIGHT - ], - debugText: message - }); - var messageView = Titanium.UI.createView({ - id:'messageview', - height:30, - width:250, - borderRadius:10, - backgroundColor:'#000', - opacity:0.7, - touchEnabled:false - }); - - var messageLabel = Titanium.UI.createLabel({ - id:'messagelabel', - text:'', - color:'#fff', - width:250, - height:'auto', - font:{ - fontFamily:'Helvetica Neue', - fontSize:13 - }, - textAlign:'center' - }); - - messageLabel.text = message; - - messageWin.add(messageView); - messageWin.add(messageLabel); - - this.messageWindow = messageWin; - - }; - - var openNoticeWindow; - - Drupal.NoticeDialog.prototype.show = function(time) { - // Close any open notice windows first. - if (openNoticeWindow) { - openNoticeWindow.close(); - } - this.messageWindow.open(); - openNoticeWindow = this.messageWindow; +Drupal.getObjectProperties = function (o) { + var properties = []; + var values = []; + var prop; + + if (o.hasOwnProperty) { + for (prop in o) { + if (o.hasOwnProperty(prop)) { + properties.push(prop); + values.push(o[prop]); + } + } + } else { + for (prop in o) { + properties.push(prop); + values.push(o[prop]); + } + } + return properties; +}; - // Needed to avoid 'this' confusion in the callback. Blech. - var win = this.messageWindow; - setTimeout(function() { - win.close({opacity:0,duration:2000}); - }, time); - }; +(function () { + + Drupal.createNoticeDialog = function (message) { + return new Drupal.NoticeDialog(message); + }; + + Drupal.NoticeDialog = function (message) { + + var messageWin = Titanium.UI.createWindow({ + height: 30, + width: 250, + bottom: 70, + borderRadius: 10, + border: 1, + touchEnabled: false, + orientationModes: [ + Titanium.UI.PORTRAIT, Titanium.UI.UPSIDE_PORTRAIT, Titanium.UI.LANDSCAPE_LEFT, Titanium.UI.LANDSCAPE_RIGHT], + debugText: message + }); + var messageView = Titanium.UI.createView({ + id: 'messageview', + height: 30, + width: 250, + borderRadius: 10, + backgroundColor: '#000', + opacity: 0.7, + touchEnabled: false + }); + + var messageLabel = Titanium.UI.createLabel({ + id: 'messagelabel', + text: '', + color: '#fff', + width: 250, + height: 'auto', + font: { + fontFamily: 'Helvetica Neue', + fontSize: 13 + }, + textAlign: 'center' + }); + + messageLabel.text = message; + + messageWin.add(messageView); + messageWin.add(messageLabel); + + this.messageWindow = messageWin; + + }; + + var openNoticeWindow; + + Drupal.NoticeDialog.prototype.show = function (time) { + // Close any open notice windows first. + if (openNoticeWindow) { + openNoticeWindow.close(); + } + + this.messageWindow.open(); + + openNoticeWindow = this.messageWindow; + + // Needed to avoid 'this' confusion in the callback. Blech. + var win = this.messageWindow; + setTimeout(function () { + win.close({ + opacity: 0, + duration: 2000 + }); + }, time); + }; })(); @@ -218,36 +203,31 @@ Drupal.getObjectProperties = function(o) { * including seconds. * @return {Date} */ + function parseISO8601(str) { - // Parses "as is" without attempting timezone conversion - - var parts = str.split('T'); - var dateParts = parts[0].split('-'); - var timeParts = parts[1].split('Z'); - var timeSubParts = timeParts[0].split(':'); - var timeSecParts = timeSubParts[2].split('.'); - var timeHours = Number(timeSubParts[0]); - var _date = new Date(); - - _date.setFullYear(Number(dateParts[0])); - _date.setMonth(Number(dateParts[1])-1); - _date.setDate(Number(dateParts[2])); - _date.setHours(Number(timeHours)); - _date.setMinutes(Number(timeSubParts[1])); - _date.setSeconds(Number(timeSecParts[0])); - if (timeSecParts[1]) { _date.setMilliseconds(Number(timeSecParts[1])); }; - - return _date; + // Parses "as is" without attempting timezone conversion + var parts = str.split('T'); + var dateParts = parts[0].split('-'); + var timeParts = parts[1].split('Z'); + var timeSubParts = timeParts[0].split(':'); + var timeSecParts = timeSubParts[2].split('.'); + var timeHours = Number(timeSubParts[0]); + var _date = new Date(); + + _date.setFullYear(Number(dateParts[0])); + _date.setMonth(Number(dateParts[1]) - 1); + _date.setDate(Number(dateParts[2])); + _date.setHours(Number(timeHours)); + _date.setMinutes(Number(timeSubParts[1])); + _date.setSeconds(Number(timeSecParts[0])); + if (timeSecParts[1]) { + _date.setMilliseconds(Number(timeSecParts[1])); + }; + + return _date; }; -function strpos (haystack, needle, offset) { - // http://kevin.vanzonneveld.net - // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + improved by: Onno Marsman - // + bugfixed by: Daniel Esteban - // + improved by: Brett Zamir (http://brett-zamir.me) - // * example 1: strpos('Kevin van Zonneveld', 'e', 5); - // * returns 1: 14 +function strpos(haystack, needle, offset) { var i = (haystack + '').indexOf(needle, (offset || 0)); return i === -1 ? false : i; } \ No newline at end of file diff --git a/Resources/drupal/entity.datastore.js b/Resources/drupal/entity.datastore.js index 7186487..cb89e06 100644 --- a/Resources/drupal/entity.datastore.js +++ b/Resources/drupal/entity.datastore.js @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ - // Declaring variables to prevent implied global error in jslint var Drupal, Ti; @@ -33,16 +32,16 @@ var Drupal, Ti; * The type of entity this datastore should access. * @return Drupal.entity.Datastore */ -Drupal.entity.Datastore = function(site, connection, entityType, entityInfo) { - this.site = site; - this.connection = connection; - this.entityType = entityType; - this.entityInfo = entityInfo; - this.idField = this.getIdField(); +Drupal.entity.Datastore = function (site, connection, entityType, entityInfo) { + this.site = site; + this.connection = connection; + this.entityType = entityType; + this.entityInfo = entityInfo; + this.idField = this.getIdField(); - this.schemaDefinition = null; + this.schemaDefinition = null; - return this; + return this; }; /** @@ -51,10 +50,10 @@ Drupal.entity.Datastore = function(site, connection, entityType, entityInfo) { * @return string * The name of the field that holds this entity type's primary key. */ -Drupal.entity.Datastore.prototype.getIdField = function() { - var idField = this.entityInfo.entity_keys.id; +Drupal.entity.Datastore.prototype.getIdField = function () { + var idField = this.entityInfo.entity_keys.id; - return idField; + return idField; }; /** @@ -70,13 +69,13 @@ Drupal.entity.Datastore.prototype.getIdField = function() { * object. It is (or should be) safe to simply use an * entity object retrieved from a Drupal site. */ -Drupal.entity.Datastore.prototype.save = function(entity) { - // For simplicity, we'll just do a delete/insert cycle. - // We're only using a very simple (if dynamic) schema, - // so this lets us avoid having to write a dynamic - // update builder for now. - this.remove(entity[this.idField]); - return this.insert(entity); +Drupal.entity.Datastore.prototype.save = function (entity) { + // For simplicity, we'll just do a delete/insert cycle. + // We're only using a very simple (if dynamic) schema, + // so this lets us avoid having to write a dynamic + // update builder for now. + this.remove(entity[this.idField]); + return this.insert(entity); }; /** @@ -90,61 +89,59 @@ Drupal.entity.Datastore.prototype.save = function(entity) { * The number of rows affected. This should only ever be 1 for * a successful insert or 0 if something went wrong. */ -Drupal.entity.Datastore.prototype.insert = function(entity) { - //Ti.API.debug('In Datastore.insert()'); - - // var fields = {}; - - // // Get the basic fields first. - // var properties = ['id', 'revision', 'bundle', 'label']; - // var property; - // for (var i = 0; i < properties.length; i++) { +Drupal.entity.Datastore.prototype.insert = function (entity) { + //Ti.API.debug('In Datastore.insert()'); + // var fields = {}; + // // Get the basic fields first. + // var properties = ['id', 'revision', 'bundle', 'label']; + // var property; + // for (var i = 0; i < properties.length; i++) { // property = properties[i]; // if (this.entityInfo.entity_keys[property]) { - // fields[this.entityInfo.entity_keys[property]] = entity[this.entityInfo.entity_keys[property]]; + // fields[this.entityInfo.entity_keys[property]] = entity[this.entityInfo.entity_keys[property]]; // } - // } - // fields = entity; - if (this.entityInfo.label === 'Node') { - var timeslot = entity['time']; - var m = /^(\d+)\s+([^\s]+)\s+(\d\d\:\d\d)\s*\-\s*(\d\d\:\d\d)/.exec(timeslot); - if (m && m.length) { - entity['start_date'] = '2011-09-' + m[1] + ' ' + m[3] + ':00.000'; - entity['end_date'] = '2011-09-' + m[1] + ' ' + m[4] + ':00.000'; - } else { - entity['start_date'] = ''; - entity['end_date'] = ''; - } - - if (!entity.room) { - entity.room = ''; - } - } - - // For whatever reason, `delete` does not actually delete the property on Android - var fields = {}; - if (Codestrong.isAndroid()) { - for (var mykey in entity) { - if (mykey !== 'time') { - fields[mykey] = entity[mykey]; - } - } - } else { - delete entity['time']; - fields = entity; - } - - // And finally, store the serialized entity object. - fields.data = JSON.stringify(entity); - - // Ensure that the schema table exists. - if (!this.connection.tableExists(this.entityType)) { - this.connection.createTable(this.entityType, this.getSchema()); - } + // } + // fields = entity; + if (this.entityInfo.label === 'Node') { + var timeslot = entity['time']; + var m = /^(\d+)\s+([^\s]+)\s+(\d\d\:\d\d)\s*\-\s*(\d\d\:\d\d)/.exec(timeslot); + if (m && m.length) { + entity['start_date'] = '2011-09-' + m[1] + ' ' + m[3] + ':00.000'; + entity['end_date'] = '2011-09-' + m[1] + ' ' + m[4] + ':00.000'; + } else { + entity['start_date'] = ''; + entity['end_date'] = ''; + } - this.connection.insert(this.entityType).fields(fields).execute(); + if (!entity.room) { + entity.room = ''; + } + } - return this.connection.rowsAffected; + // For whatever reason, `delete` does not actually delete the property on Android + var fields = {}; + if (Codestrong.isAndroid()) { + for (var mykey in entity) { + if (mykey !== 'time') { + fields[mykey] = entity[mykey]; + } + } + } else { + delete entity['time']; + fields = entity; + } + + // And finally, store the serialized entity object. + fields.data = JSON.stringify(entity); + + // Ensure that the schema table exists. + if (!this.connection.tableExists(this.entityType)) { + this.connection.createTable(this.entityType, this.getSchema()); + } + + this.connection.insert(this.entityType).fields(fields).execute(); + + return this.connection.rowsAffected; }; /** @@ -163,10 +160,10 @@ Drupal.entity.Datastore.prototype.insert = function(entity) { * a successful update or 0 if the entity didn't exist in the * first place. */ -Drupal.entity.Datastore.prototype.update = function(entity) { - var data = JSON.stringify(entity); - this.connection.query("UPDATE " + this.entityType + " SET type=?, title=?, data=? WHERE nid=?", [entity.type, entity.title, data, entity[this.idField]]); - return this.connection.rowsAffected; +Drupal.entity.Datastore.prototype.update = function (entity) { + var data = JSON.stringify(entity); + this.connection.query("UPDATE " + this.entityType + " SET type=?, title=?, data=? WHERE nid=?", [entity.type, entity.title, data, entity[this.idField]]); + return this.connection.rowsAffected; }; /** @@ -181,18 +178,18 @@ Drupal.entity.Datastore.prototype.update = function(entity) { * true if an entity with the specified ID exists, false * if not or if there was an error. */ -Drupal.entity.Datastore.prototype.exists = function(id) { - var rows = this.connection.query("SELECT 1 FROM " + this.entityType + " WHERE " + this.idField + " = ?", [id]); - - // In case of pretty much any error whatsoever, Ti will just - // return null rather than show a useful error. So we have - // to check the return, always. Fail. We'll assume that a - // null return (error) indicates that the record is not there. - var ret = rows && rows.rowCount; - if (rows) { - rows.close(); - } - return ret; +Drupal.entity.Datastore.prototype.exists = function (id) { + var rows = this.connection.query("SELECT 1 FROM " + this.entityType + " WHERE " + this.idField + " = ?", [id]); + + // In case of pretty much any error whatsoever, Ti will just + // return null rather than show a useful error. So we have + // to check the return, always. Fail. We'll assume that a + // null return (error) indicates that the record is not there. + var ret = rows && rows.rowCount; + if (rows) { + rows.close(); + } + return ret; }; /** @@ -204,16 +201,15 @@ Drupal.entity.Datastore.prototype.exists = function(id) { * The entity with the specified ID if any, or null * if one was not found. */ -Drupal.entity.Datastore.prototype.load = function(id) { - var entities = this.loadMultiple([id]); - - if (entities && entities[0]) { - return entities[0]; - } - else { - Ti.API.error('No such entity found: ' + id); - return null; - } +Drupal.entity.Datastore.prototype.load = function (id) { + var entities = this.loadMultiple([id]); + + if (entities && entities[0]) { + return entities[0]; + } else { + Ti.API.error('No such entity found: ' + id); + return null; + } }; /** @@ -231,8 +227,8 @@ Drupal.entity.Datastore.prototype.load = function(id) { * the array will be empty. Note that the order of entities * in the array is undefined. */ -Drupal.entity.Datastore.prototype.loadMultiple = function(ids, order) { - return this.loadByField(this.idField, ids, order); +Drupal.entity.Datastore.prototype.loadMultiple = function (ids, order) { + return this.loadByField(this.idField, ids, order); }; /** @@ -255,34 +251,34 @@ Drupal.entity.Datastore.prototype.loadMultiple = function(ids, order) { * An array of loaded entity objects. If none were found the array will be * empty. */ -Drupal.entity.Datastore.prototype.loadByField = function(field, values, order) { +Drupal.entity.Datastore.prototype.loadByField = function (field, values, order) { - var entities = []; + var entities = []; - var placeholders = []; - for (var i=0, numPlaceholders = values.length; i < numPlaceholders; i++) { - placeholders.push('?'); - } + var placeholders = []; + for (var i = 0, numPlaceholders = values.length; i < numPlaceholders; i++) { + placeholders.push('?'); + } - var query = 'SELECT data FROM ' + this.entityType + ' WHERE ' + field + ' IN (' + placeholders.join(', ') + ')'; + var query = 'SELECT data FROM ' + this.entityType + ' WHERE ' + field + ' IN (' + placeholders.join(', ') + ')'; - if (order !== undefined) { - query += ' ORDER BY ' + order.join(', '); - } + if (order !== undefined) { + query += ' ORDER BY ' + order.join(', '); + } - var rows = this.connection.query(query, values); + var rows = this.connection.query(query, values); - if (rows) { - while (rows.isValidRow()) { - var data = rows.fieldByName('data'); - var entity = JSON.parse(data); - entities.push(entity); - rows.next(); + if (rows) { + while (rows.isValidRow()) { + var data = rows.fieldByName('data'); + var entity = JSON.parse(data); + entities.push(entity); + rows.next(); + } + rows.close(); } - rows.close(); - } - return entities; + return entities; }; /** @@ -302,30 +298,31 @@ Drupal.entity.Datastore.prototype.loadByField = function(field, values, order) { * a successful deletion or 0 if the entity didn't exist in the * first place. */ -Drupal.entity.Datastore.prototype.remove = function(id) { - this.connection.query("DELETE FROM " + this.entityType + " WHERE " + this.idField + " = ?", [id]); - return this.connection.rowsAffected; +Drupal.entity.Datastore.prototype.remove = function (id) { + this.connection.query("DELETE FROM " + this.entityType + " WHERE " + this.idField + " = ?", [id]); + return this.connection.rowsAffected; }; -Drupal.entity.Datastore.prototype.fetchUpdates = function(bundle) { - var callback = function() { - // Let other systems respond to the update completion. - Ti.fireEvent('drupal:entity:datastore:update_completed', {entity: this.entityType, bundle: bundle}); - }; - - if (this.entityInfo.schema.fetchers && this.entityInfo.schema.fetchers[bundle]) { - this.entityInfo.schema.fetchers[bundle](this, callback); - } - else if (this.entityInfo.schema.defaultFetcher) { - this.entityInfo.schema.defaultFetcher(bundle, this, callback); - } - else { - Ti.API.error('No fetcher found for entity: ' + this.entityType + ', bundle: ' + bundle); - throw new Error('No fetcher found for entity: ' + this.entityType + ', bundle: ' + bundle); - } +Drupal.entity.Datastore.prototype.fetchUpdates = function (bundle) { + var callback = function () { + // Let other systems respond to the update completion. + Ti.fireEvent('drupal:entity:datastore:update_completed', { + entity: this.entityType, + bundle: bundle + }); + }; + + if (this.entityInfo.schema.fetchers && this.entityInfo.schema.fetchers[bundle]) { + this.entityInfo.schema.fetchers[bundle](this, callback); + } else if (this.entityInfo.schema.defaultFetcher) { + this.entityInfo.schema.defaultFetcher(bundle, this, callback); + } else { + Ti.API.error('No fetcher found for entity: ' + this.entityType + ', bundle: ' + bundle); + throw new Error('No fetcher found for entity: ' + this.entityType + ', bundle: ' + bundle); + } }; -Drupal.entity.Datastore.prototype.defaultUpdater = function(bundle) { +Drupal.entity.Datastore.prototype.defaultUpdater = function (bundle) { }; @@ -336,70 +333,70 @@ Drupal.entity.Datastore.prototype.defaultUpdater = function(bundle) { * type. That is, all existing data will be destroyed. Did we mention * *all existing data for this entity type will be lost*? */ -Drupal.entity.Datastore.prototype.initializeSchema = function() { - this.connection.dropTable(this.entityType); - this.connection.createTable(this.entityType, this.getSchema()); +Drupal.entity.Datastore.prototype.initializeSchema = function () { + this.connection.dropTable(this.entityType); + this.connection.createTable(this.entityType, this.getSchema()); }; /** * Returns the schema definition for this enity's storage. */ -Drupal.entity.Datastore.prototype.getSchema = function() { - if (! this.schemaDefinition) { - var schema = { - description: 'Storage table for ' + this.entityType + ' entities.', - fields: {}, - indexes: {}, - uniqueKeys: {} - }; - - // We always want to denormalize the entity keys, if available. - if (this.entityInfo.entity_keys.id) { - schema.fields[this.entityInfo.entity_keys.id] = { - type: 'INTEGER' - }; - schema.primaryKey = [this.entityInfo.entity_keys.id]; - } - if (this.entityInfo.entity_keys.revision) { - schema.fields[this.entityInfo.entity_keys.revision] = { - type: 'INTEGER' - }; - } - if (this.entityInfo.entity_keys.bundle) { - schema.fields[this.entityInfo.entity_keys.bundle] = { - type: 'VARCHAR' - }; - } - if (this.entityInfo.entity_keys.label) { - schema.fields[this.entityInfo.entity_keys.label] = { - type: 'VARCHAR' - }; - } +Drupal.entity.Datastore.prototype.getSchema = function () { + if (!this.schemaDefinition) { + var schema = { + description: 'Storage table for ' + this.entityType + ' entities.', + fields: {}, + indexes: {}, + uniqueKeys: {} + }; + + // We always want to denormalize the entity keys, if available. + if (this.entityInfo.entity_keys.id) { + schema.fields[this.entityInfo.entity_keys.id] = { + type: 'INTEGER' + }; + schema.primaryKey = [this.entityInfo.entity_keys.id]; + } + if (this.entityInfo.entity_keys.revision) { + schema.fields[this.entityInfo.entity_keys.revision] = { + type: 'INTEGER' + }; + } + if (this.entityInfo.entity_keys.bundle) { + schema.fields[this.entityInfo.entity_keys.bundle] = { + type: 'VARCHAR' + }; + } + if (this.entityInfo.entity_keys.label) { + schema.fields[this.entityInfo.entity_keys.label] = { + type: 'VARCHAR' + }; + } - // Now extract any additional fields and indexes to denormalize. - if (this.entityInfo.schema.fields) { - var extraSchema = this.entityInfo.schema.fields(); - var properties = ['fields', 'indexes', 'uniqueKeys']; - var set; - var property; - for (var i = 0; i < properties.length; i++) { - property = properties[i]; - set = extraSchema[property]; - for (var key in set) { - if (set.hasOwnProperty(key)) { - schema[property][key] = set[key]; - } + // Now extract any additional fields and indexes to denormalize. + if (this.entityInfo.schema.fields) { + var extraSchema = this.entityInfo.schema.fields(); + var properties = ['fields', 'indexes', 'uniqueKeys']; + var set; + var property; + for (var i = 0; i < properties.length; i++) { + property = properties[i]; + set = extraSchema[property]; + for (var key in set) { + if (set.hasOwnProperty(key)) { + schema[property][key] = set[key]; + } + } + } } - } - } - // We always want a "data" column to store the serialized object itself. - schema.fields.data = { - type: 'BLOB' - }; + // We always want a "data" column to store the serialized object itself. + schema.fields.data = { + type: 'BLOB' + }; - this.schemaDefinition = schema; - } + this.schemaDefinition = schema; + } - return this.schemaDefinition; -}; + return this.schemaDefinition; +}; \ No newline at end of file diff --git a/Resources/drupal/entity.js b/Resources/drupal/entity.js index 6c4ef09..7450727 100644 --- a/Resources/drupal/entity.js +++ b/Resources/drupal/entity.js @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ - // Declaring variables to prevent implied global error in jslint var Ti, Drupal; @@ -23,175 +22,167 @@ var Ti, Drupal; */ Drupal.entity = { - sites: { - main: { - /** - * Entity types known to the system. - * - * This is a subset of the information provided in hook_entity_info(). We have - * to specify it again here because we may not be dealing with Drupal 7 on - * the other end. - * - * We're using lower_case variables here instead of camelCase so that they - * exactly match the PHP variables. That will make dynamic definition easier - * later. - * - * @todo Make it possible to override this data with a direct pull of - * hook_entity_info() from a connected server. - */ - types: { - node: { - label: Ti.Locale.getString('Node', 'Node'), - entity_keys: { - id: 'nid', - revision: 'vid', - bundle: 'type', - label: 'title' - }, - schema: {}, - requestUrl: function(id) { - return 'node/' + id; - } - }, - user: { - label: Ti.Locale.getString('User', 'User'), - entity_keys: { - id: 'uid', - bundle: null, - label: 'name' - }, - schema: {}, - requestUrl: function(id) { - return 'user/' + id; - } + sites: { + main: { + /** + * Entity types known to the system. + * + * This is a subset of the information provided in hook_entity_info(). We have + * to specify it again here because we may not be dealing with Drupal 7 on + * the other end. + * + * We're using lower_case variables here instead of camelCase so that they + * exactly match the PHP variables. That will make dynamic definition easier + * later. + * + * @todo Make it possible to override this data with a direct pull of + * hook_entity_info() from a connected server. + */ + types: { + node: { + label: Ti.Locale.getString('Node', 'Node'), + entity_keys: { + id: 'nid', + revision: 'vid', + bundle: 'type', + label: 'title' + }, + schema: {}, + requestUrl: function (id) { + return 'node/' + id; + } + }, + user: { + label: Ti.Locale.getString('User', 'User'), + entity_keys: { + id: 'uid', + bundle: null, + label: 'name' + }, + schema: {}, + requestUrl: function (id) { + return 'user/' + id; + } + } + } } - } - } - }, - - /** - * Creates a new entity storage object. - * - * @param string site - * A key for the site from which we are mirroring - * content. This corresponds to the database we are - * loading. - * @param string entityType - * The type of entity (node, user, etc.) that we are - * accessing. - * @return Drupal.entity.Datastore - * A new datastore object for the specified site and entity. - */ - db: function(site, entityType) { - var conn = Drupal.db.openConnection(site); - return new Drupal.entity.Datastore(site, conn, entityType, this.entityInfo(site, entityType)); - }, - - /** - * Retrieves information about a defined entity. - * - * @param string site - * The site key for which we want information. - * @param entityType - * The type of entity for which we want information. - * @return Object - * The entity definition as an object/associative array, - * or null if not found. - */ - entityInfo: function(site, entityType) { - if (this.sites[site].types[entityType] !== undefined) { - return this.sites[site].types[entityType]; + }, + + /** + * Creates a new entity storage object. + * + * @param string site + * A key for the site from which we are mirroring + * content. This corresponds to the database we are + * loading. + * @param string entityType + * The type of entity (node, user, etc.) that we are + * accessing. + * @return Drupal.entity.Datastore + * A new datastore object for the specified site and entity. + */ + db: function (site, entityType) { + var conn = Drupal.db.openConnection(site); + return new Drupal.entity.Datastore(site, conn, entityType, this.entityInfo(site, entityType)); + }, + + /** + * Retrieves information about a defined entity. + * + * @param string site + * The site key for which we want information. + * @param entityType + * The type of entity for which we want information. + * @return Object + * The entity definition as an object/associative array, + * or null if not found. + */ + entityInfo: function (site, entityType) { + if (this.sites[site].types[entityType] !== undefined) { + return this.sites[site].types[entityType]; + } + Ti.API.error('Entity type ' + entityType + ' not defined for site ' + site); + }, + + /** + * Mirror an entity from a remote server. + * + * Note that the mirroring process is asynchronous. That is, the entity + * will not be available locally until sometime after this method returns, + * depending on network latency. + * + * @todo Add an event that fires when mirroring is done. + * + * @param site + * The site key from which to mirror. + * @param entityType + * The type of entity to be mirrored. + * @param id + * The ID of the entity that is being mirrored. + */ + mirror: function (site, entityType, id) { + var service = Drupal.services.createConnection('main'); + service.loadHandler = function () { + Drupal.entity.db(site, entityType).save(JSON.parse(this.responseText)); + }; + + service.request({ + query: this.entityInfo(site, entityType).requestUrl(id) + }); } - Ti.API.error('Entity type ' + entityType + ' not defined for site ' + site); - }, - - /** - * Mirror an entity from a remote server. - * - * Note that the mirroring process is asynchronous. That is, the entity - * will not be available locally until sometime after this method returns, - * depending on network latency. - * - * @todo Add an event that fires when mirroring is done. - * - * @param site - * The site key from which to mirror. - * @param entityType - * The type of entity to be mirrored. - * @param id - * The ID of the entity that is being mirrored. - */ - mirror: function(site, entityType, id) { - var service = Drupal.services.createConnection('main'); - service.loadHandler = function() { - Drupal.entity.db(site, entityType).save(JSON.parse(this.responseText)); - }; - - service.request({query: this.entityInfo(site, entityType).requestUrl(id)}); - } }; -Drupal.entity.DefaultSchema = function() { - - this.fetchUrl = null; - - this.bypassCache = false; - - this.fetchers = {}; - +Drupal.entity.DefaultSchema = function () { + this.fetchUrl = null; + this.bypassCache = false; + this.fetchers = {}; }; -Drupal.entity.DefaultSchema.prototype.fields = function() { - return {}; +Drupal.entity.DefaultSchema.prototype.fields = function () { + return {}; }; -Drupal.entity.DefaultSchema.prototype.getFieldValues = function(entity, values) { - // Do nothing. +Drupal.entity.DefaultSchema.prototype.getFieldValues = function (entity, values) { + // Do nothing. }; -Drupal.entity.DefaultSchema.prototype.defaultFetcher = function(bundle, store, func, fetchUrl) { - var xhr = Titanium.Network.createHTTPClient(); - //xhr.onerror = options.errorHandler; - xhr.onload = function() { - var entities = JSON.parse(this.responseText).entities; - - var length = entities.length; +Drupal.entity.DefaultSchema.prototype.defaultFetcher = function (bundle, store, func, fetchUrl) { + var xhr = Titanium.Network.createHTTPClient(); + //xhr.onerror = options.errorHandler; + xhr.onload = function () { + var entities = JSON.parse(this.responseText).entities; + var length = entities.length; - Ti.API.debug('Downloading ' + length + ' entities of type ' + store.entityType); + //Ti.API.debug('Downloading ' + length + ' entities of type ' + store.entityType); - for (var i=0; i < length; i++) { - //Ti.API.debug('Downloading entity: ' + entities[i].entity); - store.save(entities[i].entity); - } + for (var i = 0; i < length; i++) { + store.save(entities[i].entity); + } - // Call our post-completion callback. - if (func) { - func(); - } - }; - - //open the client and encode our URL - var url = fetchUrl || this.fetchUrl || null; - if (url) { - if (this.bypassCache) { - if (strpos(url, '?') === false) { - url += '?cacheBypass=' + Math.random(); - } - else { - url += '&cacheBypass=' + Math.random(); - } - } - xhr.open('GET', url); - - //send the data - Ti.API.debug('Requesting data from: ' + url); - xhr.send(); - } - else { - Ti.API.error('No fetching URL found. Unable to retrieve data.'); - } -}; + // Call our post-completion callback. + if (func) { + func(); + } + }; + //open the client and encode our URL + var url = fetchUrl || this.fetchUrl || null; + if (url) { + if (this.bypassCache) { + if (strpos(url, '?') === false) { + url += '?cacheBypass=' + Math.random(); + } else { + url += '&cacheBypass=' + Math.random(); + } + } + xhr.open('GET', url); + //send the data + Ti.API.debug('Requesting data from: ' + url); + xhr.send(); + } else { + Ti.API.error('No fetching URL found. Unable to retrieve data.'); + } +}; \ No newline at end of file diff --git a/Resources/windows/HtmlWindow.js b/Resources/windows/HtmlWindow.js index c678a50..860fac4 100644 --- a/Resources/windows/HtmlWindow.js +++ b/Resources/windows/HtmlWindow.js @@ -14,39 +14,37 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ +(function () { + Codestrong.ui.createHtmlWindow = function (settings) { + Drupal.setDefaults(settings, { + title: 'title here', + url: '' + }); -(function() { + var htmlWindow = Titanium.UI.createWindow({ + id: 'htmlWindow', + title: settings.title, + backgroundColor: '#FFF', + barColor: '#414444', + width: '100%', + height: '100%', + fullscreen: false + }); + htmlWindow.orientationModes = [Ti.UI.PORTRAIT]; - Codestrong.ui.createHtmlWindow = function(settings) { - Drupal.setDefaults(settings, { - title: 'title here', - url: '' - }); + var webview = Ti.UI.createWebView({ + url: settings.url, + width: '100%', + height: '100%' + }); + htmlWindow.add(webview); + htmlWindow.addEventListener('focus', function (e) { + webview.url = settings.url; + webview.height = '100%'; + webview.width = '100%'; + }); - var htmlWindow = Titanium.UI.createWindow({ - id: 'htmlWindow', - title: settings.title, - backgroundColor: '#FFF', - barColor: '#414444', - width: '100%', - height: '100%', - fullscreen: false - }); - htmlWindow.orientationModes = [Ti.UI.PORTRAIT]; - - var webview = Ti.UI.createWebView({ - url: settings.url, - width:'100%', - height:'100%' - }); - htmlWindow.add(webview); - htmlWindow.addEventListener('focus', function(e) { - webview.url = settings.url; - webview.height = '100%'; - webview.width = '100%'; - }); + return htmlWindow; + }; - return htmlWindow; - }; - -})(); +})(); \ No newline at end of file diff --git a/Resources/windows/MapWindow.js b/Resources/windows/MapWindow.js index 976ba34..54c4b8c 100644 --- a/Resources/windows/MapWindow.js +++ b/Resources/windows/MapWindow.js @@ -14,114 +14,128 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ +(function () { -(function() { + Codestrong.ui.createMapWindow = function () { + var mapWindow = Titanium.UI.createWindow({ + id: 'mapWindow', + title: 'Meeting Room Maps', + backgroundColor: '#FFF', + barColor: '#414444', + height: '100%', + fullscreen: false + }); - Codestrong.ui.createMapWindow = function() { - var mapWindow = Titanium.UI.createWindow({ - id: 'mapWindow', - title: 'Meeting Room Maps', - backgroundColor: '#FFF', - barColor: '#414444', - height:'100%', - fullscreen: false - }); + // create table view data object + var duration = 250; + var data = [ + { + title: 'Floor 3 - Grand Ballroom', + shortTitle: '3rd Floor', + url: 'pages/maps/map3.html', + animateOut: { + left: -1 * Ti.Platform.displayCaps.platformWidth, + top: Codestrong.ui.tabBarHeight, + duration: duration + }, + animateIn: { + left: 0, + top: Codestrong.ui.tabBarHeight, + duration: duration + }, + left: 0 + }, + { + title: 'Floor 4 - Pacific Terrace', + shortTitle: '4th Floor', + url: 'pages/maps/map4.html', + animateOut: { + left: Ti.Platform.displayCaps.platformWidth, + top: Codestrong.ui.tabBarHeight, + duration: duration + }, + animateIn: { + left: 0, + top: Codestrong.ui.tabBarHeight, + duration: duration + }, + left: Ti.Platform.displayCaps.platformWidth + } + ]; - // create table view data object - var duration = 250; - var data = [ - { - title: 'Floor 3 - Grand Ballroom', - shortTitle:'3rd Floor', - url: 'pages/maps/map3.html', - animateOut: {left:-1 * Ti.Platform.displayCaps.platformWidth, top: Codestrong.ui.tabBarHeight, duration:duration}, - animateIn: {left:0, top: Codestrong.ui.tabBarHeight, duration:duration}, - left: 0 - }, - { - title: 'Floor 4 - Pacific Terrace', - shortTitle:'4th Floor', - url: 'pages/maps/map4.html', - animateOut: {left:Ti.Platform.displayCaps.platformWidth, top: Codestrong.ui.tabBarHeight, duration:duration}, - animateIn: {left:0, top:Codestrong.ui.tabBarHeight, duration:duration}, - left: Ti.Platform.displayCaps.platformWidth - } - ]; - - var tabbedBarView = Ti.UI.createView({ - backgroundColor:'#555', - top:0, - height:Codestrong.ui.tabBarHeight - }); - var tabbedBar = Ti.UI.createView({ - top:0, - backgroundColor: '#000', - height:Codestrong.ui.tabBarHeight, - width:Ti.Platform.displayCaps.platformWidth - }); - - for (var i = 0; i < data.length; i++) { - var myEntry = data[i]; - - myEntry.webview = Ti.UI.createWebView({ - scalesPageToFit: true, - url: myEntry.url, - top:Codestrong.ui.tabBarHeight, - bottom:0, - left:myEntry.left, - width:Ti.Platform.displayCaps.platformWidth - }); - - var tabView = Ti.UI.createView({ - backgroundImage: (i == 0) ? 'images/buttonbar/button2_selected.png' : 'images/buttonbar/button2_unselected_shadowL.png', - height:Codestrong.ui.tabBarHeight, - left: i * (Ti.Platform.displayCaps.platformWidth/data.length), - right: Ti.Platform.displayCaps.platformWidth - ((parseInt(i) + 1) * (Ti.Platform.displayCaps.platformWidth/data.length)), - index: i - }); - - var tabLabel = Ti.UI.createLabel({ - text: myEntry.shortTitle, - textAlign:'center', - color: '#fff', - height:'auto', - touchEnabled: false, - font: { - fontSize:14, - fontWeight: 'bold' - } - }); - tabView.addEventListener('click', function(e) { - if (e.source.index == 0) { - data[0].tabView.backgroundImage = 'images/buttonbar/button2_selected.png'; - data[1].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowL.png'; - } else if (e.source.index == 1) { - data[0].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowR.png'; - data[1].tabView.backgroundImage = 'images/buttonbar/button2_selected.png'; - } - - for (var j = 0; j < data.length; j++) { - if (e.source.index == 0) { - data[0].webview.animate(data[0].animateIn); - data[1].webview.animate(data[1].animateOut); - } else { - data[0].webview.animate(data[0].animateOut); - data[1].webview.animate(data[1].animateIn); - } - } - }); - - tabView.add(tabLabel); - tabbedBar.add(tabView); - myEntry.tabView = tabView; - } + var tabbedBarView = Ti.UI.createView({ + backgroundColor: '#555', + top: 0, + height: Codestrong.ui.tabBarHeight + }); + var tabbedBar = Ti.UI.createView({ + top: 0, + backgroundColor: '#000', + height: Codestrong.ui.tabBarHeight, + width: Ti.Platform.displayCaps.platformWidth + }); - tabbedBarView.add(tabbedBar); - mapWindow.add(tabbedBarView); - mapWindow.add(data[0].webview); - mapWindow.add(data[1].webview); - - return mapWindow; - }; + for (var i = 0; i < data.length; i++) { + var myEntry = data[i]; -})(); + myEntry.webview = Ti.UI.createWebView({ + scalesPageToFit: true, + url: myEntry.url, + top: Codestrong.ui.tabBarHeight, + bottom: 0, + left: myEntry.left, + width: Ti.Platform.displayCaps.platformWidth + }); + + var tabView = Ti.UI.createView({ + backgroundImage: (i == 0) ? 'images/buttonbar/button2_selected.png' : 'images/buttonbar/button2_unselected_shadowL.png', + height: Codestrong.ui.tabBarHeight, + left: i * (Ti.Platform.displayCaps.platformWidth / data.length), + right: Ti.Platform.displayCaps.platformWidth - ((parseInt(i) + 1) * (Ti.Platform.displayCaps.platformWidth / data.length)), + index: i + }); + + var tabLabel = Ti.UI.createLabel({ + text: myEntry.shortTitle, + textAlign: 'center', + color: '#fff', + height: 'auto', + touchEnabled: false, + font: { + fontSize: 14, + fontWeight: 'bold' + } + }); + tabView.addEventListener('click', function (e) { + if (e.source.index == 0) { + data[0].tabView.backgroundImage = 'images/buttonbar/button2_selected.png'; + data[1].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowL.png'; + } else if (e.source.index == 1) { + data[0].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowR.png'; + data[1].tabView.backgroundImage = 'images/buttonbar/button2_selected.png'; + } + + for (var j = 0; j < data.length; j++) { + if (e.source.index == 0) { + data[0].webview.animate(data[0].animateIn); + data[1].webview.animate(data[1].animateOut); + } else { + data[0].webview.animate(data[0].animateOut); + data[1].webview.animate(data[1].animateIn); + } + } + }); + + tabView.add(tabLabel); + tabbedBar.add(tabView); + myEntry.tabView = tabView; + } + + tabbedBarView.add(tabbedBar); + mapWindow.add(tabbedBarView); + mapWindow.add(data[0].webview); + mapWindow.add(data[1].webview); + + return mapWindow; + }; +})(); \ No newline at end of file diff --git a/Resources/windows/PresenterDetailWindow.js b/Resources/windows/PresenterDetailWindow.js index 5f2ac4a..79ff23f 100644 --- a/Resources/windows/PresenterDetailWindow.js +++ b/Resources/windows/PresenterDetailWindow.js @@ -14,189 +14,194 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ +(function () { + Codestrong.ui.createPresenterDetailWindow = function (settings) { + Drupal.setDefaults(settings, { + title: 'title here', + uid: '', + name: '' + }); + + var presenterData = Drupal.entity.db('main', 'user').load(settings.uid); + var presenterDetailWindow = Titanium.UI.createWindow({ + id: 'presenterDetailWindow', + title: presenterData.full_name, + backgroundColor: '#FFF', + barColor: '#414444', + fullscreen: false + }); + presenterDetailWindow.orientationModes = [Ti.UI.PORTRAIT]; + + var tvData = []; + var blueBg = '#C4E2EF'; + + // Structure + var tv = Ti.UI.createTableView({ + textAlign: 'left', + width: '100%', + separatorColor: '#fff' + }); + tv.footerView = Ti.UI.createView({ + height: 1, + opacity: 0 + }); + + var av = Ti.UI.createImageView({ + image: presenterData.picture.replace(/^\s+|\s+$/g, '') || 'images/userpict-large.png', + left: 0, + top: 0, + height: 110, + width: 110, + defaultImage: 'images/userpict-large.png', + backgroundColor: '#000', + touchEnabled: false + }); + var headerRow = Ti.UI.createTableViewRow({ + height: 110, + backgroundImage: 'images/sessionbckgd@2x.png', + className: 'presHeaderRow', + left: 0, + top: -5, + bottom: 0, + layout: 'vertical', + selectionStyle: 'none' + }); + headerRow[Codestrong.ui.backgroundSelectedProperty + 'Image'] = 'images/sessionbckgd@2x.png'; + + var bioRow = Ti.UI.createTableViewRow({ + hasChild: false, + height: 'auto', + width: '100%', + selectionStyle: 'none' + }); + + // Add the avatar image to the view + headerRow.add(av); + + if (presenterData.full_name != undefined) { + var fullName = Ti.UI.createLabel({ + text: Codestrong.cleanSpecialChars(presenterData.full_name), + font: { + fontSize: 20, + fontWeight: 'bold' + }, + textAlign: 'left', + color: '#000', + height: 'auto', + left: 120, + top: -95, + ellipsize: true, + touchEnabled: false + }); + headerRow.add(fullName); + } -(function() { - - Codestrong.ui.createPresenterDetailWindow = function(settings) { - Drupal.setDefaults(settings, { - title: 'title here', - uid: '', - name: '' - }); - - // var presenterData = settings.data; - var presenterData = Drupal.entity.db('main', 'user').load(settings.uid); - - var presenterDetailWindow = Titanium.UI.createWindow({ - id: 'presenterDetailWindow', - title: presenterData.full_name, - backgroundColor: '#FFF', - barColor: '#414444', - fullscreen: false - }); - presenterDetailWindow.orientationModes = [Ti.UI.PORTRAIT]; - - var tvData = []; - var blueBg = '#C4E2EF'; - - // Structure - var tv = Ti.UI.createTableView({ - textAlign: 'left', - width:'100%', - separatorColor:'#fff' - }); - tv.footerView = Ti.UI.createView({ - height:1, - opacity:0 - }); - - var av = Ti.UI.createImageView({ - image:presenterData.picture.replace(/^\s+|\s+$/g, '') || 'images/userpict-large.png', - left:0, - top:0, - height:110, - width:110, - defaultImage:'images/userpict-large.png', - backgroundColor: '#000', - touchEnabled: false - }); - var headerRow = Ti.UI.createTableViewRow({ - height:110, - backgroundImage:'images/sessionbckgd@2x.png', - className: 'presHeaderRow', - left:0, - top:-5, - bottom:0, - layout:'vertical', - selectionStyle:'none' - }); - headerRow[Codestrong.ui.backgroundSelectedProperty + 'Image'] = 'images/sessionbckgd@2x.png'; - - var bioRow = Ti.UI.createTableViewRow({ - hasChild:false, - height:'auto', - width:'100%', - selectionStyle:'none' - }); - - // Add the avatar image to the view - headerRow.add(av); - - if (presenterData.full_name != undefined) { - var fullName = Ti.UI.createLabel({ - text: Codestrong.cleanSpecialChars(presenterData.full_name), - font: {fontSize: 20, fontWeight: 'bold'}, - textAlign: 'left', - color: '#000', - height: 'auto', - left: 120, - top: -95, - ellipsize:true, - touchEnabled: false - }); - headerRow.add(fullName); - } + if (presenterData.company != undefined) { + var company = Ti.UI.createLabel({ + text: Codestrong.cleanSpecialChars(presenterData.company), + font: { + fontSize: 14, + fontWeight: 'bold' + }, + textAlign: 'left', + color: '#666', + height: 'auto', + left: 120, + touchEnabled: false + }); + headerRow.add(company); + } + tvData.push(headerRow); + + var sessions = getRelatedSessions(presenterData.full_name); + var sessionRow = []; + if (sessions && sessions.length) { + tvData.push(Codestrong.ui.createHeaderRow('Sessions')); + for (var i in sessions) { + sessionRow = Ti.UI.createTableViewRow({ + hasChild: true, + sessionTitle: Codestrong.cleanSpecialChars(sessions[i].title), + nid: sessions[i].nid, + height: 'auto', + backgroundColor: '#CE3016' + }); + sessionRow[Codestrong.ui.backgroundSelectedProperty + 'Color'] = Codestrong.ui.backgroundSelectedColor; + + var titleLabel = Ti.UI.createLabel({ + text: Codestrong.cleanSpecialChars(sessions[i].title), + font: { + fontSize: 14, + fontWeight: 'normal' + }, + left: 10, + top: 10, + right: 10, + bottom: 10, + height: 'auto', + color: '#fff', + font: { + fontWeight: 'bold' + }, + touchEnabled: false + }); + sessionRow.add(titleLabel); + + // create table view event listener + sessionRow.addEventListener('click', function (e) { + Codestrong.navGroup.open(Codestrong.ui.createSessionDetailWindow({ + title: e.rowData.sessionTitle, + nid: e.rowData.nid + }), { + animated: true + }); + }); + + tvData.push(sessionRow); + } + } - if (presenterData.company != undefined) { - var company = Ti.UI.createLabel({ - text:Codestrong.cleanSpecialChars(presenterData.company), - font:{fontSize: 14, fontWeight: 'bold'}, - textAlign: 'left', - color: '#666', - height: 'auto', - left: 120, - touchEnabled: false - }); - headerRow.add(company); - } - tvData.push(headerRow); - - var sessions = getRelatedSessions(presenterData.full_name); - var sessionRow = []; - if (sessions && sessions.length) { - tvData.push(Codestrong.ui.createHeaderRow('Sessions')); - for (var i in sessions) { - sessionRow = Ti.UI.createTableViewRow({ - hasChild:true, - sessionTitle: Codestrong.cleanSpecialChars(sessions[i].title), - nid:sessions[i].nid, - height: 'auto', - backgroundColor: '#CE3016' - }); - sessionRow[Codestrong.ui.backgroundSelectedProperty + 'Color'] = Codestrong.ui.backgroundSelectedColor; - - var titleLabel = Ti.UI.createLabel({ - text: Codestrong.cleanSpecialChars(sessions[i].title), - font: {fontSize:14, fontWeight:'normal'}, - left: 10, - top: 10, - right: 10, - bottom: 10, - height: 'auto', - color: '#fff', - font:{fontWeight:'bold'}, - touchEnabled: false - }); - sessionRow.add(titleLabel); - - // create table view event listener - sessionRow.addEventListener('click', function(e) { - Codestrong.navGroup.open(Codestrong.ui.createSessionDetailWindow({ - title: e.rowData.sessionTitle, - nid: e.rowData.nid - }), {animated:true}); - }); - - tvData.push(sessionRow); - } - } - - var bioText = (!presenterData.bio) ? "No biography available" : Codestrong.cleanSpecialChars(presenterData.bio.replace(/^[\s\n\r\t]+|[\s\n\r\t]+$/g, '').replace(/\n/g,"\n\n")); - var bio = Ti.UI.createLabel({ - text: bioText, - backgroundColor:'#fff', - textAlign:'left', - color:'#000', - height:'auto', - width: Codestrong.isAndroid() ? '92%' : 'auto', - top: 10, - bottom: 10, - font: { - fontSize:16 + var bioText = (!presenterData.bio) ? "No biography available" : Codestrong.cleanSpecialChars(presenterData.bio.replace(/^[\s\n\r\t]+|[\s\n\r\t]+$/g, '').replace(/\n/g, "\n\n")); + var bio = Ti.UI.createLabel({ + text: bioText, + backgroundColor: '#fff', + textAlign: 'left', + color: '#000', + height: 'auto', + width: Codestrong.isAndroid() ? '92%' : 'auto', + top: 10, + bottom: 10, + font: { + fontSize: 16 + } + }); + + if (!Codestrong.isAndroid()) { + bio.right = 10; + bio.left = 10; } - }); - - if (!Codestrong.isAndroid()) { - bio.right = 10; - bio.left = 10; - } - - bioRow.add(bio); - tvData.push(Codestrong.ui.createHeaderRow('Biography')); - tvData.push(bioRow); - - - tv.setData(tvData); - presenterDetailWindow.add(tv); - - return presenterDetailWindow; - }; - - function getRelatedSessions(name) { - var conn = Drupal.db.getConnection('main'); - var rows = conn.query("SELECT nid, title FROM node WHERE instructors LIKE ? ORDER BY start_date, nid", ['%' + name + '%']); - - var nids = []; - while(rows.isValidRow()) { - nids.push(rows.fieldByName('nid')); - rows.next(); - } - rows.close(); - - var sessions = Drupal.entity.db('main', 'node').loadMultiple(nids, ['start_date', 'nid']); - return sessions; - } + bioRow.add(bio); + tvData.push(Codestrong.ui.createHeaderRow('Biography')); + tvData.push(bioRow); -})(); + tv.setData(tvData); + presenterDetailWindow.add(tv); + + return presenterDetailWindow; + }; + + function getRelatedSessions(name) { + var conn = Drupal.db.getConnection('main'); + var rows = conn.query("SELECT nid, title FROM node WHERE instructors LIKE ? ORDER BY start_date, nid", ['%' + name + '%']); + + var nids = []; + while (rows.isValidRow()) { + nids.push(rows.fieldByName('nid')); + rows.next(); + } + rows.close(); + + return Drupal.entity.db('main', 'node').loadMultiple(nids, ['start_date', 'nid']); + } +})(); \ No newline at end of file diff --git a/Resources/windows/PresentersWindow.js b/Resources/windows/PresentersWindow.js index 323ea83..aae0c26 100644 --- a/Resources/windows/PresentersWindow.js +++ b/Resources/windows/PresentersWindow.js @@ -14,200 +14,204 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ +(function () { -(function() { - - Codestrong.ui.createPresentersWindow = function() { - var PresentersWindow = Titanium.UI.createWindow({ - id: 'presentersWindow', - title: 'Speakers', - backgroundColor: '#FFF', - barColor: '#414444', - fullscreen: false - }); - - // Create the table view - var tableview = Titanium.UI.createTableView({ - backgroundColor: '#fff' - }); - - PresentersWindow.doRefresh = function() { - var nameList = getNameList(); - - // I want our list of names to have the usernames mixed in, and they usually - // start with lowercase, so we need to create a custom sortorder that ignores case. - var sortedNames = nameList.sort(function(a, b) { - a = a.toLowerCase(); - b = b.toLowerCase(); - if (a > b) { return 1; } - if (a < b) { return -1; } - return 0; - }); - - // Now we can do something, like, oh I don't know, build the table :) - var headerLetter = ''; - var index = []; - var presenterRow = []; - var data = []; - - for (var i in sortedNames) { - var user = sortedNames[i].split(':'); - var uid = parseInt(user[1]) + 0; - var fullName = user[0] + ''; - - var shortName = user[2] + ''; - var name = shortName; - if (fullName.charAt(fullName.length-2) == ',') { - fullName = fullName.slice(0, fullName.length - 2); - } - else { - name = fullName; - } - - presenterRow = Ti.UI.createTableViewRow({ - hasChild: Codestrong.isAndroid(), - className: 'presenters_row', - selectedColor: '#999', - backgroundColor: '#fff', - color: '#000', - name: name, - uid: uid, - height: 40, - layout: 'auto' - }); - presenterRow[Codestrong.ui.backgroundSelectedProperty + 'Color'] = Codestrong.ui.backgroundSelectedColor; - - if (fullName == shortName) { - fullName = ''; - } - else { - fullName = Codestrong.cleanSpecialChars(fullName); - var firstLastName = fullName.split(', '); - fullName = firstLastName[1] + ' ' + firstLastName[0]; - shortName = "(" + shortName + ")"; - var lastName = firstLastName[0]; - var firstName = firstLastName[1]; - } - - - // Android can't handle some of this label manipulation - if (Codestrong.isAndroid()) { - presenterRow.add(Ti.UI.createLabel({ - text: fullName, - fontFamily:'sans-serif', - font: { - fontWeight:'bold' - }, - left: (fullName != '') ? 9 : 0, - height: 40, - color: '#000', - touchEnabled:false - })); - - - } - else { - // iPhone - make it fancy - if (fullName != '') { - var nameView = Ti.UI.createView({ - height:40, - layout:'horizontal' - }); - - var firstNameLabel = Ti.UI.createLabel({ - text: firstName, - font:'Helvetica', - left: 10, - height: 40, - width: 'auto', - color: '#000', - touchEnabled:false - }); - nameView.add(firstNameLabel); - - var lastNameLabel = Ti.UI.createLabel({ - text: lastName, - font:'Helvetica-Bold', - left: 5, - height: 40, - width: 'auto', - color: '#000', - touchEnabled:false - }); - nameView.add(lastNameLabel); - presenterRow.add(nameView); - } - } - - // If there is a new last name first letter, insert a header in the table. - // We also push a new index so we can create a right side index for iphone. - if (headerLetter == '' || name.charAt(0).toUpperCase() != headerLetter) { - headerLetter = name.charAt(0).toUpperCase(); - data.push(Codestrong.ui.createHeaderRow(headerLetter)); - index.push({title:headerLetter,index:i}); - } - - data.push(presenterRow); - } - - tableview.setData(data); - tableview.index = index; - }; - - PresentersWindow.doRefresh(); - Ti.App.addEventListener('app:update_presenters', function() { - PresentersWindow.doRefresh(); - }); - - // create table view event listener - tableview.addEventListener('click', function(e) { - if (!e.rowData.uid) { - return; - } - // event data - var index = e.index; - Codestrong.navGroup.open(Codestrong.ui.createPresenterDetailWindow({ - title: e.rowData.name, - uid: e.rowData.uid, - name: e.rowData.name - }), {animated:true}); - }); - - // add table view to the window - PresentersWindow.add(tableview); - - return PresentersWindow; - }; - - - function getNameList() { - var conn = Drupal.db.getConnection('main'); - var rows = conn.query("SELECT uid, name, full_name FROM user"); - - // As far as I can tell, objects aren't allowed to be sorted, so even though - // I can write a sort on say a.lastName - it won't stay sorted (yes I tried) - // so I have to build an array, sort it, then decompile it to use it. - // Have I mentioned lately that javascript is not my favorite language right now? - var nameList = []; - if (rows) { - while (rows.isValidRow()) { - var uid = rows.fieldByName('uid'); - var full = rows.fieldByName('full_name'); - if (full) { - var names = rows.fieldByName('full_name').split(' '); - var lastName = names[names.length -1]; - var firstName = full.substr(0,full.length - (lastName.length + 1)); - nameList.push(lastName + ', ' + firstName + ':' + rows.fieldByName('uid') + ':' + rows.fieldByName('name')); - } - else { - nameList.push(rows.fieldByName('name') + ':' + rows.fieldByName('uid') + ':' + rows.fieldByName('name')); + Codestrong.ui.createPresentersWindow = function () { + var PresentersWindow = Titanium.UI.createWindow({ + id: 'presentersWindow', + title: 'Speakers', + backgroundColor: '#FFF', + barColor: '#414444', + fullscreen: false + }); + + // Create the table view + var tableview = Titanium.UI.createTableView({ + backgroundColor: '#fff' + }); + + PresentersWindow.doRefresh = function () { + var nameList = getNameList(); + + // I want our list of names to have the usernames mixed in, and they usually + // start with lowercase, so we need to create a custom sortorder that ignores case. + var sortedNames = nameList.sort(function (a, b) { + a = a.toLowerCase(); + b = b.toLowerCase(); + if (a > b) { + return 1; + } + if (a < b) { + return -1; + } + return 0; + }); + + // Now we can do something, like, oh I don't know, build the table :) + var headerLetter = ''; + var index = []; + var presenterRow = []; + var data = []; + + for (var i in sortedNames) { + var user = sortedNames[i].split(':'); + var uid = parseInt(user[1]) + 0; + var fullName = user[0] + ''; + + var shortName = user[2] + ''; + var name = shortName; + if (fullName.charAt(fullName.length - 2) == ',') { + fullName = fullName.slice(0, fullName.length - 2); + } else { + name = fullName; + } + + presenterRow = Ti.UI.createTableViewRow({ + hasChild: Codestrong.isAndroid(), + className: 'presenters_row', + selectedColor: '#999', + backgroundColor: '#fff', + color: '#000', + name: name, + uid: uid, + height: 40, + layout: 'auto' + }); + presenterRow[Codestrong.ui.backgroundSelectedProperty + 'Color'] = Codestrong.ui.backgroundSelectedColor; + + if (fullName == shortName) { + fullName = ''; + } else { + fullName = Codestrong.cleanSpecialChars(fullName); + var firstLastName = fullName.split(', '); + fullName = firstLastName[1] + ' ' + firstLastName[0]; + shortName = "(" + shortName + ")"; + var lastName = firstLastName[0]; + var firstName = firstLastName[1]; + } + + + // Android can't handle some of this label manipulation + if (Codestrong.isAndroid()) { + presenterRow.add(Ti.UI.createLabel({ + text: fullName, + fontFamily: 'sans-serif', + font: { + fontWeight: 'bold' + }, + left: (fullName != '') ? 9 : 0, + height: 40, + color: '#000', + touchEnabled: false + })); + + + } else { + // iPhone - make it fancy + if (fullName != '') { + var nameView = Ti.UI.createView({ + height: 40, + layout: 'horizontal' + }); + + var firstNameLabel = Ti.UI.createLabel({ + text: firstName, + font: 'Helvetica', + left: 10, + height: 40, + width: 'auto', + color: '#000', + touchEnabled: false + }); + nameView.add(firstNameLabel); + + var lastNameLabel = Ti.UI.createLabel({ + text: lastName, + font: 'Helvetica-Bold', + left: 5, + height: 40, + width: 'auto', + color: '#000', + touchEnabled: false + }); + nameView.add(lastNameLabel); + presenterRow.add(nameView); + } + } + + // If there is a new last name first letter, insert a header in the table. + // We also push a new index so we can create a right side index for iphone. + if (headerLetter == '' || name.charAt(0).toUpperCase() != headerLetter) { + headerLetter = name.charAt(0).toUpperCase(); + data.push(Codestrong.ui.createHeaderRow(headerLetter)); + index.push({ + title: headerLetter, + index: i + }); + } + + data.push(presenterRow); + } + + tableview.setData(data); + tableview.index = index; + }; + + PresentersWindow.doRefresh(); + Ti.App.addEventListener('app:update_presenters', function () { + PresentersWindow.doRefresh(); + }); + + // create table view event listener + tableview.addEventListener('click', function (e) { + if (!e.rowData.uid) { + return; + } + // event data + var index = e.index; + Codestrong.navGroup.open(Codestrong.ui.createPresenterDetailWindow({ + title: e.rowData.name, + uid: e.rowData.uid, + name: e.rowData.name + }), { + animated: true + }); + }); + + // add table view to the window + PresentersWindow.add(tableview); + + return PresentersWindow; + }; + + + function getNameList() { + var conn = Drupal.db.getConnection('main'); + var rows = conn.query("SELECT uid, name, full_name FROM user"); + + // As far as I can tell, objects aren't allowed to be sorted, so even though + // I can write a sort on say a.lastName - it won't stay sorted (yes I tried) + // so I have to build an array, sort it, then decompile it to use it. + // Have I mentioned lately that javascript is not my favorite language right now? + var nameList = []; + if (rows) { + while (rows.isValidRow()) { + var uid = rows.fieldByName('uid'); + var full = rows.fieldByName('full_name'); + if (full) { + var names = rows.fieldByName('full_name').split(' '); + var lastName = names[names.length - 1]; + var firstName = full.substr(0, full.length - (lastName.length + 1)); + nameList.push(lastName + ', ' + firstName + ':' + rows.fieldByName('uid') + ':' + rows.fieldByName('name')); + } else { + nameList.push(rows.fieldByName('name') + ':' + rows.fieldByName('uid') + ':' + rows.fieldByName('name')); + } + rows.next(); + } + rows.close(); } - rows.next(); - } - rows.close(); + + return nameList; } - return nameList; - } - -})(); +})(); \ No newline at end of file diff --git a/Resources/windows/SessionDetailWindow.js b/Resources/windows/SessionDetailWindow.js index e7e5183..c0e8ef7 100644 --- a/Resources/windows/SessionDetailWindow.js +++ b/Resources/windows/SessionDetailWindow.js @@ -14,234 +14,241 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ +(function () { + + Codestrong.ui.createSessionDetailWindow = function (settings) { + Drupal.setDefaults(settings, { + title: 'title here', + nid: '' + }); + var commonPadding = 15; + var sessionDetailWindow = Titanium.UI.createWindow({ + id: 'sessionDetailWindow', + title: settings.title, + backgroundColor: '#FFF', + barColor: '#414444', + fullscreen: false + }); + sessionDetailWindow.orientationModes = [Ti.UI.PORTRAIT]; + + // Build session data + var sessionData = Drupal.entity.db('main', 'node').load(settings.nid); + var tvData = []; + var blueBg = '#FFF'; + + // Structure + var tv = Ti.UI.createTableView({ + textAlign: 'left', + layout: 'vertical', + separatorColor: '#fff' + }); + tv.footerView = Ti.UI.createView({ + height: 1, + opacity: 0 + }); + + var headerRow = Ti.UI.createTableViewRow({ + height: 'auto', + left: 0, + top: -5, + bottom: 10, + layout: 'vertical', + className: 'mainHeaderRow', + backgroundImage: 'images/sessionbckgd@2x.png', + backgroundPosition: 'bottom left', + selectionStyle: 'none' + }); + headerRow[Codestrong.ui.backgroundSelectedProperty + 'Image'] = 'images/sessionbckgd@2x.png'; + + var bodyRow = Ti.UI.createTableViewRow({ + hasChild: false, + height: 'auto', + backgroundColor: blueBg, + left: 0, + top: -5, + bottom: 10, + layout: 'vertical', + className: 'bodyRow', + selectionStyle: 'none' + }); + + if (sessionData.title) { + var titleLabel = Ti.UI.createLabel({ + text: Codestrong.cleanSpecialChars(sessionData.title), + font: { + fontSize: 28, + fontWeight: 'bold' + }, + textAlign: 'left', + color: '#000', + left: commonPadding, + top: 18, + bottom: 7, + right: commonPadding, + height: 'auto' + }); + headerRow.add(titleLabel); + } -(function() { - - Codestrong.ui.createSessionDetailWindow = function(settings) { - Drupal.setDefaults(settings, { - title: 'title here', - nid: '' - }); - var commonPadding = 15; - var sessionDetailWindow = Titanium.UI.createWindow({ - id: 'sessionDetailWindow', - title: settings.title, - backgroundColor: '#FFF', - barColor: '#414444', - fullscreen: false - }); - sessionDetailWindow.orientationModes = [Ti.UI.PORTRAIT]; - - // Build session data - var sessionData = Drupal.entity.db('main', 'node').load(settings.nid); - - // Build the page: - var tvData = []; - var blueBg = '#FFF'; - - // Structure - var tv = Ti.UI.createTableView({ - textAlign: 'left', - layout:'vertical', - separatorColor:'#fff' - }); - tv.footerView = Ti.UI.createView({ - height:1, - opacity:0 - }); - - var headerRow = Ti.UI.createTableViewRow({ - height: 'auto', - left: 0, - top: -5, - bottom: 10, - layout: 'vertical', - className: 'mainHeaderRow', - backgroundImage:'images/sessionbckgd@2x.png', - backgroundPosition:'bottom left', - selectionStyle:'none' - }); - headerRow[Codestrong.ui.backgroundSelectedProperty + 'Image'] = 'images/sessionbckgd@2x.png'; - - var bodyRow = Ti.UI.createTableViewRow({ - hasChild: false, - height: 'auto', - backgroundColor: blueBg, - left: 0, - top: -5, - bottom: 10, - layout: 'vertical', - className: 'bodyRow', - selectionStyle:'none' - }); - - if (sessionData.title) { - var titleLabel = Ti.UI.createLabel({ - text: Codestrong.cleanSpecialChars(sessionData.title), - font: {fontSize: 28, fontWeight: 'bold'}, - textAlign: 'left', - color: '#000', - left: commonPadding, - top: 18, - bottom: 7, - right: commonPadding, - height: 'auto' - }); - headerRow.add(titleLabel); - } + if (sessionData.start_date) { + var matches = /^(\d{4})\-(\d{2})\-(\d{2})/.exec(sessionData.start_date); + var startDate = new Date(matches[1], matches[2] - 1, matches[3]); + var datetime = Ti.UI.createLabel({ + text: Codestrong.datetime.cleanDate(startDate) + ', ' + Codestrong.datetime.cleanTime(sessionData.start_date), + font: { + fontSize: 18, + fontWeight: 'normal' + }, + textAlign: 'left', + color: '#000', + left: commonPadding, + top: 'auto', + bottom: 5, + right: 'auto', + height: 'auto' + }); + headerRow.add(datetime); + } - if (sessionData.start_date) { - var matches = /^(\d{4})\-(\d{2})\-(\d{2})/.exec(sessionData.start_date); - var startDate = new Date(matches[1], matches[2]-1, matches[3]); - var datetime = Ti.UI.createLabel({ - text: Codestrong.datetime.cleanDate(startDate) + ', ' + Codestrong.datetime.cleanTime(sessionData.start_date), - font: {fontSize: 18, fontWeight: 'normal'}, - textAlign: 'left', - color: '#000', - left: commonPadding, - top: 'auto', - bottom: 5, - right: 'auto', - height: 'auto' - }); - headerRow.add(datetime); - } + var skipRoom; + if (sessionData.title === 'Lunch' || sessionData.title === 'Break' || sessionData.title.indexOf('Party') !== -1) { + skipRoom = true; + } - // Don't show a room for Lunch and Break, since what's on the web site is - // actually completely wrong. It's hacked in for the site display, but - // wrong for the mobile app. We do want to show rooms for the keynotes, - // however, which is why we can't jus exclude schedule_items. - var skipRoom; - if (sessionData.title === 'Lunch' || sessionData.title === 'Break' || sessionData.title.indexOf('Party') !== -1) { - skipRoom = true; - } + if (sessionData.room && !skipRoom) { + var room = Ti.UI.createLabel({ + text: sessionData.room, + font: { + fontSize: 18, + fontWeight: 'normal' + }, + textAlign: 'left', + color: '#000', + left: commonPadding, + top: 'auto', + bottom: 12, + right: commonPadding, + height: 'auto' + }); + headerRow.add(room); + } - if (sessionData.room && !skipRoom) { - var room = Ti.UI.createLabel({ - text: sessionData.room, - font: {fontSize: 18, fontWeight: 'normal'}, - textAlign: 'left', - color: '#000', - left: commonPadding, - top: 'auto', - bottom: 12, - right: commonPadding, - height: 'auto' - }); - headerRow.add(room); - } - - if (sessionData.body) { - var body = Ti.UI.createLabel({ - text: Codestrong.cleanSpecialChars(sessionData.body.replace('\n','\n\n')), - backgroundColor:'#fff', - textAlign:'left', - color:'#000', - height: 'auto', - width: Codestrong.isAndroid() ? '92%' : 'auto', - top: 15, - bottom: 15, - font: { - fontSize:16 + if (sessionData.body) { + var body = Ti.UI.createLabel({ + text: Codestrong.cleanSpecialChars(sessionData.body.replace('\n', '\n\n')), + backgroundColor: '#fff', + textAlign: 'left', + color: '#000', + height: 'auto', + width: Codestrong.isAndroid() ? '92%' : 'auto', + top: 15, + bottom: 15, + font: { + fontSize: 16 + } + }); + bodyRow.add(body); } - }); - bodyRow.add(body); - } - - if (!Codestrong.isAndroid()) { - body.right = commonPadding; - body.left = commonPadding; - } - tvData.push(headerRow); - - //if (sessionData.instructors && sessionData.instructors.length) { - if (sessionData.instructors) { - var instructorList = sessionData.instructors.split(","); - for (var k = 0; k < instructorList.length; k++) { - instructorList[k] = instructorList[k].replace(/^\s+|\s+$/g, ''); - } - - // Get the presenter information. - var presenterData = Drupal.entity.db('main', 'user').loadByField('full_name', instructorList);//sessionData.instructors); - - tvData.push(Codestrong.ui.createHeaderRow((instructorList.length > 1) ? 'Speakers' : 'Speaker')); - for (var j in presenterData) { - tvData.push(renderPresenter(presenterData[j])); - } - } + if (!Codestrong.isAndroid()) { + body.right = commonPadding; + body.left = commonPadding; + } - tvData.push(Codestrong.ui.createHeaderRow('Description')); - tvData.push(bodyRow); - - tv.addEventListener('click', function(e) { - if (e.source.presenter != undefined){ - var fullName = e.source.presenter.full_name || ''; - Codestrong.navGroup.open(Codestrong.ui.createPresenterDetailWindow({ - title: fullName, - uid: e.source.presenter.uid - }), {animated:true}); - } - }); - tv.setData(tvData); - sessionDetailWindow.add(tv); - - return sessionDetailWindow; - }; - - function renderPresenter(presenter) { - var userPict = presenter.picture.replace(/^\s+|\s+$/g, '') || 'images/userpict-large.png'; - - var av = Ti.UI.createImageView({ - image:userPict, - left:5, - top:5, - height:50, - width:50, - defaultImage:'images/userpict-large.png', - backgroundColor: '#000', - touchEnabled: false - }); - - var presRow = Ti.UI.createTableViewRow({ - presenter: presenter, - height: 60, - className: 'presenterRow', - borderColor: '#C4E2EF', - hasChild: true, - backgroundColor: '#CE3016', - layout:'vertical' - }); - presRow[Codestrong.ui.backgroundSelectedProperty + 'Color'] = Codestrong.ui.backgroundSelectedColor; - - presRow.add(av); - var presenterFullName2 = Ti.UI.createLabel({ - presenter: presenter, - text: Codestrong.cleanSpecialChars(presenter.full_name), - font: {fontSize:18, fontWeight:'bold'}, - left: 75, - top: -45, - height: 'auto', - color: '#fff', - touchEnabled: false - }); - - var presenterName2 = Ti.UI.createLabel({ - presenter: presenter, - text: Codestrong.cleanSpecialChars(presenter.company), - font:{fontSize:14, fontWeight:'normal'}, - left: 75, - bottom: 10, - height: 'auto', - color: "#fff", - touchEnabled: false - }); - - presRow.add(presenterFullName2); - presRow.add(presenterName2); - - return presRow; - } - -})(); + tvData.push(headerRow); + + //if (sessionData.instructors && sessionData.instructors.length) { + if (sessionData.instructors) { + var instructorList = sessionData.instructors.split(","); + for (var k = 0; k < instructorList.length; k++) { + instructorList[k] = instructorList[k].replace(/^\s+|\s+$/g, ''); + } + + // Get the presenter information. + var presenterData = Drupal.entity.db('main', 'user').loadByField('full_name', instructorList); //sessionData.instructors); + tvData.push(Codestrong.ui.createHeaderRow((instructorList.length > 1) ? 'Speakers' : 'Speaker')); + for (var j in presenterData) { + tvData.push(renderPresenter(presenterData[j])); + } + } + tvData.push(Codestrong.ui.createHeaderRow('Description')); + tvData.push(bodyRow); + + tv.addEventListener('click', function (e) { + if (e.source.presenter != undefined) { + var fullName = e.source.presenter.full_name || ''; + Codestrong.navGroup.open(Codestrong.ui.createPresenterDetailWindow({ + title: fullName, + uid: e.source.presenter.uid + }), { + animated: true + }); + } + }); + tv.setData(tvData); + sessionDetailWindow.add(tv); + + return sessionDetailWindow; + }; + + function renderPresenter(presenter) { + var userPict = presenter.picture.replace(/^\s+|\s+$/g, '') || 'images/userpict-large.png'; + + var av = Ti.UI.createImageView({ + image: userPict, + left: 5, + top: 5, + height: 50, + width: 50, + defaultImage: 'images/userpict-large.png', + backgroundColor: '#000', + touchEnabled: false + }); + + var presRow = Ti.UI.createTableViewRow({ + presenter: presenter, + height: 60, + className: 'presenterRow', + borderColor: '#C4E2EF', + hasChild: true, + backgroundColor: '#CE3016', + layout: 'vertical' + }); + presRow[Codestrong.ui.backgroundSelectedProperty + 'Color'] = Codestrong.ui.backgroundSelectedColor; + + presRow.add(av); + var presenterFullName2 = Ti.UI.createLabel({ + presenter: presenter, + text: Codestrong.cleanSpecialChars(presenter.full_name), + font: { + fontSize: 18, + fontWeight: 'bold' + }, + left: 75, + top: -45, + height: 'auto', + color: '#fff', + touchEnabled: false + }); + + var presenterName2 = Ti.UI.createLabel({ + presenter: presenter, + text: Codestrong.cleanSpecialChars(presenter.company), + font: { + fontSize: 14, + fontWeight: 'normal' + }, + left: 75, + bottom: 10, + height: 'auto', + color: "#fff", + touchEnabled: false + }); + + presRow.add(presenterFullName2); + presRow.add(presenterName2); + + return presRow; + } +})(); \ No newline at end of file diff --git a/Resources/windows/TwitterWindow.js b/Resources/windows/TwitterWindow.js index 1884744..3e6a2ab 100644 --- a/Resources/windows/TwitterWindow.js +++ b/Resources/windows/TwitterWindow.js @@ -14,321 +14,315 @@ * You should have received a copy of the GNU General Public License * along with CODESTRONG Mobile. If not, see . */ +(function () { + Codestrong.ui.createTwitterWindow = function () { + var twitterTimeout = 11000; + var tweetCount = 50; + var firstRun = true; -(function() { - Codestrong.ui.createTwitterWindow = function() { - var twitterTimeout = 11000; - var tweetCount = 50; - var firstRun = true; - - var createTwitterTable = function(search) { - return Ti.UI.createTableView({ - height:'100%', - width:'100%', - viewTitle:search - }); - } - var data = [ - { - search:'#codestrong', - url: 'http://search.twitter.com/search.json?q=%23codestrong&result_type=recent&rpp=' + tweetCount, - table: createTwitterTable('#codestrong'), - isSearch: true - }, - { - search:'@appcelerator', - url: 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=appcelerator&count=' + tweetCount, - table: createTwitterTable('@appcelerator'), - isSearch: false - }, - { - search:'@codestrong', - url: 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=codestrong&count=' + tweetCount, - table: createTwitterTable('@codestrong'), - isSearch: false - } - - ]; - var loadedViews = []; - - var twitterWindow = Titanium.UI.createWindow({ - id: 'twitterWindow', - title: 'Twitter News', - backgroundColor: '#FFF', - barColor: '#414444', - fullscreen: false - }); - var tabbedBarView = Ti.UI.createView({ - backgroundColor:'#555', - top:0, - height:36 - }); - var tabbedBar = Ti.UI.createView({ - top:0, - backgroundColor: '#000', - height:36, - width:Ti.Platform.displayCaps.platformWidth - }); - - for (var index in data) { - myEntry = data[index]; - myEntry.table.addEventListener('click', function(e) { - Codestrong.navGroup.open(Codestrong.ui.createTwitterDetailWindow({ - title: e.rowData.user, - text: e.rowData.tweet, - name: e.rowData.user, - date: e.rowData.date - }), {animated:true}); - }); - - var bgImage = 'images/buttonbar/button2_selected.png'; - if (index == 1) { - bgImage = 'images/buttonbar/button2_unselected_shadowL.png'; - } else if (index == 2) { - bgImage = 'images/buttonbar/button2_unselected_shadowR.png'; - } - - var tabView = Ti.UI.createView({ - backgroundImage: bgImage, - height:36, - left: index * (Ti.Platform.displayCaps.platformWidth/data.length), - right: Ti.Platform.displayCaps.platformWidth - ((parseInt(index) + 1) * (Ti.Platform.displayCaps.platformWidth/data.length)), - index: index - }); - - var tabLabel = Ti.UI.createLabel({ - text: myEntry.search, - textAlign:'center', - color: '#fff', - height:'auto', - touchEnabled: false, - font: { - fontSize:14 - } - }); - tabView.addEventListener('click', function(e) { - for (var i = 0; i < data.length; i++) { - if (e.source.index == 0) { - data[0].tabView.backgroundImage = 'images/buttonbar/button2_selected.png'; - data[1].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowL.png'; - data[2].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowR.png'; - } else if (e.source.index == 1) { - data[0].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowR.png'; - data[1].tabView.backgroundImage = 'images/buttonbar/button2_selected.png'; - data[2].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowL.png'; - } else if (e.source.index == 2) { - data[0].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowL.png'; - data[1].tabView.backgroundImage = 'images/buttonbar/button2_unselected_shadowR.png'; - data[2].tabView.backgroundImage = 'images/buttonbar/button2_selected.png'; - } - - if (e.source.index == i) { - scrollable.scrollToView(data[i].table); - } - } - }); - - tabView.add(tabLabel); - tabbedBar.add(tabView); - myEntry.tabView = tabView; - } - - var scrollable = Ti.UI.createScrollableView({ - showPagingControl: true, - backgroundColor: '#000000', - top:30, - views:[ - data[0].table, - data[1].table, - data[2].table - ] - }); - scrollable.addEventListener('scroll', function(e) { - if (e.view) { - data[e.currentPage].tabView.fireEvent('click'); - } - }); - - twitterWindow.add(scrollable); - tabbedBarView.add(tabbedBar); - twitterWindow.add(tabbedBarView); + var createTwitterTable = function (search) { + return Ti.UI.createTableView({ + height: '100%', + width: '100%', + viewTitle: search + }); + }; + var data = [{ + search: '#codestrong', + url: 'http://search.twitter.com/search.json?q=%23codestrong&result_type=recent&rpp=' + tweetCount, + table: createTwitterTable('#codestrong'), + isSearch: true + }, { + search: '@appcelerator', + url: 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=appcelerator&count=' + tweetCount, + table: createTwitterTable('@appcelerator'), + isSearch: false + }, { + search: '@codestrong', + url: 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=codestrong&count=' + tweetCount, + table: createTwitterTable('@codestrong'), + isSearch: false + } - // Using the parsing method shown https://gist.github.com/819929 - var tweetWebJs = "document.body.addEventListener('touchmove', function(e) { e.preventDefault();}, false);"; - var baseHTMLStart = '', - baseHTMLEnd = ''; + ]; + var loadedViews = []; - // set this to true if you are only tracking one user - var single = true; - var getTweets = function(entry) { - // create table view data object - var tvData = []; + var twitterWindow = Titanium.UI.createWindow({ + id: 'twitterWindow', + title: 'Twitter News', + backgroundColor: '#FFF', + barColor: '#414444', + fullscreen: false + }); + var tabbedBarView = Ti.UI.createView({ + backgroundColor: '#555', + top: 0, + height: 36 + }); + var tabbedBar = Ti.UI.createView({ + top: 0, + backgroundColor: '#000', + height: 36, + width: Ti.Platform.displayCaps.platformWidth + }); - var xhr = Ti.Network.createHTTPClient(); - xhr.timeout = twitterTimeout; - xhr.open("GET", entry.url); - - xhr.onerror = function() { - loadedViews.push(entry.table); - if (loadedViews.length >= data.length) { - loadedViews = []; - Codestrong.ui.activityIndicator.hideModal(); - } - }; - - xhr.onload = function() { - try { - var json = eval('('+this.responseText+')'); - var tweets = entry.isSearch ? json.results : json; - for (var c=0;c'; - entry.table.setData(tvData); - loadedViews.push(entry.table); - if (loadedViews.length >= data.length) { - loadedViews = []; - Codestrong.ui.activityIndicator.hideModal(); - } - } - catch(e) { - Ti.API.info(e); - } - }; - // Get the data - xhr.send(); - } + // set this to true if you are only tracking one user + var single = true; + var getTweets = function (entry) { + // create table view data object + var tvData = []; + + var xhr = Ti.Network.createHTTPClient(); + xhr.timeout = twitterTimeout; + xhr.open("GET", entry.url); - var reloadAllTweets = function() { - Codestrong.ui.activityIndicator.showModal('Loading latest tweets...', twitterTimeout, 'Twitter timed out. All streams may not have updated.'); - for (var i = 0; i < data.length; i++) { - getTweets(data[i]); - } - }; + xhr.onerror = function () { + loadedViews.push(entry.table); + if (loadedViews.length >= data.length) { + loadedViews = []; + Codestrong.ui.activityIndicator.hideModal(); + } + }; - // Get the tweets for 'twitter_name' - if (Ti.Network.online) { - twitterWindow.addEventListener('open', function(e) { - if (firstRun) { - firstRun = false; - reloadAllTweets(); - } - }); + xhr.onload = function () { + try { + var json = eval('(' + this.responseText + ')'); + var tweets = entry.isSearch ? json.results : json; + for (var c = 0; c < tweets.length; c++) { + var tweet = tweets[c].text; + var user = entry.isSearch ? tweets[c].from_user : tweets[c].user.screen_name; + var avatarWidth = 48; + var avatar; + if (single == true && !entry.isSearch) { + avatar = tweets[1].user.profile_image_url; + } else { + avatar = entry.isSearch ? tweets[c].profile_image_url : tweets[c].user.profile_image_url; - if (Codestrong.isAndroid()) { - twitterWindow.activity.onCreateOptionsMenu = function(e) { - var menuitem = e.menu.add({ - title : 'Refresh Tweets' - }); - menuitem.addEventListener('click', function(e) { - reloadAllTweets(); - }); - }; - } else { - var button = Ti.UI.createButton({ - systemButton: Ti.UI.iPhone.SystemButton.REFRESH - }); - button.addEventListener('click', function(e) { - reloadAllTweets(); - }); - twitterWindow.rightNavButton = button; - } - } else { - alert('No network connection detected.'); - } + } - return twitterWindow; - }; + var created_at = Codestrong.datetime.getTwitterInterval(tweets[c].created_at); + var bgcolor = (c % 2) === 0 ? '#fff' : '#eee'; -})(); + var row = Ti.UI.createTableViewRow({ + hasChild: true, + className: 'twitterRow', + backgroundColor: bgcolor, + height: 'auto', + date: created_at, + user: user, + tweet: tweet + }); + + // Create a vertical layout view to hold all the info labels and images for each tweet + var post_view = Ti.UI.createView({ + height: 15, + left: 64, + top: 10, + right: 5 + }); + + var av = Ti.UI.createImageView({ + image: avatar, + left: 10, + top: 10, + height: 48, + width: avatarWidth + }); + row.add(av); + + var user_label = Ti.UI.createLabel({ + text: user, + left: 0, + width: 120, + top: -3, + height: 20, + textAlign: 'left', + color: '#444444', + font: { + fontFamily: 'Trebuchet MS', + fontSize: 14, + fontWeight: 'bold' + } + }); + post_view.add(user_label); + + var date_label = Ti.UI.createLabel({ + text: created_at, + right: 20, + top: -2, + height: 20, + textAlign: 'right', + width: 110, + color: '#444444', + font: { + fontFamily: 'Trebuchet MS', + fontSize: 12 + } + }); + post_view.add(date_label); + row.add(post_view); + + var tweet_text = Ti.UI.createLabel({ + text: tweet, + left: 64, + top: 30, + right: 20, + color: '#333', + height: 'auto', + textAlign: 'left', + bottom: 10, + font: { + fontSize: 14 + } + }); + + // Add the tweet to the view + row.add(tweet_text); + tvData[c] = row; + } + + entry.table.setData(tvData); + loadedViews.push(entry.table); + if (loadedViews.length >= data.length) { + loadedViews = []; + Codestrong.ui.activityIndicator.hideModal(); + } + } catch (e) { + Ti.API.info(e); + } + }; + // Get the data + xhr.send(); + } + + var reloadAllTweets = function () { + Codestrong.ui.activityIndicator.showModal('Loading latest tweets...', twitterTimeout, 'Twitter timed out. All streams may not have updated.'); + for (var i = 0; i < data.length; i++) { + getTweets(data[i]); + } + }; + + // Get the tweets for 'twitter_name' + if (Ti.Network.online) { + twitterWindow.addEventListener('open', function (e) { + if (firstRun) { + firstRun = false; + reloadAllTweets(); + } + }); + + if (Codestrong.isAndroid()) { + twitterWindow.activity.onCreateOptionsMenu = function (e) { + var menuitem = e.menu.add({ + title: 'Refresh Tweets' + }); + menuitem.addEventListener('click', function (e) { + reloadAllTweets(); + }); + }; + } else { + var button = Ti.UI.createButton({ + systemButton: Ti.UI.iPhone.SystemButton.REFRESH + }); + button.addEventListener('click', function (e) { + reloadAllTweets(); + }); + twitterWindow.rightNavButton = button; + } + } else { + alert('No network connection detected.'); + } + return twitterWindow; + }; +})(); \ No newline at end of file