From b3e6fbf25e063ac9957511fea2769183106275a7 Mon Sep 17 00:00:00 2001 From: Gary Lo Date: Sun, 15 Apr 2018 04:44:59 +0800 Subject: [PATCH] replace ion-spinner by custom implementation (ir-spinner) to optimize performance clone & rewrite ionic-image-lazy plugin for optimize image loading performance modify ion-infinite-scroll directive for performance improve loading previous ux bump version to 3.1.0 --- bower.json | 1 - src/es6/core/app.js | 2 - .../core/controller/PostDetailController.js | 30 +- .../core/controller/TopicListController.js | 2 +- src/es6/core/directives.js | 315 ++++++++++++------ src/es6/core/model/general-html.js | 1 - src/es6/core/model/hkepc-html.js | 1 - src/es6/data/config/hkepc.js | 2 +- src/scss/global.scss | 5 + src/scss/spinner.scss | 45 +++ src/scss/topics/card.view.scss | 5 +- www/index.android.dark.html | 1 - www/index.android.html | 1 - www/index.dark.html | 1 - www/index.html | 1 - www/index.ios.dark.html | 1 - www/index.ios.html | 1 - www/lib/ionic/js/ionic-angular.js | 21 +- www/templates/about/version.html | 5 +- www/templates/edit-post.html | 2 +- .../features/chats/chats.details.html | 9 +- www/templates/features/chats/chats.list.html | 13 +- www/templates/features/features.route.html | 4 +- .../features/history/history.details.html | 4 +- www/templates/features/history/history.html | 4 +- www/templates/features/mypost/my.post.html | 4 +- www/templates/features/myreply/my.reply.html | 8 +- .../features/notification/notification.html | 13 +- www/templates/find-message.html | 4 +- www/templates/ir/index.html | 8 +- www/templates/post-detail.html | 16 +- www/templates/post-list.html | 4 +- www/templates/search.html | 5 +- www/templates/tab-likes.html | 4 +- www/templates/tab-topics.html | 2 +- www/templates/user-profile.html | 2 +- 36 files changed, 352 insertions(+), 195 deletions(-) diff --git a/bower.json b/bower.json index fc41c256..c2dfedf8 100644 --- a/bower.json +++ b/bower.json @@ -2,7 +2,6 @@ "name": "hkepc-ir-pro-html", "private": "true", "dependencies": { - "ionic-image-lazy-load": "ion-image-lazy-load#*", "ngToast": "ngtoast#~1.5.6", "csshake": "*", "babel-polyfill": "^0.0.1", diff --git a/src/es6/core/app.js b/src/es6/core/app.js index d1cabe3a..934abd5c 100644 --- a/src/es6/core/app.js +++ b/src/es6/core/app.js @@ -44,7 +44,6 @@ function dynamicModules() { 'starter.services', 'starter.directives', 'ngToast', - 'ionicLazyLoad', 'rx', 'ngFileUpload', ] @@ -55,7 +54,6 @@ function dynamicModules() { 'starter.services', 'starter.directives', 'ngToast', - 'ionicLazyLoad', 'LocalForageModule', 'rx', 'ngFileUpload', diff --git a/src/es6/core/controller/PostDetailController.js b/src/es6/core/controller/PostDetailController.js index 29581fb4..5a33b4ca 100644 --- a/src/es6/core/controller/PostDetailController.js +++ b/src/es6/core/controller/PostDetailController.js @@ -290,7 +290,6 @@ export class PostDetailController{ } else { // normal style (next) - this.scope.$broadcast('scroll.infiniteScrollComplete') this.messages.push({ post: { page: page }, @@ -306,6 +305,10 @@ export class PostDetailController{ } } + this.$timeout(() => { + this.scope.$broadcast('scroll.infiniteScrollComplete') + }) + this.refreshing = false this.loadingPrevious = false this.end = page >= this.totalPageNum @@ -317,10 +320,11 @@ export class PostDetailController{ const focusPosition = angular.element(document.querySelector(`#message-${this.focus}`)).prop('offsetTop') console.log("ready to scroll to ",document.querySelector(`#message-${this.focus}`), focusPosition) - this.$timeout(() =>{ - this.ionicScrollDelegate.scrollTo(0,focusPosition) - }) + this.ionicScrollDelegate.scrollTo(0,focusPosition) + this.$timeout(() => { + swal.close() + }) this.focus = undefined }) @@ -528,14 +532,26 @@ export class PostDetailController{ doLoadPreviousPage(){ const minPageNum = Math.min(...this.messages.map(msg => msg.post.page)) - // scroll to top first - this.ionicScrollDelegate.scrollTo(0,0, true) this.inputPage = minPageNum == 1 ? 1 : minPageNum - 1 + const spinnerHtml = ` +
+
加載上一頁中
+
+ ` + + swal({ + html: spinnerHtml, + allowOutsideClick: false, + showCancelButton: false, + showConfirmButton: false, + }) + + swal.showLoading() + this.$timeout(() => { this.currentPage = minPageNum - this.doJumpPage() },400) diff --git a/src/es6/core/controller/TopicListController.js b/src/es6/core/controller/TopicListController.js index 6cc35894..4d7ccfe4 100644 --- a/src/es6/core/controller/TopicListController.js +++ b/src/es6/core/controller/TopicListController.js @@ -1,8 +1,8 @@ /** * Created by Gaplo917 on 11/1/2016. */ -import {Bridge} from "../bridge/Bridge"; import * as Controllers from "./index" +import swal from 'sweetalert2' export class TopicListController { diff --git a/src/es6/core/directives.js b/src/es6/core/directives.js index a2cd7730..db866bd2 100644 --- a/src/es6/core/directives.js +++ b/src/es6/core/directives.js @@ -3,83 +3,83 @@ */ import * as HKEPC from '../data/config/hkepc' -import { Bridge, Channel } from './bridge/index' +import {Bridge, Channel} from './bridge/index' /** * Register the directives */ -export default - angular.module('starter.directives', ['ngAnimate']) +export default angular.module('starter.directives', ['ngAnimate']) .directive('compile', ['$compile', ($compile) => { return (scope, element, attrs) => { scope.$watch( - (scope) => { - return scope.$eval(attrs.compile); - }, - (value) => { - element.html(value); - $compile(element.contents())(scope); - } - )}; + (scope) => { + return scope.$eval(attrs.compile); + }, + (value) => { + element.html(value); + $compile(element.contents())(scope); + } + ) + }; }]) .directive('lastread', ($document, $timeout, $ionicScrollDelegate) => { return { - restrict: 'A', - scope: true, - link: ($scope, $element, $attributes) => { + restrict: 'A', + scope: true, + link: ($scope, $element, $attributes) => { - const deregistration = $scope.$on('lazyScrollEvent', () => { - if (isInView()) { - //console.log("isInView",$attributes.id,$attributes.page) - $scope.$emit('lastread', { page: $attributes.page, id: $attributes.id }) - } - }) + const deregistration = $scope.$on('lazyScrollEvent', () => { + if (isInView()) { + //console.log("isInView",$attributes.id,$attributes.page) + $scope.$emit('lastread', {page: $attributes.page, id: $attributes.id}) + } + }) - function isInView() { - var clientHeight = $document[0].documentElement.clientHeight; - // var clientWidth = $document[0].documentElement.clientWidth; - var imageRect = $element[0].getBoundingClientRect(); + function isInView() { + var clientHeight = $document[0].documentElement.clientHeight; + // var clientWidth = $document[0].documentElement.clientWidth; + var imageRect = $element[0].getBoundingClientRect(); - //console.log(`isInView height ${clientHeight}, width ${clientWidth}`,imageRect) + //console.log(`isInView height ${clientHeight}, width ${clientWidth}`,imageRect) - // scroll to the half of the screen mean user if viewing - return (imageRect.top >= 0 && imageRect.top <= clientHeight / 2) - } + // scroll to the half of the screen mean user if viewing + return (imageRect.top >= 0 && imageRect.top <= clientHeight / 2) + } - // bind listener - // listenerRemover = scrollAndResizeListener.bindListener(isInView); + // bind listener + // listenerRemover = scrollAndResizeListener.bindListener(isInView); - // unbind event listeners if element was destroyed - // it happens when you change view, etc - $element.on('$destroy', () => { - deregistration(); - }) + // unbind event listeners if element was destroyed + // it happens when you change view, etc + $element.on('$destroy', () => { + deregistration(); + }) - $timeout(() => { - if (isInView()) { - $scope.$emit('lastread', { page: $attributes.page, id: $attributes.id }) - deregistration(); - } - }); + $timeout(() => { + if (isInView()) { + $scope.$emit('lastread', {page: $attributes.page, id: $attributes.id}) + deregistration(); + } + }); - } } + } }) - .directive('inputHelper', (Upload,$timeout) => { + .directive('inputHelper', (Upload, $timeout) => { return { restrict: 'E', - scope: { - modal:'=', - contentModel:'=', + scope: { + modal: '=', + contentModel: '=', onImageUpload: '=' }, - link: function (scope, element) { + link: function (scope, element) { const modal = scope.modal scope.selectTab = (index) => { - if(index === 4 && Bridge.isAvailable()){ + if (index === 4 && Bridge.isAvailable()) { Bridge.callHandler(Channel.uploadImage, modal.hiddenAttachFormInputs, (attachmentIds) => { modal.onImageUploadSuccess(attachmentIds) @@ -105,13 +105,12 @@ export default scope.imageErrSuggestion = undefined scope.previewUploadImage = undefined - if (file) { var reader = new FileReader(); reader.onload = function (e) { - const fileSizeInKB = e.total/1000 - if(fileSizeInKB >= 150){ + const fileSizeInKB = e.total / 1000 + if (fileSizeInKB >= 150) { scope.imageErr = `圖片(${fileSizeInKB} KB) 大於 HKEPC 限制(150KB)` scope.imageErrSuggestion = `iOS 用家:可使用 Apple 新收購的 Work Flow 配搭作者設計專用的 Script 壓縮圖片。查看此教學` @@ -131,7 +130,7 @@ export default scope.upload = function () { console.log("modal.hiddenAttachFormInputs", modal.hiddenAttachFormInputs) - if(!modal.hiddenAttachFormInputs){ + if (!modal.hiddenAttachFormInputs) { throw new Error("Modal Missing hiddenAttachFormInputs") } @@ -139,17 +138,17 @@ export default data.Filedata = scope.file Upload.upload({ - url: data.action, + url: data.action, data: data }).then(function (resp) { - console.log('Success uploaded. Response: ' , resp.data); + console.log('Success uploaded. Response: ', resp.data); //DISCUZUPLOAD|0|1948831|1 const attactmentId = resp.data.split('|')[2] modal.onImageUpload({ - formData:`attachnew[${attactmentId}][description]=`, - id: attactmentId + formData: `attachnew[${attactmentId}][description]=`, + id: attactmentId }) scope.imageUploadSuccess = `上傳成功,已插入 ${attachImageCode}!` @@ -175,13 +174,13 @@ export default modal.gifs = HKEPC.data.gifs - modal.addUrlToText = function(url,urlText) { + modal.addUrlToText = function (url, urlText) { const selectorId = this.id const selectionStart = document.getElementById(selectorId).selectionStart const content = document.getElementById(selectorId).value - const splits = [content.slice(0,selectionStart),content.slice(selectionStart)] + const splits = [content.slice(0, selectionStart), content.slice(selectionStart)] - if(urlText) { + if (urlText) { scope.contentModel = `${splits[0]}[url=${url}]${urlText}[/url]${splits[1]}` } else { scope.contentModel = `${splits[0]}[url=${url}][/url]${splits[1]}` @@ -195,16 +194,16 @@ export default } - modal.addTextStyleTagToText = function(tag) { + modal.addTextStyleTagToText = function (tag) { const selectorId = this.id const selectionStart = document.getElementById(selectorId).selectionStart const content = document.getElementById(selectorId).value - const splits = [content.slice(0,selectionStart),content.slice(selectionStart)] + const splits = [content.slice(0, selectionStart), content.slice(selectionStart)] console.log(splits) const openTag = `[${tag}]` const closeTag = `[/${tag}]` - if(tag == 'hr'){ + if (tag == 'hr') { scope.contentModel = `${splits[0]}${openTag}${splits[1]}` } else { scope.contentModel = `${splits[0]}${openTag}${closeTag}${splits[1]}` @@ -217,18 +216,17 @@ export default const elem = document.getElementById(selectorId) elem.focus() $timeout(() => { - elem.setSelectionRange(nselectionStart,nselectionStart) - },200) + elem.setSelectionRange(nselectionStart, nselectionStart) + }, 200) }) }) - } - modal.addFontSizeTagToText = function(size) { + modal.addFontSizeTagToText = function (size) { const selectorId = this.id const selectionStart = document.getElementById(selectorId).selectionStart const content = document.getElementById(selectorId).value - const splits = [content.slice(0,selectionStart),content.slice(selectionStart)] + const splits = [content.slice(0, selectionStart), content.slice(selectionStart)] const openTag = `[size=${size}]` const closeTag = `[/size]` @@ -242,27 +240,27 @@ export default elem.focus() $timeout(() => { - elem.setSelectionRange(nselectionStart,nselectionStart) - },200) + elem.setSelectionRange(nselectionStart, nselectionStart) + }, 200) }) }) } - modal.addGifCodeToText = function(code) { + modal.addGifCodeToText = function (code) { const selectorId = this.id const selectionStart = document.getElementById(selectorId).selectionStart const content = document.getElementById(selectorId).value - const splits = [content.slice(0,selectionStart),content.slice(selectionStart)] + const splits = [content.slice(0, selectionStart), content.slice(selectionStart)] scope.contentModel = `${splits[0]} ${code} ${splits[1]}` } - modal.addImageUrlToText = function(imageUrl) { + modal.addImageUrlToText = function (imageUrl) { const selectorId = this.id const selectionStart = document.getElementById(selectorId).selectionStart const content = document.getElementById(selectorId).value - const splits = [content.slice(0,selectionStart),content.slice(selectionStart)] + const splits = [content.slice(0, selectionStart), content.slice(selectionStart)] scope.contentModel = `${splits[0]}[img]${imageUrl}[/img]${splits[1]}` scope.imageUrl = undefined @@ -277,20 +275,20 @@ export default } }) // Customize from https://gist.github.com/BobNisco/9885852 - .directive('onLongPress', function($timeout) { + .directive('onLongPress', function ($timeout) { return { restrict: 'A', - link: function($scope, $elm, $attrs) { - $elm.bind('touchstart', function(evt) { + link: function ($scope, $elm, $attrs) { + $elm.bind('touchstart', function (evt) { // Locally scoped variable that will keep track of the long press $scope.longPress = true; // We'll set a timeout for 600 ms for a long press - $timeout(function() { + $timeout(function () { if ($scope.longPress) { // If the touchend event hasn't fired, // apply the function given in on the element's on-long-press attribute - $scope.$apply(function() { + $scope.$apply(function () { $scope.$eval($attrs.onLongPress) }); @@ -299,11 +297,11 @@ export default }, 600); }); - $elm.bind('touchend', function(evt) { - if(!$scope.triggeredLongPress){ + $elm.bind('touchend', function (evt) { + if (!$scope.triggeredLongPress) { // no long press is triggered, show try to trigger short press - if ($attrs.onShortPress){ - $scope.$apply(function() { + if ($attrs.onShortPress) { + $scope.$apply(function () { $scope.$eval($attrs.onShortPress) }); } @@ -315,7 +313,7 @@ export default $scope.longPress = false; // If there is an on-touch-end function attached to this element, apply it if ($attrs.onTouchEnd) { - $scope.$apply(function() { + $scope.$apply(function () { $scope.$eval($attrs.onTouchEnd) }); } @@ -324,21 +322,146 @@ export default }; }) .directive('onLongerThanScreen', function ($window, $document, $timeout) { + return { + restrict: 'A', + link: function ($scope, $elm, $attrs) { + const screenHeight = $window.innerHeight + $timeout(() => { + const height = $elm[0].clientHeight + if (height > screenHeight) { + + console.log(`onLongerThanScreen, elementHeight ${height} > ${screenHeight}`) + + $scope.$apply(function () { + $scope.$eval($attrs.onLongerThanScreen) + }); + } + }) + } + } + }) + .directive('onLongerThanScreen', function ($window, $document, $timeout) { + return { + restrict: 'A', + link: function ($scope, $elm, $attrs) { + const screenHeight = $window.innerHeight + $timeout(() => { + const height = $elm[0].clientHeight + if (height > screenHeight) { + + console.log(`onLongerThanScreen, elementHeight ${height} > ${screenHeight}`) + + $scope.$apply(function () { + $scope.$eval($attrs.onLongerThanScreen) + }); + } + }) + } + } + }) + .directive('lazyScroll', ['$rootScope', + function ($rootScope) { return { - restrict: 'A', - link: function ($scope, $elm, $attrs) { - const screenHeight = $window.innerHeight - $timeout(() => { - const height = $elm[0].clientHeight - if(height > screenHeight){ + restrict: 'A', + link: function ($scope, $element) { + var origEvent = $scope.$onScroll; + $scope.$onScroll = function () { + $rootScope.$broadcast('lazyScrollEvent'); + + if (typeof origEvent === 'function') { + origEvent(); + } + }; + } + }; + }]) + + .directive('imageLazySrc', ['$document', '$timeout', '$ionicScrollDelegate', '$compile', + function ($document, $timeout, $ionicScrollDelegate, $compile) { + return { + restrict: 'A', + scope: { + lazyScrollResize: "@lazyScrollResize", + imageLazyBackgroundImage: "@imageLazyBackgroundImage", + imageLazySrc: "@" + }, + link: function ($scope, $element, $attributes) { + const imageLazyDistanceFromBottomToLoad = $attributes.imageLazyDistanceFromBottomToLoad + ? parseInt($attributes.imageLazyDistanceFromBottomToLoad) + : 0 + + let loader; + let isLoaded = false + + const deregistration = $scope.$on('lazyScrollEvent', function () { + console.log('scroll'); + if (isInView()) { + loadImage(); + } + + if(isLoaded){ + deregistration(); + } + } + ); - console.log(`onLongerThanScreen, elementHeight ${height} > ${screenHeight}`) + function loadImage() { + if(!loader){ + loader = $compile(`
`)($scope); + $element.after(loader); + } - $scope.$apply(function() { - $scope.$eval($attrs.onLongerThanScreen) - }); + //Bind "load" event + $element.bind("load", function (e) { + if (loader) { + loader.remove(); + } + isLoaded = true + $element.unbind("load"); + }); + + if ($scope.imageLazyBackgroundImage == "true") { + const bgImg = new Image(); + bgImg.onload = function () { + if (loader) { + loader.remove(); } - }) + $element[0].style.backgroundImage = 'url(' + $attributes.imageLazySrc + ')'; // set style attribute on element (it will load image) + }; + bgImg.src = $attributes.imageLazySrc; + } else { + $element[0].src = $attributes.imageLazySrc; // set src attribute on element (it will load image) + } } - } - }); + + function isInView() { + const clientHeight = $document[0].documentElement.clientHeight; + const imageRect = $element[0].getBoundingClientRect(); + return (imageRect.top >= 0 && imageRect.top <= clientHeight + imageLazyDistanceFromBottomToLoad) + } + + // bind listener + // listenerRemover = scrollAndResizeListener.bindListener(isInView); + + // unbind event listeners if element was destroyed + // it happens when you change view, etc + $element.on('$destroy', function () { + deregistration(); + }); + + // explicitly call scroll listener (because, some images are in viewport already and we haven't scrolled yet) + $timeout(function () { + if (isInView()) { + loadImage(); + } + }); + } + }; + }]) + .directive('irSpinner', function () { + return { + restrict: 'E', + template: `
` + + }; + }); \ No newline at end of file diff --git a/src/es6/core/model/general-html.js b/src/es6/core/model/general-html.js index e3eaedac..e70cf7eb 100644 --- a/src/es6/core/model/general-html.js +++ b/src/es6/core/model/general-html.js @@ -88,7 +88,6 @@ export class GeneralHtml{ if(imgSrc && !imgSrc.endsWith('.gif')){ elm.attr('image-lazy-src', imgSrc) elm.attr('image-lazy-distance-from-bottom-to-load',"0") - elm.attr('image-lazy-loader',"android") elm.removeAttr('src') elm.removeAttr('alt') elm.attr('ng-click',`vm.openImage('${uid}', '${imgSrc}')`) diff --git a/src/es6/core/model/hkepc-html.js b/src/es6/core/model/hkepc-html.js index eec031d8..ade5c508 100644 --- a/src/es6/core/model/hkepc-html.js +++ b/src/es6/core/model/hkepc-html.js @@ -3,7 +3,6 @@ */ import {GeneralHtml} from './general-html' import * as URLUtils from '../../utils/url' -const cheerio = require('cheerio') export class HKEPCHtml extends GeneralHtml{ diff --git a/src/es6/data/config/hkepc.js b/src/es6/data/config/hkepc.js index 72b32c7e..415daa8f 100644 --- a/src/es6/data/config/hkepc.js +++ b/src/es6/data/config/hkepc.js @@ -5,7 +5,7 @@ const PROXY_URL = 'https://ionic-reader.xyz' const BASE_URL = `https://www.hkepc.com` const BASE_FORUM_URL = `${BASE_URL}/forum` const IMAGE_URL = 'https://www.hkepc.com/forum' -const VERSION = "3.0.0" +const VERSION = "3.1.0" function getMobileOperatingSystem(userAgent){ const ua = userAgent || navigator.userAgent || navigator.vendor || window.opera; diff --git a/src/scss/global.scss b/src/scss/global.scss index 9b21a459..d6408e83 100644 --- a/src/scss/global.scss +++ b/src/scss/global.scss @@ -342,4 +342,9 @@ textarea { .custom-svg-fill { fill: $epc-color; +} + +ion-infinite-scroll { + position: absolute; + height: 50px; } \ No newline at end of file diff --git a/src/scss/spinner.scss b/src/scss/spinner.scss index b4c2337a..3838982b 100644 --- a/src/scss/spinner.scss +++ b/src/scss/spinner.scss @@ -9,6 +9,51 @@ div{ } } +ir-spinner { + @-webkit-keyframes ir-rotate-loading { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + + @keyframes ir-rotate-loading { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + + display: flex; + justify-content: center; + align-items: center; + + .icon { + display: flex; + width: 25px; + height: 25px; + border: 2px solid transparent; + border-left-color: $epc-color; + border-right-color: $epc-color; + margin: 5px; + padding: 0; + border-radius: 100%; + background-color: transparent !important; + color: transparent; + cursor: default; + box-sizing: border-box; + -webkit-animation: ir-rotate-loading 1.5s linear 0s infinite normal; + animation: ir-rotate-loading 1.5s linear 0s infinite normal; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + +} + // infinity spinner .ispinner { .spinner { diff --git a/src/scss/topics/card.view.scss b/src/scss/topics/card.view.scss index b94bb293..10114ab9 100644 --- a/src/scss/topics/card.view.scss +++ b/src/scss/topics/card.view.scss @@ -27,9 +27,12 @@ padding: 0 20px; } + .f5-button, .page-divider, .card { + margin: 15px 0 0 0; + } + .card { background-color: $card-bg-color; - margin: 15px 0; .card-button{ color: $tab-item-stoke-color; diff --git a/www/index.android.dark.html b/www/index.android.dark.html index 5b035306..89a19a18 100644 --- a/www/index.android.dark.html +++ b/www/index.android.dark.html @@ -16,7 +16,6 @@ - diff --git a/www/index.android.html b/www/index.android.html index 621f402c..946ea962 100644 --- a/www/index.android.html +++ b/www/index.android.html @@ -16,7 +16,6 @@ - diff --git a/www/index.dark.html b/www/index.dark.html index 4f88512e..213d682d 100644 --- a/www/index.dark.html +++ b/www/index.dark.html @@ -16,7 +16,6 @@ - diff --git a/www/index.html b/www/index.html index 6dea274e..2d3563fa 100644 --- a/www/index.html +++ b/www/index.html @@ -16,7 +16,6 @@ - diff --git a/www/index.ios.dark.html b/www/index.ios.dark.html index ba7a1340..02f21874 100644 --- a/www/index.ios.dark.html +++ b/www/index.ios.dark.html @@ -16,7 +16,6 @@ - diff --git a/www/index.ios.html b/www/index.ios.html index 63405114..35e49fcc 100644 --- a/www/index.ios.html +++ b/www/index.ios.html @@ -16,7 +16,6 @@ - diff --git a/www/lib/ionic/js/ionic-angular.js b/www/lib/ionic/js/ionic-angular.js index e7bdde58..c9cd1e7e 100644 --- a/www/lib/ionic/js/ionic-angular.js +++ b/www/lib/ionic/js/ionic-angular.js @@ -5680,7 +5680,8 @@ IonicModule '$attrs', '$element', '$timeout', -function($scope, $attrs, $element, $timeout) { + '$compile', +function($scope, $attrs, $element, $timeout, $compile) { var self = this; self.isLoading = false; @@ -5703,19 +5704,29 @@ function($scope, $attrs, $element, $timeout) { } }); + let loader; + // debounce checking infinite scroll events - self.checkBounds = ionic.Utils.throttle(checkInfiniteBounds, 300); + self.checkBounds = ionic.Utils.throttle(checkInfiniteBounds, 500); function onInfinite() { + loader = $compile(`
`)($scope); + ionic.requestAnimationFrame(function() { + $element.after(loader); $element[0].classList.add('active'); + + $timeout(() => { + $scope.$parent && $scope.$parent.$apply($attrs.onInfinite || ''); + }) + }); self.isLoading = true; - $scope.$parent && $scope.$parent.$apply($attrs.onInfinite || ''); } function finishInfiniteScroll() { ionic.requestAnimationFrame(function() { + if(loader) loader.remove() $element[0].classList.remove('active'); }); $timeout(function() { @@ -10603,10 +10614,6 @@ IonicModule return { restrict: 'E', require: ['?^$ionicScroll', 'ionInfiniteScroll'], - template: function($element, $attrs) { - if ($attrs.icon) return ''; - return ''; - }, scope: true, controller: '$ionInfiniteScroll', link: function($scope, $element, $attrs, ctrls) { diff --git a/www/templates/about/version.html b/www/templates/about/version.html index 6bc3476e..882e8b69 100644 --- a/www/templates/about/version.html +++ b/www/templates/about/version.html @@ -1,10 +1,7 @@
- - +
diff --git a/www/templates/edit-post.html b/www/templates/edit-post.html index 675cd6bf..27567b78 100644 --- a/www/templates/edit-post.html +++ b/www/templates/edit-post.html @@ -29,7 +29,7 @@
- +