From f0f547af4b779d3bd67fa94e0bc48f3e7dd40f84 Mon Sep 17 00:00:00 2001
From: Eike Cochu <eike@cochu.com>
Date: Mon, 2 May 2016 00:34:45 +0200
Subject: [PATCH] fixed some npes, added loading screen and fade to loading
 topic models

---
 vipra                                         |  8 +++---
 .../main/java/de/vipra/cmd/lda/Analyzer.java  |  7 +++--
 vipra-ui/app/html/index.html                  |  4 +--
 vipra-ui/app/index.html                       | 10 ++++++-
 vipra-ui/app/js/app.js                        |  1 +
 vipra-ui/app/js/controllers.js                | 10 +++++--
 vipra-ui/app/less/app.less                    | 26 ++++++++++++++++---
 vipra-ui/bower.json                           |  5 ++--
 vipra-ui/gulpfile.js                          |  1 +
 .../java/de/vipra/util/model/ArticleFull.java |  4 ++-
 .../de/vipra/util/model/ArticleStats.java     |  3 +++
 11 files changed, 63 insertions(+), 16 deletions(-)

diff --git a/vipra b/vipra
index bd0b989a..eb76199d 100755
--- a/vipra
+++ b/vipra
@@ -10,9 +10,11 @@ if [ $? -ne 0 ]; then
 fi
 
 JARS="$VIPRA_JAR
-/opt/vipra/vipra-cmd/target/vipra-cmd*.jar
-vipra-cmd*.jar
-$DIR/vipra-cmd/target/vipra-cmd*.jar"
+/opt/vipra/vipra-cmd/target/vipra*.jar
+vipra*.jar
+$DIR/vipra-cmd/target/vipra*.jar
+$DIR/target/vipra*.jar
+$DIR/vipra*.jar"
 for f in $JARS
 do
   if [ -f $f ]; then
diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/lda/Analyzer.java b/vipra-cmd/src/main/java/de/vipra/cmd/lda/Analyzer.java
index 0c416a9a..8bbdec95 100644
--- a/vipra-cmd/src/main/java/de/vipra/cmd/lda/Analyzer.java
+++ b/vipra-cmd/src/main/java/de/vipra/cmd/lda/Analyzer.java
@@ -140,7 +140,9 @@ public class Analyzer {
 					avgDuration = smoothingFactor * lastDuration + (1 - smoothingFactor) * avgDuration;
 					final long remainingDuration = (long) avgDuration * (modelConfig.getDynamicMaxIterations() - iteration);
 
-					lastLength = printProgress(tenthPercent, progress, iteration, maxIterationsLength, remainingDuration, modelConfig, lastLength);
+					if (progress <= 100)
+						lastLength = printProgress(tenthPercent, progress, iteration, maxIterationsLength, remainingDuration, modelConfig,
+								lastLength);
 				}
 			}
 
