From 19710d7306f19c9cfb8bb6bb6a661d5418df711a Mon Sep 17 00:00:00 2001
From: blavenie <benoit.lavenier@e-is.pro>
Date: Thu, 3 Aug 2017 18:51:20 +0200
Subject: [PATCH] [fix] fix groups lookup

---
 www/js/app.js                                 | 32 +++----
 www/plugins/es/i18n/locale-fr-FR.json         |  2 +
 .../es/js/controllers/common-controllers.js   | 42 +++++---
 .../es/js/controllers/group-controllers.js    | 32 +++++--
 .../es/js/controllers/registry-controllers.js | 32 +++----
 www/plugins/es/js/services/group-services.js  | 95 ++++++++++++++-----
 .../es/js/services/registry-services.js       |  2 +-
 .../es/js/services/settings-services.js       |  3 -
 .../es/templates/common/edit_pictures.html    | 22 +++--
 .../es/templates/group/item_group.html        | 40 ++++----
 .../es/templates/group/lookup_form.html       |  4 +-
 .../es/templates/group/view_record.html       |  6 +-
 .../es/templates/registry/edit_record.html    |  3 +-
 .../es/templates/registry/lookup_lg.html      |  2 +-
 www/templates/home/home.html                  |  2 +-
 15 files changed, 193 insertions(+), 126 deletions(-)

diff --git a/www/js/app.js b/www/js/app.js
index d5682e66..8c280a5e 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -140,10 +140,6 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
   // Must be done before any other $stateChangeStart listeners
   csPlatform.disableChangeState();
 
-  // removeIf(android)
-  // removeIf(ios)
-  // removeIf(firefoxos)
-  // -- Automatic redirection to large state (if define) (keep this code for platforms web and ubuntu build)
   var preventStateChange = false; // usefull to avoid duplicate login, when a first page with auth
   $rootScope.$on('$stateChangeStart', function (event, next, nextParams, fromState) {
     if (event.defaultPrevented) return;
@@ -158,14 +154,21 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
 
     var options;
 
-    // Large screen: redirect to specific state
+    // removeIf(android)
+    // removeIf(ios)
+    // removeIf(firefoxos)
+    // -- Automatic redirection to large state (if define) (keep this code for platforms web and ubuntu build)
     if (next.data.large && !UIUtils.screen.isSmall()) {
       event.preventDefault();
       $state.go(next.data.large, nextParams);
+      return;
     }
+    // endRemoveIf(firefoxos)
+    // endRemoveIf(ios)
+    // endRemoveIf(android)
 
     // If state need auth
-    else if (next.data.auth && !csWallet.isAuth()) {
+    if (next.data.auth && !csWallet.isAuth()) {
       event.preventDefault();
       options = next.data.minData ? {minData: true} : undefined;
       preventStateChange = true;
@@ -222,25 +225,14 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
       $state.go('app.home');
     }
   });
-  // endRemoveIf(firefoxos)
-  // endRemoveIf(ios)
-  // endRemoveIf(android)
 
   // Prevent $urlRouter's default handler from firing (don't sync ui router)
   $rootScope.$on('$locationChangeSuccess', function(event, newUrl, oldUrl) {
     if ($state.current.data && $state.current.data.silentLocationChange === true) {
-      var oldPath = oldUrl.split('?')[0];
-      var newPath = newUrl.split('?')[0];
-      if (newPath === oldPath) {
-        console.debug('[app] Skipping state sync (silent location change)');
-
-        event.preventDefault();
-        return;
-      }
+      // Skipping propagation, because same URL, and state configured with 'silentLocationChange' options
+      var sameUrl = oldUrl && (oldUrl.split('?')[0] === newUrl.split('?')[0]);
+      if (sameUrl) event.preventDefault();
     }
-
-    // default action, propagate to ui-router
-    //$urlRouter.sync();
   });
   // Configures $urlRouter's listener *after* the previous listener
   $urlRouter.listen();
diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json
index a9cf5d70..fce9f314 100644
--- a/www/plugins/es/i18n/locale-fr-FR.json
+++ b/www/plugins/es/i18n/locale-fr-FR.json
@@ -8,6 +8,7 @@
     "BTN_PUBLISH": "Publier",
     "BTN_PICTURE_DELETE": "Supprimer",
     "BTN_PICTURE_FAVORISE": "Principale",
+    "BTN_PICTURE_ROTATE": "Tourner",
     "BTN_ADD_PICTURE": "Ajouter une photo",
     "NOTIFICATIONS": {
       "TITLE": "Notifications",
@@ -204,6 +205,7 @@
     "LOCATION_DIVIDER": "Adresse",
     "SOCIAL_NETWORKS_DIVIDER": "Réseaux sociaux et site web",
     "TECHNICAL_DIVIDER": "Informations techniques",
+    "CREATED_TIME": "Crée {{creationTime|formatFromNow}}",
     "NOTIFICATIONS": {
       "TITLE": "Invitations"
     },
diff --git a/www/plugins/es/js/controllers/common-controllers.js b/www/plugins/es/js/controllers/common-controllers.js
index 6ec83000..0dd165c0 100644
--- a/www/plugins/es/js/controllers/common-controllers.js
+++ b/www/plugins/es/js/controllers/common-controllers.js
@@ -23,7 +23,7 @@ function ESPicturesEditController($scope, UIUtils, $q, Device) {
       openPicturePopup();
     }
     else {
-      var fileInput = angular.element(document.querySelector(inputSelector));
+      var fileInput = angular.element(document.querySelector(inputSelector||'#pictureFile'));
       if (fileInput && fileInput.length > 0) {
         fileInput[0].click();
       }
@@ -69,6 +69,14 @@ function ESPicturesEditController($scope, UIUtils, $q, Device) {
       $scope.pictures.splice(0, 0, item);
     }
   };
+
+  $scope.rotatePicture = function(index){
+    var item = $scope.pictures[index];
+    UIUtils.image.rotateSrc(item.src)
+      .then(function(dataURL){
+        item.src = dataURL;
+      });
+  };
 }
 
 
@@ -121,7 +129,6 @@ function ESCategoryModalController($scope, UIUtils, $timeout, parameters) {
     });
   }
 
