1//////////////////////////////////////////////////////////////////////////////// 2// MDPublication App 3//////////////////////////////////////////////////////////////////////////////// 4 5function MDPublicationApp() { 6 this.tag="mdpublication"; 7 this.title="MDPublication"; 8} 9 10MDPublicationApp.prototype=new App("mdpublication", "MDPublication"); 11MDPublicationApp.prototype.constructor=MDPublicationApp; 12 13//////////////////////////////////////////////////////////////////////////////// 14// App Lifecycle 15 16MDPublicationApp.prototype.initialize=function() { 17 var localApp=this; 18 19 //App 20 this.publicationFeedList=new Array(); 21 this.articles=new Array(); 22 this.articlesBySource=new Array(); 23 this.articlesBySourceTags=new Array(); 24 this.articlesLoading=false; 25 this.sources=new Array(); 26 this.hiddenSources=new Array(); 27 this.selectedSource=""; 28 29 this.navigationController=new NavigationController("mdpublication", "MDPublication", "menu_mdpublication_2x.png"); 30 this.mainViewController=createViewController(this, "main", "MDPublication"); 31 this.navigationController.setRootController(this.mainViewController); 32 33 this.mainSourcesButton=$("#app_mdpublication_viewController_main_button_sources"); 34 this.mainSourcesButton.on("click", function(e) { localApp.navigationController.pushViewController(localApp.sourcesViewController); }); 35 36 this.mainRefreshButton=$("#app_mdpublication_viewController_main_button_refresh"); 37 this.mainRefreshButton.on("click", function(e) { localApp.loadArticles(); }); 38 39 this.mainMainArea=$("#app_mdpublication_viewController_main_mainArea"); 40 this.mainToolBar=$("#app_mdpublication_viewController_main_toolBar"); 41 42 this.articlesViewController=createViewController(this, "articles", "MDPublication"); 43 this.articlesListView=createListView(this, "articles", this.mainViewController); 44 this.articlesSearchField=$('#app_mdpublication_listView_articles_searchField'); 45 this.articlesSearchField.change(function(){ localApp.articlesListView.search(); }); 46 this.articlesSearchField.keyup(function(){ localApp.articlesListView.search(); }); 47 this.articlesSearchField.bind('click', function(event){ localApp.articlesListView.search(); }); 48 49 this.articlesWebButton=$("#app_mdpublication_viewController_articles_button_web"); 50 this.articlesWebButton.on("click", function(e) { window.open(localApp.articlesBySource[localApp.selectedSource][0].sourceWebsite); }); 51 52 this.articlesToolBar=$("#app_mdpublication_viewController_articles_toolBar"); 53 54 this.sourcesViewController=createViewController(this, "sources", "Sources"); 55 this.sourcesListView=createListView(this, "sources", this.sourcesViewController); 56 57 this.sourcesToolBar=$("#app_mdpublication_viewController_sources_toolBar"); 58 59 //Initialization complete - return localApp 60 return localApp; 61} 62 63MDPublicationApp.prototype.launch=function() { 64 var localApp=this; 65 66 this.publicationFeedList=new Array(); 67 this.articles=new Array(); 68 this.articlesBySource=new Array(); 69 this.articlesBySourceTags=new Array(); 70 this.articlesLoading=false; 71 this.sources=new Array(); 72 var implodedHiddenSources=localApp.getAppSetting("hiddenSources"); 73 if(implodedHiddenSources && implodedHiddenSources!="") { 74 localApp.hiddenSources=implodedHiddenSources.split(","); 75 } else { 76 localApp.hiddenSources=[]; 77 } 78 this.selectedSource=""; 79 80 localApp.listPublicationFeeds(0); 81} 82 83MDPublicationApp.prototype.quit=function() { 84 var localApp=this; 85 86 this.publicationFeedList=new Array(); 87 this.articles=new Array(); 88 this.articlesBySource=new Array(); 89 this.articlesBySourceTags=new Array(); 90 this.articlesLoading=false; 91 this.sources=new Array(); 92 this.hiddenSources=new Array(); 93 this.selectedSource=""; 94 95 localApp.mainToolBar.html(""); 96 localApp.sourcesToolBar.html(""); 97 localApp.articlesToolBar.html(""); 98} 99 100MDPublicationApp.prototype.receiveNotification=function(tag, message) { 101 var localApp=this; 102 103 switch(tag) { 104 case "googleAPILoaded": 105 localApp.loadArticles(); 106 break; 107 } 108} 109 110//////////////////////////////////////////////////////////////////////////////// 111// ListView Delegate Methods 112 113MDPublicationApp.prototype.sectionsForList=function(listView) { 114 var localApp=this; 115 switch(listView.tag) { 116 case "articles": 117 return 0; 118 break; 119 case "sources": 120 return 0; 121 break; 122 default: 123 return 0; 124 break; 125 } 126} 127 128MDPublicationApp.prototype.rowsForSection=function(listView, section) { 129 var localApp=this; 130 switch(listView.tag) { 131 case "articles": 132 return localApp.articlesBySource[localApp.selectedSource].length; 133 break; 134 case "sources": 135 return localApp.sources.length; 136 break; 137 default: 138 return 0; 139 break; 140 } 141} 142 143MDPublicationApp.prototype.titleForSection=function(listView, section) { 144 var localApp=this; 145 switch(listView.tag) { 146 default: 147 return ""; 148 break; 149 } 150} 151 152MDPublicationApp.prototype.accessoryForSection=function(listView, section) { 153 switch(listView.tag) { 154 } 155} 156 157MDPublicationApp.prototype.listViewCellForRow=function(listView, row, section) { 158 var localApp=this; 159 var mListViewCell; 160 mListViewCell=new ListViewCell(); 161 var correctedSectionRow=listView.rowCorrectedForSection(row, section); 162 163 switch(listView.tag) { 164 case "articles": 165 var articleItem=localApp.articlesBySource[localApp.selectedSource][row]; 166 var pubDate=new Date(articleItem.publishedDate); 167
168 var currentDateObject=new Date(); 169 var yesterdayDateObject=new Date(); 170 yesterdayDateObject.setDate(currentDateObject.getDate()-1); 171 172 var dateLabel; 173 174 if(mSystem.dateToSQLDate(currentDateObject)==mSystem.dateToSQLDate(pubDate)) { 175 dateLabel=mSystem.dateToShortTime(pubDate); 176 } else if(mSystem.dateToSQLDate(yesterdayDateObject)==mSystem.dateToSQLDate(pubDate)) { 177 dateLabel="Yesterday"; 178 } else { 179 dateLabel=mSystem.dateToSQLDate(pubDate); 180 } 181 182 var sourceBadge; 183 if(articleItem.sourceTag!="") sourceBadge="<div class=\"sourceBadge\" style=\"background-color:"+articleItem.sourceColour+";\">"+articleItem.sourceTitle+"</div>"; 184 else sourceBadge=""; 185 186 // mListViewCell.title="<div class=\"mainTitle\" style=\"float:left;width:500px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;\">"+sourceBadge+articleItem.title+"</div><div class=\"smallDetail\" style=\"float:right;width:100px;text-align:right;\">"+dateLabel+"</div><div style=\"clear:both;\"></div>"; 187 // mListViewCell.details=articleItem.content; 188 mListViewCell.title="<div class=\"mainTitle\" style=\"float:left;width:500px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;\">"+articleItem.title+"</div><div style=\"float:right;width:100px;text-align:right;\">"+sourceBadge+"</div><div style=\"clear:both;\"></div>"; 189 mListViewCell.details="<div style=\"float:left;width:500px;\">"+articleItem.content+"</div><div class=\"smallDetail\" style=\"float:right;width:100px;text-align:right;font-size:12px;\">"+dateLabel+"</div><div style=\"clear:both;\"></div>"; 190 break; 191 case "sources": 192 var sourceItem=localApp.sources[row]; 193 194 var sourceBadge; 195 sourceBadge="<div class=\"sourceBadge\" style=\"background-color:"+sourceItem.colour+";\">"+sourceItem.title+"</div> "+sourceItem.longTitle; 196 197 var sourceChecked=""; 198 if(localApp.hiddenSources.indexOf(sourceItem.tag)==-1) sourceChecked="checked"; 199 200 mListViewCell.title="<input id=\"app_mdpublication_source_"+sourceItem.tag+"\" type=\"checkbox\" "+sourceChecked+" /> "+sourceBadge; 201 mListViewCell.details=""; 202 break; 203 } 204 return mListViewCell; 205} 206 207MDPublicationApp.prototype.listViewRowSelected=function(listView, row, section) { 208 var localApp=this; 209 var correctedSectionRow=listView.rowCorrectedForSection(row, section); 210 switch(listView.tag) { 211 case "articles": 212 window.open(localApp.articlesBySource[localApp.selectedSource][row].link); 213 break; 214 case "sources": 215 break; 216 } 217} 218 219MDPublicationApp.prototype.listViewSectionSelected=function(listView, section) { 220 var localApp=this; 221 switch(listView.tag) { 222 case "articles": 223 break; 224 case "sources": 225 break; 226 } 227} 228 229MDPublicationApp.prototype.listViewWillRefresh=function(listView) { 230 var localApp=this; 231 switch(listView.tag) { 232 case "main": 233 break; 234 } 235} 236 237MDPublicationApp.prototype.listViewRefreshed=function(listView) { 238 var localApp=this; 239 switch(listView.tag) { 240 case "articles": 241 if(listView.rows.length==1) localApp.articlesToolBar.html(listView.rows.length+" article"); 242 else localApp.articlesToolBar.html(listView.rows.length+" articles"); 243 break; 244 case "sources": 245 var sourceCheckbox; 246 for(var i=0;i<localApp.sources.length;i++) { 247 sourceCheckbox=$("#app_mdpublication_source_"+localApp.sources[i].tag); 248 sourceCheckbox.change(function(){ 249 localApp.updateHiddenSources(); 250 }); 251 } 252 if(listView.rows.length==1) localApp.sourcesToolBar.html(listView.rows.length+" source"); 253 else localApp.sourcesToolBar.html(listView.rows.length+" sources"); 254 break; 255 } 256} 257 258MDPublicationApp.prototype.listViewCellSearchCheck=function(listView, searchTerms, row, section) { 259 var localApp=this; 260 var found; 261 switch(listView.tag) { 262 case "articles": 263 var found; 264 var articleItem=localApp.articlesBySource[localApp.selectedSource][row]; 265 for(i=0;i<listView.searchArray.length;i++) { 266 found=false; 267 if(articleItem.sourceTitle.toLowerCase().indexOf(listView.searchArray[i].toLowerCase())>-1) found=true; 268 if(articleItem.title.toLowerCase().indexOf(listView.searchArray[i].toLowerCase())>-1) found=true; 269 if(articleItem.content.toLowerCase().indexOf(listView.searchArray[i].toLowerCase())>-1) found=true; 270 if(!found) return false;
271 } 272 return true; 273 break; 274 default: 275 return true; 276 break; 277 } 278} 279 280//////////////////////////////////////////////////////////////////////////////// 281// ViewController Delegate Methods 282 283MDPublicationApp.prototype.viewControllerWasShown=function(viewController, parameters) { 284 var localApp=this; 285 286 switch(viewController.tag) { 287 case "main": 288 mSystem.setPathAndTitle("mdpublication", "MDPublication"); 289 break; 290 case "articles": 291 mSystem.setPathAndTitle("mdpublication/"+localApp.articlesBySource[localApp.selectedSource][0].sourceTag, "MDPublication - "+localApp.articlesBySource[localApp.selectedSource][0].sourceLongTitle); 292 viewController.navigationBar.setTitle(localApp.articlesBySource[localApp.selectedSource][0].sourceLongTitle); 293 localApp.articlesListView.refresh(); 294 break; 295 case "sources": 296 localApp.sourcesListView.refresh(); 297 break; 298 } 299} 300 301MDPublicationApp.prototype.viewControllerWasHidden=function(viewController) { 302 var localApp=this; 303 304 switch(viewController.tag) { 305 case "main": 306 break; 307 case "articles": 308 mSystem.setPathAndTitle("mdpublication", "MDPublication"); 309 localApp.selectedSource=""; 310 break; 311 case "sources": 312 localApp.syncAppSettings(); 313 localApp.loadArticles(); 314 break; 315 } 316} 317 318//////////////////////////////////////////////////////////////////////////////// 319// NotificationController Delegate Methods 320 321MDPublicationApp.prototype.notificationSelected=function(notification) { 322 var localApp=this; 323 324 mSystem.menuController.setSelectionWithTag("mdpublication"); 325 localApp.selectedSource=localApp.articlesBySourceTags[notification.tag]; 326 localApp.navigationController.pushViewController(localApp.articlesViewController); 327} 328 329//////////////////////////////////////////////////////////////////////////////// 330// App Methods 331 332MDPublicationApp.prototype.isSourceHidden=function(tag) { 333 var localApp=this; 334 335 var index=localApp.hiddenSources.indexOf(tag); 336 if(index>-1) return true; 337 else return false; 338} 339 340MDPublicationApp.prototype.updateHiddenSources=function() { 341 var localApp=this; 342 343 var sourceCheckbox; 344 for(var i=0;i<localApp.sources.length;i++) { 345 sourceCheckbox=$("#app_mdpublication_source_"+localApp.sources[i].tag); 346 347 if(sourceCheckbox.is(':checked')) { 348 var index=localApp.hiddenSources.indexOf(localApp.sources[i].tag); 349 if(index>-1) { 350 localApp.hiddenSources.splice(index, 1); 351 } 352 } else { 353 localApp.hiddenSources.push(localApp.sources[i].tag); 354 } 355 } 356 localApp.hiddenSources=localApp.hiddenSources.getUnique(); 357 localApp.setAppSetting("hiddenSources", localApp.hiddenSources.join(",")); 358} 359 360MDPublicationApp.prototype.rebuildMainArea=function() { 361 var localApp=this; 362 363 localApp.mainMainArea.empty(); 364 var sourceArticles; 365 var articleDate; 366 var newPublication; 367 for(var i=0;i<localApp.articlesBySourceTags.length;i++) { 368 sourceArticles=localApp.articlesBySource[localApp.articlesBySourceTags[i]]; 369 articleDate=new Date(sourceArticles[0].publishedDate); 370 localApp.mainMainArea.append("<div id=\"app_mdpublication_journal_"+sourceArticles[0].sourceTag+"\" class=\"app_mdpublication_journal\" style=\"background-color:"+sourceArticles[0].sourceColour+"\"><div class=\"title\">"+sourceArticles[0].sourceLongTitle+"</div><div class=\"date\">"+mSystem.getMonthName(articleDate)+" "+articleDate.getFullYear()+"</div></div>"); 371 newPublication=$("#app_mdpublication_journal_"+sourceArticles[0].sourceTag); 372 newPublication.data("sourceTag", sourceArticles[0].sourceTag); 373 newPublication.on("click", function(e) { 374 localApp.selectedSource=$(this).data("sourceTag"); 375 localApp.navigationController.pushViewController(localApp.articlesViewController); 376 }); 377 } 378 localApp.mainMainArea.append("<div style=\"height:32px;clear:both;\"></div>"); 379 380 if(localApp.articlesBySourceTags.length==1) localApp.mainToolBar.html(localApp.articlesBySourceTags.length+" publication"); 381 else localApp.mainToolBar.html(localApp.articlesBySourceTags.length+" publications"); 382} 383 384MDPublicationApp.prototype.loadArticles=function() { 385 var localApp=this; 386 387 if(mSystem.googleAPILoaded) { 388 if(localApp.publicationFeedList.length>0 && !localApp.articlesLoading) { 389 localApp.articlesLoading=true; 390 localApp.articles=new Array(); 391 localApp.articlesBySource=new Array(); 392 localApp.articlesBySourceTags=new Array(); 393 localApp.sources=new Array(); 394 var i; 395 var j; 396 var sourceFound; 397 var newSource; 398 var sourcesRequested=false; 399 for(i=0;i<localApp.publicationFeedList.length;i++) { 400 //Add to sources if not already there 401 sourceFound=false; 402 for(j=0;j<localApp.sources.length;j++) { 403 if(localApp.sources[j].tag==localApp.publicationFeedList[i].tag) { 404 sourceFound=true; 405 break; 406 } 407 } 408 if(!sourceFound) { 409 //Add source 410 newSource=new Array(); 411 newSource.tag=localApp.publicationFeedList[i].tag; 412 newSource.title=localApp.publicationFeedList[i].title; 413 newSource.longTitle=localApp.publicationFeedList[i].longtitle; 414 newSource.colour=localApp.publicationFeedList[i].colour; 415 newSource.website=localApp.publicationFeedList[i].website; 416 localApp.sources.push(newSource); 417 } 418 //Get Feed 419 if(localApp.isSourceHidden(localApp.publicationFeedList[i].tag)) { 420 localApp.publicationFeedList[i].received=true; 421 } else { 422 sourcesRequested=true; //At least one source was requested 423 localApp.publicationFeedList[i].received=false; 424 var feed=new google.feeds.Feed(localApp.publicationFeedList[i].url); 425 feed.setNumEntries(50); 426 //feed.includeHistoricalEntries(); 427 feed.setResultFormat(google.feeds.Feed.JSON_FORMAT); 428 var feedError=false; 429 feed.load(function(result) { 430 var newsFeed; 431 var content; 432 if (!result.error) { 433 newsFeed=null; 434 for(j=0;j<localApp.publicationFeedList.length;j++) { 435 if(localApp.publicationFeedList[j].url==result.feed.feedUrl) { 436 localApp.publicationFeedList[j].received=true; 437 newsFeed=localApp.publicationFeedList[j]; 438 break; 439 } 440 } 441 for(j=0;j<result.feed.entries.length;j++) { 442 //Purge undefined 443 if(result.feed.entries[j].title!==undefined) { 444 //Clean results 445 result.feed.entries[j].title=result.feed.entries[j].title.replaceAll("--", "—"); 446 if(result.feed.entries[j].title.indexOf("] ")>-1) result.feed.entries[j].title=result.feed.entries[j].title.split("] ")[1]; 447 if(result.feed.entries[j].title.indexOf(" [")>-1) result.feed.entries[j].title=result.feed.entries[j].title.split(" [")[0]; 448 content=result.feed.entries[j].content.replaceAll("Backgroun
448dâ", "").replaceAll("(Reuters) - ", "").replaceAll("(Reuters Health) - ", "").replaceAll("--", "—").replace(/(<([^>]+)>)/ig,"").split("<br>")[0]; 449 if(content.length>=200) { 450 content=$.trim(content.substring(0,200)); 451 if(content.substring(content.length-1)!=".") content=content+"..."; 452 } 453 content=content.split("Source:")[0]; 454 content=content.split("Page:")[0]; 455 result.feed.entries[j].content=$.trim(content); 456 if(result.feed.entries[j].content=="") result.feed.entries[j].content="No summary available."; 457 if(newsFeed!=null) { 458 result.feed.entries[j].sourceTag=newsFeed.tag; 459 result.feed.entries[j].sourceTitle=newsFeed.title; 460 result.feed.entries[j].sourceLongTitle=newsFeed.longtitle; 461 result.feed.entries[j].sourceColour=newsFeed.colour; 462 result.feed.entries[j].sourceWebsite=newsFeed.website; 463 } else { 464 result.feed.entries[j].sourceTag=""; 465 result.feed.entries[j].sourceTitle=""; 466 result.feed.entries[j].sourceLongTitle=""; 467 result.feed.entries[j].sourceColour=""; 468 result.feed.entries[j].sourceWebsite=""; 469 } 470 result.feed.entries[j].publishedDate=mSystem.sqlDateTimeToDate(result.feed.entries[j].publishedDate); 471 } else { 472 result.feed.entries.splice(j, 1); 473 j--; 474 } 475 } 476 localApp.articles=localApp.articles.concat(result.feed.entries); 477 } else { 478 feedError=true; 479 } 480 var allReceived=true; 481 for(j=0;j<localApp.publicationFeedList.length;j++) { 482 if(localApp.publicationFeedList[j].received==false) { 483 allReceived=false; 484 break; 485 } 486 } 487 if(allReceived || feedError) { 488 //Sort articles 489 function comparePublishedDate(a, b) { 490 var pubDateValue1=Date.parse(a.publishedDate); 491 var pubDateValue2=Date.parse(b.publishedDate); 492 return pubDateValue1-pubDateValue2; 493 } 494 localApp.articles.sort(comparePublishedDate).reverse(); 495 //Seperate them by source 496 for(j=0;j<localApp.articles.length;j++) { 497 if(typeof localApp.articlesBySource[localApp.articles[j].sourceTag]==="undefined") { 498 localApp.articlesBySource[localApp.articles[j].sourceTag]=new Array(); 499 localApp.articlesBySourceTags.push(localApp.articles[j].sourceTag); 500 } 501 localApp.articlesBySource[localApp.articles[j].sourceTag].push(localApp.articles[j]); 502 } 503 //Refresh articles list 504 localApp.rebuildMainArea(); 505 localApp.articlesLoading=false; 506 //Refresh notifications (5 max) first remove current notifications 507 mSystem.notificationController.removeNotification(localApp, 0
507); 508 mSystem.notificationController.removeNotification(localApp, 1); 509 mSystem.notificationController.removeNotification(localApp, 2); 510 mSystem.notificationController.removeNotification(localApp, 3); 511 mSystem.notificationController.removeNotification(localApp, 4); 512 //Add the lastest 5 publications using latest date 513 var sourceArticles; 514 var articleDate; 515 //for(var j=0;j<=4;j++) { 516 for(var j=4;j>=0;j--) { 517 if(j<localApp.articlesBySourceTags.length) { 518 sourceArticles=localApp.articlesBySource[localApp.articlesBySourceTags[j]]; 519 articleDate=new Date(sourceArticles[0].publishedDate); 520 mSystem.notificationController.addNotification(new Notification(localApp, j, sourceArticles[0].sourceLongTitle, "Current issue: "+mSystem.getMonthName(articleDate)+" "+articleDate.getFullYear(), new Date(sourceArticles[0].publishedDate), "")); 521 } 522 } 523 } 524 }); 525 } 526 if(!sourcesRequested) { 527 //Not a single source was requested, so just refresh with nothing. 528 localApp.rebuildMainArea(); 529 localApp.articlesLoading=false; 530 } 531 } 532 } 533 } 534} 535 536//////////////////////////////////////////////////////////////////////////////// 537// System Calls 538 539MDPublicationApp.prototype.listPublicationFeeds=function(medicalspecialtyid) { 540 var localApp=this; 541 542 var listPublicationFeedsRequest=$.ajax({ 543 url: "/system/index.php", 544 type: "POST", 545 dataType: "json", 546 data: { system: "app_mdpublication_listpublicationfeeds", medicalspecialtyid: medicalspecialtyid } 547 }); 548 549 listPublicationFeedsRequest.done(function(response) { 550 if(response.systemResponseCode==SYSTEMRESPONSECODE_SUCCESS) { 551 localApp.publicationFeedList=response.publicationFeedList; 552 553 if(localApp.publicationFeedList.length>0) localApp.loadArticles(); 554 555 //alert(listPublicationFeedsRequest.responseText); 556 } else if(response.systemResponseCode==SYSTEMRESPONSECODE_LOGOUT) { 557 medsquaresApp.logOut(false); 558 } else { 559 alert(localized("system.SystemError")); 560 } 561 }); 562 563 listPublicationFeedsRequest.fail(function(jqXHR, textStatus) { 564 alert(localized("system.SystemTimeout")); 565 }); 566}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.