@@ -436,7 +438,8 @@ public class Analyzer {
 
 		for (ListIterator<TopicFull> iter = newTopics.listIterator(); iter.hasNext();) {
 			TopicFull topic = iter.next();
-			if (topic.getArticlesCount() == 0)
+			Integer articlesCount = topic.getArticlesCount();
+			if (articlesCount == null || articlesCount == 0)
 				iter.remove();
 		}
 
diff --git a/vipra-ui/app/html/index.html b/vipra-ui/app/html/index.html
index c8494200..44abb260 100644
--- a/vipra-ui/app/html/index.html
+++ b/vipra-ui/app/html/index.html
@@ -47,7 +47,7 @@
               <article-link article="::article" badge="false" menu="false" excerpt="false"/>
             </li>
           </ul>
-          <p class="text-muted text-center" ng-if="!latestArticles.length">No articles</p>
+          <p class="text-center" ng-if="!latestArticles.length">No articles</p>
         </div>
         <div class="col-md-4 text-center">
           <h4>Latest topics</h4>
@@ -56,7 +56,7 @@
               <topic-link topic="::topic" badge="false" menu="false"/>
             </li>
           </ul>
-          <p class="text-muted text-center" ng-if="!latestTopics.length">No topics</p>
+          <p class="text-center" ng-if="!latestTopics.length">No topics</p>
         </div>
       </div>
     </div>
diff --git a/vipra-ui/app/index.html b/vipra-ui/app/index.html
index ba25f1f9..18917c14 100644
--- a/vipra-ui/app/index.html
+++ b/vipra-ui/app/index.html
@@ -126,8 +126,16 @@
   <div class="alerts">
     <bs-alert ng-model="alert" type="alert.type" ng-repeat="alert in alerts"/>
   </div>
-  <div class="fatal message-container" ng-show="fatal">
+  <div class="overlay-message" ng-show="fatal">
     <div class="message" ng-bind="fatal"></div>
   </div>
+  <div class="overlay-message fadein fadeout" ng-show="loadingScreen">
+    <svg class="logo animate centered" viewBox="0 0 200 120" style="width:200px">
+      <polyline style="animation-delay:0s" class="logo-shape" points="0,0 100,45 100,75 0,0" fill="#006591" />
+      <polyline style="animation-delay:.5s" class="logo-shape" points="100,45 200,0 100,75 100,45" fill="#0079a2" />
+      <polyline style="animation-delay:1s" class="logo-shape" points="100,75 200,0 100,120 100,75" fill="#006591" />
+      <polyline style="animation-delay:1.5s" class="logo-shape" points="0,0 100,75 100,120 0,0" fill="#0079a2" />
+    </svg>
+  </div>
 </body>
 </html>
\ No newline at end of file
diff --git a/vipra-ui/app/js/app.js b/vipra-ui/app/js/app.js
index b4a58acc..a5374727 100644
--- a/vipra-ui/app/js/app.js
+++ b/vipra-ui/app/js/app.js
@@ -10,6 +10,7 @@
   var app = angular.module('vipra.app', [
     'ngResource',
     'ngSanitize',
+    'ngAnimate',
     'ui.router',
     'cfp.hotkeys',
     'nya.bootstrap.select',
diff --git a/vipra-ui/app/js/controllers.js b/vipra-ui/app/js/controllers.js
index 0303126f..9f9e5d25 100644
--- a/vipra-ui/app/js/controllers.js
+++ b/vipra-ui/app/js/controllers.js
@@ -9,8 +9,8 @@
 
   var app = angular.module('vipra.controllers', []);
 
-  app.controller('RootController', ['$scope', '$state', '$window', 'hotkeys', 'TopicModelFactory',
-    function($scope, $state, $window, hotkeys, TopicModelFactory) {
+  app.controller('RootController', ['$scope', '$rootScope', '$state', '$window', 'hotkeys', 'TopicModelFactory',
+    function($scope, $rootScope, $state, $window, hotkeys, TopicModelFactory) {
 
       $scope.rootModels = {
         topicModel: null,
@@ -20,13 +20,19 @@
       var prevTopicModelLoading = false;
       if (localStorage.tm) {
         prevTopicModelLoading = true;
+        $rootScope.loadingScreen = true;
+
         TopicModelFactory.get({
           id: localStorage.tm
         }, function(data) {
           $scope.rootModels.topicModel = data;
           prevTopicModelLoading = false;
+          $scope.loadingScreen = false;
         }, function() {
+          delete localStorage.tm;
           prevTopicModelLoading = false;
+          $scope.loadingScreen = false;
+          $scope.chooseTopicModel();
         });
       }
 
diff --git a/vipra-ui/app/less/app.less b/vipra-ui/app/less/app.less
index 075a6a71..c846d7cb 100644
--- a/vipra-ui/app/less/app.less
+++ b/vipra-ui/app/less/app.less
@@ -676,7 +676,7 @@ entity-menu {
   overflow: auto;
 }
 
-.fatal {
+.overlay-message {
   .noselect;
   position: fixed;
   top: 0;
@@ -684,7 +684,7 @@ entity-menu {
   right: 0;
   bottom: 0;
   z-index: 9999;
-  background: rgba(0,0,0,0.1);
+  background: rgba(0,0,0,0.25);
   .message {
     color: #fff;
     font-size: 35px;
@@ -711,13 +711,33 @@ entity-menu {
   }
 }
 
-.index{
+.index {
   .navbar-default {
     border-color: transparent;
     background: rgba(255,255,255,0.6);
   }
 }
 
+.fadein,
+.fadeout {
+  -webkit-transition: all linear .3s;
+  -moz-transition: all linear .3s;
+  -o-transition: all linear .3s;
+  transition: all linear .3s;
+}
+
+.fadein.ng-hide-remove,
+.fadeout.ng-hide-add.ng-hide-add-active {
+  opacity: 0;
+  display: block !important;
+}
+
+.fadeout.ng-hide-add,
+.fadein.ng-hide-remove.ng-hide-remove-active {
+  opacity: 1;
+  display: block !important;
+}
+
 @-moz-keyframes spin {
   100% {
     -moz-transform: rotateY(360deg);
diff --git a/vipra-ui/bower.json b/vipra-ui/bower.json
index 1f12c078..160ceb62 100644
--- a/vipra-ui/bower.json
+++ b/vipra-ui/bower.json
@@ -21,8 +21,8 @@
     "jquery": "^2.x",
     "angular": "^1.x",
     "angular-resource": "^1.x",
-    "angular-ui-router": "^0.x",
     "angular-sanitize": "^1.x",
+    "angular-ui-router": "^0.x",
     "highcharts": "^4.x",
     "vis": "^4.x",
     "moment": "^2.x",
@@ -32,6 +32,7 @@
     "randomcolor": "randomColor#^0.x",
     "bootbox.js": "bootbox#^4.x",
     "angular-hotkeys": "chieffancypants/angular-hotkeys#^1.x",
-    "eonasdan-bootstrap-datetimepicker": "^4.17.37"
+    "eonasdan-bootstrap-datetimepicker": "^4.17.37",
+    "angular-animate": "^1.5.5"
   }
 }
diff --git a/vipra-ui/gulpfile.js b/vipra-ui/gulpfile.js
index 168bf714..fb129804 100644
--- a/vipra-ui/gulpfile.js
+++ b/vipra-ui/gulpfile.js
@@ -15,6 +15,7 @@ var assets = {
     'bower_components/angular/angular.min.js',
     'bower_components/angular-resource/angular-resource.min.js',
     'bower_components/angular-sanitize/angular-sanitize.min.js',
+    'bower_components/angular-animate/angular-animate.min.js',
     'bower_components/angular-hotkeys/build/hotkeys.min.js',
     'bower_components/angular-ui-router/release/angular-ui-router.min.js',
     'bower_components/bootstrap/dist/js/bootstrap.min.js',
diff --git a/vipra-util/src/main/java/de/vipra/util/model/ArticleFull.java b/vipra-util/src/main/java/de/vipra/util/model/ArticleFull.java
index d9929868..1f905fc7 100644
--- a/vipra-util/src/main/java/de/vipra/util/model/ArticleFull.java
+++ b/vipra-util/src/main/java/de/vipra/util/model/ArticleFull.java
@@ -209,7 +209,9 @@ public class ArticleFull implements Model<ObjectId>, Serializable {
 			return new String[0];
 		final List<String> topics = new ArrayList<>(refs.size());
 		for (final TopicShare ref : refs) {
-			topics.add(ref.getTopic().getName());
+			final Topic topic = ref.getTopic();
+			if(topic != null)
+				topics.add(topic.getName());
 		}
 		return topics.toArray(new String[topics.size()]);
 	}
diff --git a/vipra-util/src/main/java/de/vipra/util/model/ArticleStats.java b/vipra-util/src/main/java/de/vipra/util/model/ArticleStats.java
index 4c012be2..c8d25ee6 100644
--- a/vipra-util/src/main/java/de/vipra/util/model/ArticleStats.java
+++ b/vipra-util/src/main/java/de/vipra/util/model/ArticleStats.java
@@ -13,8 +13,11 @@ public class ArticleStats implements Serializable {
 	private static final long serialVersionUID = -4712841724990200627L;
 
 	private Long wordCount;
+	
 	private Long uniqueWordCount;
+	
 	private Long processedWordCount;
+	
 	private Double reductionRatio;
 
 	public Long getWordCount() {
-- 
GitLab