-
 }
 
 
@@ -171,8 +178,10 @@ function ESCommentsController($scope, $timeout, $filter, $state, $focus, UIUtils
 
         // Set Motion
         $timeout(function() {
-          UIUtils.motion.fadeSlideIn({
-            selector: '.comments .item'});
+          $scope.motion.show({
+            selector: '.comments .item',
+            ink: false
+          });
         });
       });
   };
@@ -189,11 +198,9 @@ function ESCommentsController($scope, $timeout, $filter, $state, $focus, UIUtils
     $scope.load($scope.id, {from: from, size: size, loadAvatarAllParent: false})
     .then(function() {
       // Set Motion
-      $timeout(function() {
-        UIUtils.motion.fadeSlideIn({
-          selector: '.card-avatar'
-        });
-      }, 10);
+      $scope.motion.show({
+        selector: '.card-avatar'
+      });
     });
   };
 
@@ -301,9 +308,7 @@ function ESSocialsEditController($scope, $focus, $filter, UIUtils, SocialUtils)
     if (!$scope.socialData.url || $scope.socialData.url.trim().length === 0) {
       return;
     }
-    if (!$scope.formData.socials) {
-      $scope.formData.socials = [];
-    }
+    $scope.formData.socials = $scope.formData.socials || [];
     var url = $scope.socialData.url.trim();
 
     var exists = _.findWhere($scope.formData.socials, {url: url});
@@ -334,6 +339,10 @@ function ESSocialsEditController($scope, $focus, $filter, UIUtils, SocialUtils)
     $scope.socialData.url = social.url;
     $focus('socialUrl');
   };
