diff --git a/Resources/app.js b/Resources/app.js index 1973d37..28675b9 100644 --- a/Resources/app.js +++ b/Resources/app.js @@ -4,7 +4,6 @@ Ti.App.Properties.setBool('map_initialized', false); // this sets the background color of the master UIView (when there are no windows/tab groups on it) Titanium.UI.setBackgroundColor('#000'); -Ti.API.debug('including the app helpers and windows'); Ti.include( 'march-hare/march-hare.js', @@ -18,12 +17,11 @@ Ti.include( var reportsInitialized = false; -var win = MarchHare.ui.createMapWindow(); - -win.open(); +var tabGroup; +var mapTab; if (Ti.Platform.osname == 'android') { - var win = Ti.UI.currentWindow; + var win = MarchHare.ui.createMapWindow(); var activity = Ti.Android.currentActivity; activity.onCreateOptionsMenu = function(e){ @@ -39,25 +37,77 @@ if (Ti.Platform.osname == 'android') { settingsWin.open({}); }); }; + win.open(); } -/* else { - // TODO: create iOS options menu - // iOS code might look something like this: where iconWin is an actuall - // icon? I am not sure how menus are done in iOS - var rightButton = Ti.UI.createButton({ - systemButton: Ti.UI.iPhone.SystemButton.REFRESH - }); - iconWin.rightNavButton = rightButton; - rightButton.addEventListener('click', function () { - Ti.fireEvent('codestrong:update_data'); - }); + // Create a tab group + tabGroup = Titanium.UI.createTabGroup(); + + // Create Main tab + var mapWin = MarchHare.ui.createMapWindow(); + mapTab = Titanium.UI.createTab({ + title: 'Map', + icon: '/img/KS_nav_map.png', + window: mapWin + }); + + // Create reports win/tab + var reportsWin = MarchHare.ui.createReportsWindow(); + var reportsTab = Titanium.UI.createTab({ + title: 'Reports', + icon: '/img/KS_nav_ui.png', + window: reportsWin + }); + + // Add tabs + tabGroup.addTab(mapTab); + tabGroup.addTab(reportsTab); + + tabGroup.setActiveTab(mapTab); + tabGroup.open(); + + // There is a situation where the windows here can be created before the + // incident database is populated. When there are updates to the db then + // we need to recreate these windows because they are not created dynamically + // like they are in the modal windows for android + Ti.App.addEventListener('categoriesDownloaded', function() { + // Create settings win/tab + var settingsWin = MarchHare.ui.createSettingsWindow(); + var settingsTab = Titanium.UI.createTab({ + title: 'Settings', + icon: '/img/KS_nav_views.png', + window: settingsWin + }); + tabGroup.addTab(settingsTab); + }); + + Ti.App.addEventListener('filterReports', function() { + tabGroup.removeTab(reportsTab); + reportsWin = MarchHare.ui.createReportsWindow(); + reportsTab = Titanium.UI.createTab({ + title: 'Reports', + icon: '/img/KS_nav_ui.png', + window: reportsWin + }); + tabGroup.addTab(reportsTab); + }); + + Ti.App.addEventListener('newIncidents', function() { + tabGroup.removeTab(reportsTab); + reportsWin = MarchHare.ui.createReportsWindow(); + reportsTab = Titanium.UI.createTab({ + title: 'Reports', + icon: '/img/KS_nav_ui.png', + window: reportsWin + }); + tabGroup.addTab(reportsTab); + }); } -*/ // Set the handler for whe the action midpoint is recieved // In testing this event does not get recieved until after the settings are // sent to the map view +// TODO: Does this create a memory leak? Ti.App.addEventListener('geolocationDownloaded', function() { updatedActionMidPoint(); }); @@ -67,12 +117,15 @@ Ti.App.addEventListener('geolocationDownloaded', function() { // TODO: test with these settings off if (DEV) { Ti.App.Properties.setString('lastpoll', '1970-01-01'); + MarchHare.database.flushCategories(); + MarchHare.database.flushIncidentCategories(); MarchHare.database.flushIncidents(); - MarchHare.database.flushIncidentCategories(); - MarchHare.database.flushCategories(); Ti.App.Properties.setInt('poll', MarchHare.settings.poll.default_value); } + +// Force a lookup of all categories everytime the application starts MarchHare.database.initializeCategories(); +MarchHare.database.initializeIncidents(); MarchHare.database.initializeMidPoint(); // TODO: in testing I have noticed that this completes before the MapWindow is @@ -91,7 +144,7 @@ Ti.App.addEventListener('readyForReports', function() { // recieve this event. Which means we have a race condition. The effects // of this should be investigated. Ti.App.addEventListener('actionDomainChanged', function() { - Ti.API.debug('actionDomainChanged event recieved, updating system'); + Ti.API.log('actionDomainChanged event recieved, updating system'); Ti.App.Properties.setString('lastpoll', '1970-01-01'); MarchHare.database.flushIncidents(); MarchHare.database.flushIncidentCategories(); @@ -103,9 +156,9 @@ Ti.App.addEventListener('actionDomainChanged', function() { var pollInterval; Ti.App.addEventListener('mapInitialized', function() { - Ti.API.debug('mapInitialized event recieved'); + Ti.API.log('mapInitialized event recieved'); Ti.App.Properties.setBool('map_initialized', true); - Ti.API.debug('polling for new reports every '+ + Ti.API.log('polling for new reports every '+ Ti.App.Properties.getInt('poll', MarchHare.settings.poll.default_value)*1000 + ' seconds'); pollInterval = setInterval(pollForReports, @@ -114,7 +167,7 @@ Ti.App.addEventListener('mapInitialized', function() { }); Ti.App.addEventListener('pollIntervalChanged', function() { - Ti.API.debug('pollIntervalChanged event recieved, updating poll interval'); + Ti.API.log('pollIntervalChanged event recieved, updating poll interval'); clearInterval(pollInterval); pollInterval = setInterval(pollForReports, Ti.App.Properties.getString('poll', MarchHare.settings.poll.default_value) @@ -137,14 +190,14 @@ if (Ti.App.Properties.getBool('gpsFollow', } Ti.App.addEventListener('gpsFollowChanged', function() { - Ti.API.debug('gpsFollowChanged ('+ + Ti.API.log('gpsFollowChanged ('+ Ti.App.Properties.getBool('gpsFollow', 'NOT SET')+ ') event recieved, updating location polling'); if (Ti.App.Properties.getBool('gpsFollow', MarchHare.settings.gpsFollow.default_value)) { Titanium.Geolocation.addEventListener('location', updateGeoLocationHandler); } else { - Ti.API.debug('gpsFollowChanged event recieved, clearing gps interval'); + Ti.API.log('gpsFollowChanged event recieved, clearing gps interval'); // This handles the privacy concern of a user turning off gpsFollow on // their device then getting their phone confiscated and the saved location @@ -159,7 +212,7 @@ Ti.App.addEventListener('gpsFollowChanged', function() { }); function updateGeoLocationHandler(location) { - Ti.API.debug('app.js::updateGeoLocationHandler() location: '+ + Ti.API.log('app.js::updateGeoLocationHandler() location: '+ JSON.stringify(location)); // Titanium.Geolocation.location: http://bit.ly/GG6qri @@ -188,7 +241,7 @@ function updateGeoLocation() { }); if( Titanium.Geolocation.locationServicesEnabled === false ) { - Ti.API.debug('app.js::updateGeoLocation() device has GPS turned off.'); + Ti.API.log('app.js::updateGeoLocation() device has GPS turned off.'); alert.message = 'Your device has GPS turned off. Please turn it on.'; alert.show(); setTimeout(function() { @@ -207,7 +260,7 @@ function updateGeoLocation() { return; } - Ti.API.debug('app.js::updateGeoLocation location: '+ + Ti.API.log('app.js::updateGeoLocation location: '+ JSON.stringify(location.coords)); // TODO: saving geo location on the device could be // a privacy concern. Can we get around this? For @@ -231,7 +284,7 @@ function pollForReports() { var url = 'http://'+ Ti.App.Properties.getString('action_domain', MarchHare.settings.action_domain.default_value)+ - '/api/?task=decayimage&by=sincedate&date='+lastpoll; + '/api/?task=decayimage&by=sincedate&limit=100&date='+lastpoll; // TODO: start an indicator var t = setInterval(function() { @@ -308,30 +361,30 @@ function handleServerResponse(response) { // if we already found a newIncident we dont have to keep checking if (!newIncidents) { - // Loop across the assigned categories to see if it is one we are i + // Loop across the assigned categories to see if it is one we are // interested in for (j in jNewIncidents.payload.incidents[i].categories) { - if (jNewIncidents.payload.incidents[i].categories[j].category.id in categories) { + if ( categories.indexOf(parseInt(jNewIncidents.payload.incidents[i].categories[j].category.id)) != -1) { newIncidents = true; - } + break; + } } } } } if (newIncidents || !initialized) { - Ti.API.debug('pollReports: firing updateReports event, map_initialized: '+ + Ti.API.log('pollReports: firing updateReports event, map_initialized: '+ initialized +', newIncidents: '+ newIncidents); updatedReportsAction(); } else { - Ti.API.debug('pollReports: not updating because we did not recieve any new reports'); + Ti.API.log('pollReports: not updating because we did not recieve any new reports'); } - // Create a notification if we recieved new incidents - if (newIncidents && Ti.App.Properties.getBool('vibrate', false)) { - Ti.API.debug('pollReports: triggering an alert'); - Titanium.Media.vibrate(); + // Let other interested parties do what they want with newIncidents + if (newIncidents) { + Ti.App.fireEvent('newIncidents'); } if (!error) { @@ -340,9 +393,21 @@ function handleServerResponse(response) { } Ti.App.addEventListener('filterReports', function() { + Ti.API.log('filterReports event recieved'); updatedReportsAction(); }); +Ti.App.addEventListener('newIncidents', function() { + notifyUser(); +}); + +function notifyUser() { + if (Ti.App.Properties.getBool('vibrate', false)) { + Ti.API.log('Vibrating the phone'); + Titanium.Media.vibrate(); + } +} + function updatedReportsAction() { result = MarchHare.database.getIncidentsJSON({}); diff --git a/Resources/img/KS_nav_map.png b/Resources/img/KS_nav_map.png new file mode 100644 index 0000000..959686f Binary files /dev/null and b/Resources/img/KS_nav_map.png differ diff --git a/Resources/img/KS_nav_ui.png b/Resources/img/KS_nav_ui.png new file mode 100644 index 0000000..28976c8 Binary files /dev/null and b/Resources/img/KS_nav_ui.png differ diff --git a/Resources/img/KS_nav_views.png b/Resources/img/KS_nav_views.png new file mode 100644 index 0000000..885abd9 Binary files /dev/null and b/Resources/img/KS_nav_views.png differ diff --git a/Resources/js/reports.js b/Resources/js/reports.js index f3dafed..e14de3b 100644 --- a/Resources/js/reports.js +++ b/Resources/js/reports.js @@ -79,13 +79,13 @@ (typeof(location.lat) === 'undefined') || (typeof(location.lon) === 'undefined') ) { - Ti.API.debug('handleUpdateGeolocation did not recieve location info'); + Ti.API.error('handleUpdateGeolocation did not recieve location info'); return; } // check to see if it is different then the values we already have if ( (latitude != location.lat) || (longitude != location.lon) ) { - Ti.API.debug('handleUpdateGeolocation updating the "Current Location" layer'); + Ti.API.info('handleUpdateGeolocation updating the "Current Location" layer'); var oldLayer = map.getLayersByName('Current Location'); for (var i = 0; i < oldLayer.length; i++) { diff --git a/Resources/march-hare/database.js b/Resources/march-hare/database.js index 656554a..c384b8a 100644 --- a/Resources/march-hare/database.js +++ b/Resources/march-hare/database.js @@ -15,7 +15,11 @@ db = Ti.Database.install('incidents.sqllite', 'incidents'); } */ - db = Ti.Database.install('incidents.sqlite', 'incidents'); + if (Ti.Platform.name === 'android') { + db = Ti.Database.install('incidents.sqlite', 'incidents'); + } else { + db = Ti.Database.install('march-hare/incidents.sqlite', 'incidents'); + } var databaseIndicator = Titanium.UI.createActivityIndicator({ height:50, width:10 }); @@ -124,14 +128,6 @@ // If you want to force an initilization of the categories just flush them // first with MarchHare.database.flushCategories() MarchHare.database.initializeCategories = function() { - // Unless we are forcing a category refresh check to see if we have any - // categories already. If so then return; - var query = 'SELECT count(*) as count from categories'; - var rows = db.execute(query); - if (rows.isValidRow() && rows.fieldByName('count') > 0) { - return; - } - var url = 'http://'+ Ti.App.Properties.getString('action_domain', MarchHare.settings.action_domain.default_value)+ @@ -556,11 +552,10 @@ } MarchHare.database.initializeIncidents = function() { - MarchHare.database.flushIncidents(); var url = 'http://'+ Ti.App.Properties.getString('action_domain', MarchHare.settings.action_domain.default_value)+ - '/api?task=decayimage'; + '/api?task=decayimage&limit=100'; // TODO: start an indicator var t = setInterval(function() { @@ -574,7 +569,7 @@ MarchHare.xhrProcess({ url: url, onload: function(response) { - handleServerResponse(response); + MarchHare.database.handleServerResponseIncidents(response); Ti.App.fireEvent('incidentsDownloaded'); } }); @@ -586,36 +581,66 @@ MarchHare.database.handleServerResponseIncidents = function(response) { var jNewIncidents = JSON.parse(response); var newIncidents = false; + var incidentids = []; + var error = false; if ( typeof jNewIncidents == 'undefined' || typeof jNewIncidents.payload == 'undefined' || typeof jNewIncidents.payload.incidents == 'undefined' || - !(jNewIncidents.payload.incidents instanceof Array) ){ - Ti.API.error('initializeIncidents: recieved invalid json from the server: '+ - JSON.stringify(jNewIncidents)); - return false; - } + !(jNewIncidents.payload.incidents instanceof Array) + ) { - for ( var i in jNewIncidents.payload.incidents) { - newIncidents = true; - var incident = { - incident: { - incidentid: jNewIncidents.payload.incidents[i].incident.incidentid, - incidenttitle: jNewIncidents.payload.incidents[i].incident.incidenttitle, - incidentdescription: jNewIncidents.payload.incidents[i].incident.incidentdescription, - incidentdate: jNewIncidents.payload.incidents[i].incident.incidentdate, - incidentlatitude: jNewIncidents.payload.incidents[i].incident.locationlatitude, - incidentlongitude: jNewIncidents.payload.incidents[i].incident.locationlongitude, - }, - categories: jNewIncidents.payload.incidents[i].categories - }; + // It may just be the case that we have not recieved any data back + // from our request + if ( + typeof jNewIncidents.error.code != 'undefined' && + (jNewIncidents.error.code == "007") && + typeof jNewIncidents.error.message != 'undefined' + ) { + } + else { + Ti.API.error('MarchHare.database.handleServerResponseIncidents: recieved invalid json from the server: '+ + JSON.stringify(jNewIncidents)); + error = true; + } + } else { - MarchHare.database.setIncident(incident); + // TODO: this finishes before the settings are sent to the map, so it does + // not actually load until after the next poll + for ( var i in jNewIncidents.payload.incidents) { + incidentids.push(parseInt(jNewIncidents.payload.incidents[i].incident.incidentid)); + var incident = { + incident: { + incidentid: jNewIncidents.payload.incidents[i].incident.incidentid, + incidenttitle: jNewIncidents.payload.incidents[i].incident.incidenttitle, + incidentdescription: jNewIncidents.payload.incidents[i].incident.incidentdescription, + incidentdate: jNewIncidents.payload.incidents[i].incident.incidentdate, + incidentlatitude: jNewIncidents.payload.incidents[i].incident.locationlatitude, + incidentlongitude: jNewIncidents.payload.incidents[i].incident.locationlongitude, + incidenthasended: jNewIncidents.payload.incidents[i].incident.incidenthasended, + }, + categories: jNewIncidents.payload.incidents[i].categories + }; + + if (MarchHare.database.getIncidentJSON(incident)) { + MarchHare.database.updateIncident(incident); + } else { + MarchHare.database.setIncident(incident); + } + } } - if (!newIncidents) { - Ti.API.debug('nitializeIncidents: did not recieve any reports'); + // Delete all old incidents + var rows = MarchHare.database.getIncidents(); + while (rows.isValidRow()) { + var id = rows.fieldByName('id'); + rows.next(); + if (incidentids.indexOf(id) != -1) { continue; } + var query = 'DELETE FROM incident_categories WHERE incident_id='+id; + db.execute(query); + query = 'DELETE FROM incidents WHERE id='+id; + db.execute(query); } } diff --git a/Resources/march-hare/march-hare.js b/Resources/march-hare/march-hare.js index 1cec7e1..8ae4a58 100644 --- a/Resources/march-hare/march-hare.js +++ b/Resources/march-hare/march-hare.js @@ -1,6 +1,8 @@ // TODO: i18n inegration var MarchHare = { - ui: {}, + ui: { + Android: (Ti.Platform.osname == 'android') ? true : false, + }, database: {}, xhr: Ti.Network.createHTTPClient(), xhrGetSemaphore: function(message) { @@ -37,25 +39,28 @@ var MarchHare = { MarchHare.xhrReleaseSemaphore(); }); - MarchHare.xhr.setOnload(function() { - if (typeof parameters.file != 'undefined') { - var f = Titanium.Filesystem.getFile( - Titanium.Filesystem.applicationDataDirectory, - parameters.file); + // We use setOnreadystatechange instead of onLoad cause it does not fire + // sometimes: http://bit.ly/bArcbC + MarchHare.xhr.setOnreadystatechange(function() { + if (MarchHare.xhr.readyState != 4) { return; } + if (typeof parameters.file != 'undefined') { + var f = Titanium.Filesystem.getFile( + Titanium.Filesystem.applicationDataDirectory, + parameters.file); - if (Titanium.Platform.name == 'android') { - f.write(this.responseData); - } + if (Titanium.Platform.name == 'android') { + f.write(this.responseData); + } - // If we are downloading a file we will not recieve responseText so - // instead we will pass on the url of the download and the local file - // where it is saved - parameters.onload({file: f.resolve(), url: parameters.url}); - } else { - parameters.onload(this.responseText); - } - MarchHare.xhrReleaseSemaphore(); - }); + // If we are downloading a file we will not recieve responseText so + // instead we will pass on the url of the download and the local file + // where it is saved + parameters.onload({file: f.resolve(), url: parameters.url}); + } else { + parameters.onload(this.responseText); + } + MarchHare.xhrReleaseSemaphore(); + }); if (Titanium.Platform.name != 'android' && (typeof parameters.file != 'undefined')) { diff --git a/Resources/windows/Map.js b/Resources/windows/Map.js index adc6028..c8ad8c5 100644 --- a/Resources/windows/Map.js +++ b/Resources/windows/Map.js @@ -1,9 +1,16 @@ (function () { MarchHare.ui.createMapView = function() { + var url; + if (Ti.Platform.name === 'android') { + url = '../pages/map.html'; + } else { + url = 'pages/map.html'; + } + var webview = Ti.UI.createWebView({ - url: '../pages/map.html', - touchEnabled: true - }); + url: url, + touchEnabled: true + }); // TODO: The gestures below need to be supported // https://wiki.appcelerator.org/display/guides/Supporting+Gestures @@ -25,7 +32,7 @@ settings.zoom = Ti.App.Properties.getInt('zoom', MarchHare.settings.zoom.default_value); settings.action_domain = Ti.App.Properties.getString('action_domain', MarchHare.settings.action_domain.default_value); settings.poll = Ti.App.Properties.getString('poll', MarchHare.settings.poll.default_value); - Ti.API.debug('load event for mapview caught, sending settings'); + Ti.API.log('load event for mapview caught, sending settings'); Ti.App.fireEvent('mapWindowLoaded', settings); }); @@ -34,7 +41,7 @@ MarchHare.ui.createMapWindow = function() { var win = Ti.UI.createWindow({ - title: 'In the streets', + title: 'Map', exitOnClose: true, }); diff --git a/Resources/windows/Reports.js b/Resources/windows/Reports.js index 097b0ca..d1c5fdd 100644 --- a/Resources/windows/Reports.js +++ b/Resources/windows/Reports.js @@ -1,3 +1,8 @@ +/* + - Applying filters to the reports listing is not working + +*/ + (function () { MarchHare.ui.createReportsView = function() { var data = []; @@ -8,8 +13,11 @@ for (i in incidents) { data[i] = Ti.UI.createTableViewRow({ hasChild: true, - height: 'auto', - description: incidents[i].incident.incidentdescription, + height: 50, + top: 0, + // title is a keyword that we dont want to use here + tit: incidents[i].incident.incidenttitle, + desc: incidents[i].incident.incidentdescription, lat: incidents[i].incident.locationlatitude, lon: incidents[i].incident.locationlongitude, date: incidents[i].incident.incidentdate, @@ -18,21 +26,92 @@ ended: incidents[i].incident, backgroundColor: ((incidents[i].incident.incidentread) ? '#000000' : '#404040') }); + data[i].addEventListener('click', function(e) { e.rowData.backgroundColor = '#000000'; + MarchHare.database.setIncidentRead(e.rowData.id, true); + var infowin = Titanium.UI.createWindow({ + title: e.rowData.title, + backgroundColor: '#000' + }); + var scrollview = Ti.UI.createScrollView({ layout: 'vertical' }); + //var view = Ti.UI.createView({ layout:'vertical', }); + + e.row.backgroundColor = '#000000'; + + // TODO: add the location name + //view.add( + //infowin.add( + scrollview.add( + Ti.UI.createLabel({ + text: 'Title: '+e.rowData.tit, + color: '#FFF', /*top: 20,*/ height: 'auto', + left: 0, + })); + + scrollview.add( + Ti.UI.createLabel({ + text: 'Reported at: '+e.rowData.date, + color: '#FFF', /*top: 30,*/ height: 'auto', + left: 0, + })); + + // From: http://bit.ly/GMVY7v + //infowin.add( + scrollview.add( + Ti.UI.createLabel({ + text: e.rowData.desc, + color: '#FFF', /*top: 70,*/ height: 'auto', + left: 0, + })); + + var closeButton = Ti.UI.createButton({ + title: 'close', height: 30, bottom: 10 + }); + + closeButton.addEventListener('click', function() { + infowin.close(); + }); + scrollview.add(closeButton); + + //infowin.add(view); + infowin.add(scrollview); + //infowin.add( closeButton ); + infowin.open({ modal: true }); }); + // It does not seem like android will fire longpresses, but I am not + // sure that iOS doesn't fire both + if (MarchHare.ui.Android) { + data[i].addEventListener('longclick', fireGotoLocation); + } else { + data[i].addEventListener('longpress', fireGotoLocation); + } + + function fireGotoLocation(e) { + Ti.API.log('longpress or longclick detected gotoLocation being fired'); + Ti.App.fireEvent('gotoLocation', { + lat: e.rowData.lat, + lon: e.rowData.lon + }); + } + + // TODO: we should move all formatting stuff like this to jss files + var top = -2; + if (!MarchHare.ui.Android) { + top = -30; + } data[i].add(Ti.UI.createLabel({ text: incidents[i].incident.incidenttitle, - left:0 + top: top, left:0, color: '#FFF' })); // TODO: It's possible that there are empty strings in incidents[i].icon // this is probably a bug in MarchHare.database.getIncidentsJSON or else // where that needs to get fixed. - var filere = /^file:\/\/\//; - var file; + var filere = /^file:\/\/\/|^\//; for (j in incidents[i].icon) { + var file; if (!incidents[i].icon[j].length) { continue; } // If it is a file make sure it exists @@ -46,75 +125,47 @@ // web urls as arguments for backgroundImage :( continue; } - data[i].add(Titanium.UI.createImageView({ - backgroundImage: incidents[i].icon[j], - top: 40, width: 16, height: 16, left: 20*j + image: file, + top: 30, width: 16, height: 16, left: 20*j })); } - //break; } if (!incidents.length) { data.push( Ti.UI.createTableViewRow({title: 'No reports have been added'})); } + tableView = Titanium.UI.createTableView({data: data}); return tableView; } MarchHare.ui.createReportsWindow = function() { + // We do not use modal windows on iOS + var useModal = (Ti.Platform.osname == 'android') ? true : false; var win = Ti.UI.createWindow({ backgroundColor: '#000', title: 'Reports', - modal: true + modal: useModal }); - var view = MarchHare.ui.createReportsView(); - view.addEventListener('click', function(e) { - var infowin = Titanium.UI.createWindow({ - modal:true, - title:e.rowData.title - }); - var view = Ti.UI.createView({ - layout:'vertical', - backgroundColor: 'black', - color: 'white' - }); - - MarchHare.database.setIncidentRead(e.rowData.id, true); - e.row.backgroundColor = '#000000'; - // TODO: add the location name - view.add( - Ti.UI.createLabel({ - text: 'Reported at: '+e.rowData.date, - left: 0 - })); - - // From: http://bit.ly/GMVY7v - view.add( - Ti.UI.createLabel({ - text: e.rowData.description, - left: 0 - })); + var view = MarchHare.ui.createReportsView(); - infowin.add(view); - infowin.open(); + // On Android we close the window, iOS we switch tabs + Ti.App.addEventListener('gotoLocation', function(e){ + if (MarchHare.ui.Android) { + win.close(); + } else { + tabGroup.setActiveTab(mapTab); + } }); - view.addEventListener('longclick', function(e) { - // close this window and center the map on the clicked incident - Ti.App.fireEvent('gotoLocation', { - lat: e.rowData.lat, - lon: e.rowData.lon - }); - win.close(); - }); - win.add(view); - return win; + win.add(view); + return win; } - Ti.API.debug('Reports.js loaded'); + Ti.API.log('Reports.js loaded'); })(); diff --git a/Resources/windows/Settings.js b/Resources/windows/Settings.js index d256048..96acbb5 100644 --- a/Resources/windows/Settings.js +++ b/Resources/windows/Settings.js @@ -3,12 +3,14 @@ // seem to be a way to create dynamic preference lists // // The example used to create this was pulled from: http://bit.ly/KbLUA7 - + + // We do not use modal windows on iOS + var useModal = (Ti.Platform.osname == 'android') ? true : false; MarchHare.ui.createSettingsWindow = function() { var win = Ti.UI.createWindow({ - backgroundColor: '#000', + //backgroundColor: '#000', title: 'Settings', - modal: true + modal: useModal }); var sections = new Array; @@ -17,14 +19,15 @@ headerTitle: "Application Settings" }); - var domainRow = Ti.UI.createTableViewRow(); + var domainRow = Ti.UI.createTableViewRow({ height: 50 }); // TODO: this should actually all be wrapped in a table with each setting // that is not a checkbox diverted to its own modal window var domainLabel = Ti.UI.createLabel({ text: 'Action Domain: ', top: 0, left: 0, - color: '#fff' }); + //color: '#fff' + }); domainRow.add(domainLabel); @@ -32,8 +35,7 @@ // want to use. We will have to change this dependent on a new property // in the MarchHare.settings list var domainField = Ti.UI.createTextField( { - //top:20, left:0, width: 200, - left:0, width: 200, top: 20, + left:0, width: 200, top: 30, hintText: Ti.App.Properties.getString('action_domain', MarchHare.settings.action_domain.default_value), autoCorrect: false, @@ -74,7 +76,8 @@ var pollLabel = Ti.UI.createLabel({ text: 'Poll Frequency in Seconds:', top: 10, left: 0, - color: '#fff' }); + //color: '#fff' + }); pollRow.add(pollLabel); var pollField = Ti.UI.createTextField( { @@ -112,12 +115,13 @@ var GPSLabel = Ti.UI.createLabel({ text: 'Update map w/ GPS: ', top: 0, left: 0, - color: '#fff' }); + //color: '#fff' + }); GPSRow.add(GPSLabel); var GPSField = Ti.UI.createSwitch( { top: 5, right: 10, - style:Ti.UI.Android.SWITCH_STYLE_CHECKBOX, + style: (Titanium.Platform.osname == 'android') && Ti.UI.Android.SWITCH_STYLE_CHECKBOX, value: Ti.App.Properties.getBool('gpsFollow', MarchHare.settings.gpsFollow.default_value) }); @@ -144,12 +148,13 @@ var VibLabel = Ti.UI.createLabel({ text: 'Vibrate on new report: ', top: 0, left: 0, - color: '#fff' }); + //color: '#fff' + }); VibRow.add(VibLabel); var VibField = Ti.UI.createSwitch( { top: 5, right: 10, - style:Ti.UI.Android.SWITCH_STYLE_CHECKBOX, + style: (Titanium.Platform.osname == 'android') && Ti.UI.Android.SWITCH_STYLE_CHECKBOX, value: Ti.App.Properties.getBool('vibrate', false) }); @@ -174,6 +179,7 @@ }); // Get all of the categories + var categoryFiltersUpdated = false; var categories = MarchHare.database.getCategoriesJSON(); categories = JSON.parse(categories); for (i in categories) { @@ -189,12 +195,13 @@ var categoryLabel = Ti.UI.createLabel({ text: categories[i].title+': ', top: 0, left: 0, - color: '#fff' }); + //color: '#fff' + }); categoryRow.add(categoryLabel); var categorySwitch = Ti.UI.createSwitch({ top: 5, right: 10, - style:Ti.UI.Android.SWITCH_STYLE_CHECKBOX, + style: (Titanium.Platform.osname == 'android') && Ti.UI.Android.SWITCH_STYLE_CHECKBOX, category_id: categories[i].id, value: categories[i].filter ? true : false }); @@ -206,6 +213,7 @@ categorySwitch. addEventListener("change", function(e) { MarchHare.database.setCategoryFilter(e.source.category_id, e.value); + categoryFiltersUpdated = true; }); categoryRow.add(categorySwitch); @@ -219,12 +227,23 @@ win.add(tableView); + // With Android modal windows we close the settings window, but with iOS we blur the window win.addEventListener('close', function() { - Ti.App.fireEvent('filterReports'); + if (categoryFiltersUpdated) { + categoryFiltersUpdated = false; + Ti.App.fireEvent('filterReports'); + } + }); + + win.addEventListener('blur', function() { + if (categoryFiltersUpdated) { + categoryFiltersUpdated = false; + Ti.App.fireEvent('filterReports'); + } }); return win; } - Ti.API.debug('Settings.js loaded'); + Ti.API.log('Settings.js loaded'); })(); diff --git a/tiapp.xml b/tiapp.xml index 6ccfd83..09e8652 100644 --- a/tiapp.xml +++ b/tiapp.xml @@ -3,7 +3,7 @@ v8 false - false + true false true false