+
+  $scope.filterFn = function(social) {
+    return !social.recipient || social.valid;
+  };
 }
 
 function ESSocialsViewController($scope, $window, Device, UIUtils)  {
@@ -341,17 +350,22 @@ function ESSocialsViewController($scope, $window, Device, UIUtils)  {
 
   $scope.open = function(event, social) {
     if (!social) return;
-    var url = (social.type == 'email') ? ('mailto:' + social.url) : social.url;
 
     // If email, do not try to open, but copy value
-    if (!Device.enable && social.type == 'email') {
+    if (!Device.enable && (social.type == 'email' || social.type == 'phone')) {
       UIUtils.popover.copy(event, social.url);
       return;
     }
 
     // Open the url
     // Note: If device is enable, this will use InAppBrowser cordova plugin
+    var url = (social.type == 'email')  ? ('mailto:' + social.url) :
+        ((social.type == 'phone')  ? ('tel:' + social.url) : social.url);
     $window.open(url, '_system', 'location=yes');
   };
 
+  $scope.filterFn = function(social) {
+    return !social.recipient || social.valid;
+  };
+
 }
diff --git a/www/plugins/es/js/controllers/group-controllers.js b/www/plugins/es/js/controllers/group-controllers.js
index 525b654f..032500e4 100644
--- a/www/plugins/es/js/controllers/group-controllers.js
+++ b/www/plugins/es/js/controllers/group-controllers.js
@@ -59,7 +59,7 @@ angular.module('cesium.es.group.controllers', ['cesium.es.services'])
 
 ;
 
-function ESGroupListController($scope, UIUtils, $state, csWallet, esGroup, ModalUtils) {
+function ESGroupListController($scope, UIUtils, $state, BMA, csWallet, esGroup, ModalUtils) {
   'ngInject';
 
   var defaultSearchLimit = 40;
@@ -73,6 +73,7 @@ function ESGroupListController($scope, UIUtils, $state, csWallet, esGroup, Modal
     limit: defaultSearchLimit
   };
   $scope.enableFilter = !UIUtils.screen.isSmall();
+  $scope.ionItemClass = 'item-border-large';
 
   $scope.$on('$ionicView.enter', function() {
     if ($scope.search.loading) {
@@ -80,10 +81,27 @@ function ESGroupListController($scope, UIUtils, $state, csWallet, esGroup, Modal
     }
   });
 
+  $scope.doSearchText = function() {
+    var text = $scope.search.text && $scope.search.text.trim();
+    if (!text || !text.length) {
+      return $scope.doSearchLast();
+    }
+    $scope.search.type='text';
+    return $scope.doSearch();
+  };
+
+  $scope.doSearchLast = function() {
+    $scope.search.type = 'last';
+    return $scope.doSearch();
+  };
+
   $scope.doSearch = function(from, size) {
     var options = {};
-    options.from = options.from || from || 0;
-    options.size = options.size || size || defaultSearchLimit;
+    options.from = from || 0;
+    options.size = size || defaultSearchLimit;
+
+    options.text = $scope.search.type == 'text' && $scope.search.text && $scope.search.text.trim();
+
     $scope.search.loading = true;
     return esGroup.record.search(options)
       .then(function(res) {
@@ -411,17 +429,17 @@ function ESGroupEditController($scope, esGroup, UIUtils, $state, $q, Device,
           json.pictures = $scope.pictures.reduce(function(res, pic) {
             return res.concat({file: esHttp.image.toAttachment(pic)});
           }, []);
-          return UIUtils.image.resizeSrc($scope.pictures[0].src, true) // resize thumbnail
+          return UIUtils.image.resizeSrc($scope.pictures[0].src, true) // resize avatar
             .then(function(imageSrc) {
-              json.thumbnail = esHttp.image.toAttachment({src: imageSrc});
+              json.avatar = esHttp.image.toAttachment({src: imageSrc});
               return json;
             });
         }
         else {
-          if (json.thumbnail) {
+          if (json.avatar) {
             // FIXME: this is a workaround to allow content deletion
             // Is it a bug in the ES attachment-mapper ?
-            json.thumbnail = {
+            json.avatar = {
               _content: '',
               _content_type: ''
             };
diff --git a/www/plugins/es/js/controllers/registry-controllers.js b/www/plugins/es/js/controllers/registry-controllers.js
index 56615a9c..16bda965 100644
--- a/www/plugins/es/js/controllers/registry-controllers.js
+++ b/www/plugins/es/js/controllers/registry-controllers.js
@@ -56,6 +56,10 @@ angular.module('cesium.es.registry.controllers', ['cesium.es.services', 'cesium.
           templateUrl: "plugins/es/templates/registry/edit_record.html",
           controller: 'ESRegistryRecordEditCtrl'
         }
+      },
+      data: {
+        auth: true,
+        minData: true
       }
     })
 
@@ -173,7 +177,6 @@ function ESRegistryLookupController($scope, $state, $focus, $timeout, esRegistry
     if (text.length > 1) {
       // pubkey : use a special 'term', because of 'non indexed' field
       if (BMA.regexp.PUBKEY.test(text /*case sensitive*/)) {
-        matches = [];
         filters.push({term : { issuer: text}});
         filters.push({term : { pubkey: text}});
       }
@@ -441,12 +444,10 @@ function ESRegistryRecordViewController($scope, $state, $q, $timeout, $ionicPopo
             }, []);
           }
           // Set Motion
-          $timeout(function(){
-            UIUtils.motion.fadeSlideIn({
-              selector: '.lazy-load .item.card-gallery, .lazy-load .item',
-              startVelocity: 3000
-            });
-          }, 200);
+          $scope.motion.show({
+            selector: '.lazy-load .item.card-gallery, .lazy-load .item',
+            startVelocity: 3000
+          });
         })
         .catch(function() {
           $scope.pictures = [];
@@ -563,7 +564,7 @@ function ESRegistryRecordEditController($scope, esRegistry, UIUtils, $state, $q,
         }
         $scope.loading = false;
         UIUtils.loading.hide();
-        UIUtils.motion.ripple();
+        $scope.motion.show();
       }
       // removeIf(device)
       $focus('registry-record-title');
@@ -585,14 +586,10 @@ function ESRegistryRecordEditController($scope, esRegistry, UIUtils, $state, $q,
         $scope.loading = false;
         UIUtils.loading.hide();
 
-        $timeout(function(){
-          UIUtils.motion.ripple({
-            selector: '.animate-ripple .item, .card-gallery',
-            startVelocity: 3000
-          });
-          // Set Ink
-          UIUtils.ink();
-        }, 100);
+        $scope.motion.show({
+          selector: '.animate-ripple .item, .card-gallery',
+          startVelocity: 3000
+        });
       })
       .catch(UIUtils.onError('REGISTRY.ERROR.LOAD_RECORD_FAILED'));
   };
@@ -605,8 +602,7 @@ function ESRegistryRecordEditController($scope, esRegistry, UIUtils, $state, $q,
     $scope.form.$submitted=true;
     if($scope.saving || // avoid multiple save
        !$scope.form.$valid ||
-       (!$scope.formData.category.id &&
-        ($scope.formData.type === 'shop' || $scope.formData.type === 'company'))) {
+       (($scope.formData.type === 'shop' || $scope.formData.type === 'company') && (!$scope.formData.category || !$scope.formData.category.id))) {
       return;
     }
     $scope.saving = true;
diff --git a/www/plugins/es/js/services/group-services.js b/www/plugins/es/js/services/group-services.js
index 6fd02827..849dfb96 100644
--- a/www/plugins/es/js/services/group-services.js
+++ b/www/plugins/es/js/services/group-services.js
@@ -11,14 +11,14 @@ angular.module('cesium.es.group.services', ['cesium.platform', 'cesium.es.http.s
 
   })
 
-.factory('esGroup', function($q, $rootScope, csPlatform, csSettings, esHttp, CryptoUtils, csWot, csWallet, esNotification, esComment) {
+.factory('esGroup', function($q, $rootScope, csPlatform, BMA, csSettings, esHttp, CryptoUtils, csWot, csWallet, esNotification, esComment) {
   'ngInject';
 
   var
     listeners,
     defaultLoadSize = 50,
     fields = {
-      list: ["issuer", "title"],
+      list: ["issuer", "title", "description", "type", "creationTime", "avatar._content_type"],
       commons: ["issuer", "title", "description", "creationTime", "time", "signature"],
       notifications: ["issuer", "time", "hash", "read_signature"]
     },
@@ -87,8 +87,8 @@ angular.module('cesium.es.group.services', ['cesium.platform', 'cesium.es.http.s
       record.description = esHttp.util.trustAsHtml(record.description);
     }
 
-    // thumbnail
-    record.thumbnail = esHttp.image.fromHit(hit, 'thumbnail');
+    // avatar
+    record.avatar = esHttp.image.fromHit(hit, 'avatar');
 
     // pictures
     if (hit._source.pictures && hit._source.pictures.reduce) {
@@ -102,24 +102,7 @@ angular.module('cesium.es.group.services', ['cesium.platform', 'cesium.es.http.s
 
   exports._internal.search = esHttp.post('/group/record/_search');
 
-  function searchGroups(options) {
-    if (!csWallet.isLogin()) {
-      return $q.when([]);
-    }
-
-    options = options || {};
-    options.from = options.from || 0;
-    options.size = options.size || defaultLoadSize;
-    options._source = options._source || fields.list;
-    var request = {
-      sort: {
-        "time" : "desc"
-      },
-      from: options.from,
-      size: options.size,
-      _source: options._source
-    };
-
+  function _executeSearchRequest(request) {
     return exports._internal.search(request)
       .then(function(res) {
         if (!res || !res.hits || !res.hits.total) {
@@ -131,12 +114,77 @@ angular.module('cesium.es.group.services', ['cesium.platform', 'cesium.es.http.s
           return record ? res.concat(record) : res;
         }, []);
 
-        console.debug('[ES] [group] Loading {0} {1} messages'.format(groups.length, options.type));
+        console.debug('[ES] [group] Loading {0} groups'.format(groups.length));
 
         return groups;
       });
   }
 
+  function getLastGroups(options) {
+    options = options || {};
+
+    /*if (!csWallet.isLogin()) {
+      return $q.when([]);
+    }*/
+
+    var request = {
+      sort: {
+        "time" : "desc"
+      },
+      from: options.from || 0,
+      size: options.size || defaultLoadSize,
+      _source: options._source || fields.list
+    };
+
+    return _executeSearchRequest(request);
+  }
+
+  function searchGroups(options) {
+    options = options || {};
+
+    var text = options.text && options.text.trim();
+    if (!text) return getLastGroups(options);
+
+    var request = {
+      from: options.from || 0,
+      size: options.size || defaultLoadSize,
+      highlight: {fields : {title : {}, tags: {}}},
+      _source: options._source || fields.list
+    };
+
+
+    var matches = [];
+    var filters = [];
+    // pubkey : use a special 'term', because of 'non indexed' field
+    if (BMA.regexp.PUBKEY.test(text /*case sensitive*/)) {
+      filters.push({term : { issuer: text}});
+      filters.push({term : { pubkey: text}});
+    }
+    else {
+      text = text.toLowerCase();
+      var matchFields = ["title", "description"];
+      matches.push({multi_match : { query: text,
+        fields: matchFields,
+        type: "phrase_prefix"
+      }});
+      matches.push({match : { title: text}});
+      matches.push({match : { description: text}});
+    }
+
+    request.query = {bool: {}};
+    if (matches.length > 0) {
+      request.query.bool.should =  matches;
+    }
+    if (filters.length > 0) {
+      request.query.bool.filter =  filters;
+    }
+
+
+
+
+    return _executeSearchRequest(request);
+  }
+
   exports._internal.get = esHttp.get('/group/record/:id');
   exports._internal.getCommons = esHttp.get('/group/record/:id?_source=' + fields.commons.join(','));
 
@@ -209,6 +257,7 @@ angular.module('cesium.es.group.services', ['cesium.platform', 'cesium.es.http.s
 
   return {
     record: {
+      last: getLastGroups,
       search: searchGroups,
       load: loadData,
       add: esHttp.record.post('/group/record'),
diff --git a/www/plugins/es/js/services/registry-services.js b/www/plugins/es/js/services/registry-services.js
index 6e6c8146..ff8294a0 100644
--- a/www/plugins/es/js/services/registry-services.js
+++ b/www/plugins/es/js/services/registry-services.js
@@ -1,6 +1,6 @@
 angular.module('cesium.es.registry.services', ['ngResource', 'cesium.services', 'cesium.es.http.services'])
 
-.factory('esRegistry', function($q, csSettings, esHttp, esComment, esProfile) {
+.factory('esRegistry', function($q, csSettings, esHttp, esComment, csWot) {
   'ngInject';
 
   function EsRegistry() {
diff --git a/www/plugins/es/js/services/settings-services.js b/www/plugins/es/js/services/settings-services.js
index 1570d704..b791fbc0 100644
--- a/www/plugins/es/js/services/settings-services.js
+++ b/www/plugins/es/js/services/settings-services.js
@@ -322,9 +322,6 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt
             console.debug("[ES] [settings] Enable");
             addListeners();
 
-            // Emit event
-            api.state.raise.changed(enable);
-
             if (csWallet.isLogin()) {
               return onWalletLogin(csWallet.data)
                 .then(function() {
diff --git a/www/plugins/es/templates/common/edit_pictures.html b/www/plugins/es/templates/common/edit_pictures.html
index 419505a0..7ad78b62 100644
--- a/www/plugins/es/templates/common/edit_pictures.html
+++ b/www/plugins/es/templates/common/edit_pictures.html
@@ -6,19 +6,21 @@
        ng-class="{'in done': picture.isnew}">
     <div>
       <h2 ng-if="picture.title">{{picture.title}}</h2>
-      <img ng-src="{{picture.src}}" ></img>
+      <img ng-src="{{picture.src}}">
     </div>
-    <div class="item in done tabs tabs-secondary tabs-icon-left">
-      <a class="tab-item stable-bg assertive-900" ng-click="removePicture($index)">
-        <i class="icon ion-close"></i>
-        {{'COMMON.BTN_PICTURE_DELETE'|translate}}
-      </a>
+    <div class="item done in tabs tabs-secondary tabs-icon-left">
+      <a class="tab-item stable-bg assertive" ng-click="removePicture($index)"
+         title="{{'COMMON.BTN_PICTURE_DELETE' | translate}}"
+        ><i class="icon ion-trash-a"></i>{{'COMMON.BTN_PICTURE_DELETE'|translate}}</a>
+      <a class="tab-item stable-bg dark"
+         ng-click="rotatePicture($index)"
+         title="{{'COMMON.BTN_PICTURE_ROTATE' | translate}}"
+        ><i class="icon ion-forward"></i>{{'COMMON.BTN_PICTURE_ROTATE'|translate}}</a>
       <a class="tab-item stable-bg"
          ng-click="favoritePicture($index)"
-         ng-class="{'dark': $index !== 0, 'positive-900': $index === 0}">
-        <i class="icon ion-star"></i>
-        {{'COMMON.BTN_PICTURE_FAVORISE'|translate}}
-      </a>
+         ng-class="{'gray': $index !== 0, 'positive': $index === 0}"
+         title="{{'COMMON.BTN_PICTURE_FAVORISE' | translate}}"
+        ><i class="icon ion-star"></i>{{'COMMON.BTN_PICTURE_FAVORISE'|translate}}</a>
     </div>
   </div>
 
diff --git a/www/plugins/es/templates/group/item_group.html b/www/plugins/es/templates/group/item_group.html
index 313f7bc9..26afc411 100644
--- a/www/plugins/es/templates/group/item_group.html
+++ b/www/plugins/es/templates/group/item_group.html
@@ -1,27 +1,25 @@
 <a name="group-{{:rebind:group.hash}}"></a>
-<ion-item id="group-{{:rebind:block.hash}}"
-          class="item item-icon-left item-group {{ionItemClass}}"
+<div id="group-{{:rebind:group.hash}}"
+          class="item item-icon-right item-avatar {{::ionItemClass}} ink"
           ng-click="select(group)">
 
-  <i class="icon ion-cube stable" ng-if=":rebind:(!group.empty && !group.avatar)"></i>
-  <i class="avatar" ng-if=":rebind:!group.empty && group.avatar" style="background-image: url('{{:rebind:block.avatar.src}}')"></i>
+  <i class="item-image avatar" style="background-image: url({{::group.avatar.src}})" ng-if="group.avatar"></i>
+  <i class="item-image icon ion-android-people" ng-if="!group.avatar"></i>
+  <i class="item-image icon-secondary ion-android-lock" ng-if="!group.avatar" style="left: 20px; top: 17px; font-size: 19px; color: #d9d9d9;"></i>
 
-  <div class="row no-padding">
-    <div class="col">
-      <h4 class="dark">
-        <i class="ion-clock"></i>
-        {{:rebind:group.creationTime|formatDate}}
-      </h4>
-      <h4>
-        <!-- membersCount -->
-        <i class="dark ion-person"></i>
-        <span class="dark" ng-if=":rebind:group.membersCount">+{{:rebind:group.membersCount}}</span>
-      </h4>
-    </div>
+  <h2 ng-bind-html=":rebind:group.title"></h2>
 
-    <div class="col col-33 positive hidden-md">
-      <h4><i class="ion-person"></i> <span ng-bind-html=":rebind:group.title"></span></h4>
-    </div>
+  <!-- creation time-->
+  <h4 class="gray pull-right">
+    <i class="ion-clock"></i>
+    {{:rebind:'GROUP.CREATED_TIME'|translate: group }}
+  </h4>
 
-  </div>
-</ion-item>
+  <!-- membersCount -->
+  <h4 class="dark pull-left" ng-if=":rebind:group.membersCount">
+    <i class="dark ion-person"></i>
+    <span class="dark">+{{:rebind:group.membersCount}}</span>
+  </h4>
+
+  <i class="icon ion-ios-arrow-right"></i>
+</div>
diff --git a/www/plugins/es/templates/group/lookup_form.html b/www/plugins/es/templates/group/lookup_form.html
index 0c6b9ae2..a6e1900c 100644
--- a/www/plugins/es/templates/group/lookup_form.html
+++ b/www/plugins/es/templates/group/lookup_form.html
@@ -71,11 +71,11 @@
     </div>
   </div>
 
-  <ion-list class="list {{ionListClass}}">
+  <div class="list {{::motion.ionListClass}}" ng-if="!$scope.search.loading">
 
     <ng-include src="'plugins/es/templates/group/items_groups.html'"></ng-include>
 
-  </ion-list>
+  </div>
 
   <ion-infinite-scroll
     ng-if="search.hasMore"
diff --git a/www/plugins/es/templates/group/view_record.html b/www/plugins/es/templates/group/view_record.html
index ad3bab2c..0a2dbdfb 100644
--- a/www/plugins/es/templates/group/view_record.html
+++ b/www/plugins/es/templates/group/view_record.html
@@ -15,8 +15,8 @@
   <ion-content scroll="true">
     <div class="positive-900-bg hero">
       <div class="content" ng-if="!loading">
-        <i class="avatar cion-registry-{{formData.type}}" ng-if="!formData.thumbnail"></i>
-        <i class="avatar" style="background-image: url({{::formData.thumbnail.src}})" ng-if="formData.thumbnail"></i>
+        <i class="avatar cion-registry-{{formData.type}}" ng-if="!formData.avatar"></i>
+        <i class="avatar" style="background-image: url({{::formData.avatar.src}})" ng-if="formData.avatar"></i>
         <h3 ng-bind-html="formData.title"></h3>
         <h4>&nbsp;</h4>
       </div>
@@ -29,7 +29,7 @@
       <div class="col col-20 hidden-xs hidden-sm">&nbsp;
       </div>
 
-      <div class="col list item-text-wrap no-padding-xs" ng-class="motion.ionListClass">
+      <div class="col list item-text-wrap no-padding-xs" ng-class="::motion.ionListClass">
 
         <div class="item">
           <h2 class="gray">
diff --git a/www/plugins/es/templates/registry/edit_record.html b/www/plugins/es/templates/registry/edit_record.html
index be56da16..e8f1438f 100644
--- a/www/plugins/es/templates/registry/edit_record.html
+++ b/www/plugins/es/templates/registry/edit_record.html
@@ -23,8 +23,7 @@
           </div>
 
           <form name="recordForm" novalidate="" ng-submit="save()">
-            <div class="list"
-                 ng-class="motion.ionListClass"
+            <div class="list {{::motion.ionListClass}}"
                  ng-init="setForm(recordForm)">
 
               <div class="item hidden-xs">
diff --git a/www/plugins/es/templates/registry/lookup_lg.html b/www/plugins/es/templates/registry/lookup_lg.html
index 27fefea2..1e3eeba6 100644
--- a/www/plugins/es/templates/registry/lookup_lg.html
+++ b/www/plugins/es/templates/registry/lookup_lg.html
@@ -62,7 +62,7 @@
       COMMON.SEARCH_NO_RESULT
     </div>
 
-    <div class="list animate-ripple"
+    <div class="list {{::motion.ionListClass}}"
          ng-if="!search.loading && search.results && search.results.length > 0">
 
       <a ng-repeat="rec in search.results"
diff --git a/www/templates/home/home.html b/www/templates/home/home.html
index d19414dc..1b66d50a 100644
--- a/www/templates/home/home.html
+++ b/www/templates/home/home.html
@@ -19,7 +19,7 @@
               <span class="dark" trust-as-html="'HOME.CONNECTION_ERROR'|translate:node"></span>
           </p>
 
-          <!-- Retry-->
+          <!-- Retry -->
           <button type="button"
                   class="button button-positive icon icon-left ion-refresh ink"
                   ng-click="reload()">{{'COMMON.BTN_REFRESH'|translate}}</button>
-- 
GitLab