a zip code crypto-currency system good for red ONLY

refresher.js 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. (function (factory) {
  2. if (typeof module === "object" && typeof module.exports === "object") {
  3. var v = factory(require, exports);
  4. if (v !== undefined) module.exports = v;
  5. }
  6. else if (typeof define === "function" && define.amd) {
  7. define(["require", "exports", "@angular/core", "../content/content", "../../gestures/gesture-controller", "../../util/util", "../../platform/platform", "../../util/dom", "../../gestures/ui-event-manager"], factory);
  8. }
  9. })(function (require, exports) {
  10. "use strict";
  11. Object.defineProperty(exports, "__esModule", { value: true });
  12. var core_1 = require("@angular/core");
  13. var content_1 = require("../content/content");
  14. var gesture_controller_1 = require("../../gestures/gesture-controller");
  15. var util_1 = require("../../util/util");
  16. var platform_1 = require("../../platform/platform");
  17. var dom_1 = require("../../util/dom");
  18. var ui_event_manager_1 = require("../../gestures/ui-event-manager");
  19. /**
  20. * @name Refresher
  21. * @description
  22. * The Refresher provides pull-to-refresh functionality on a content component.
  23. * Place the `ion-refresher` as the first child of your `ion-content` element.
  24. *
  25. * Pages can then listen to the refresher's various output events. The
  26. * `refresh` output event is fired when the user has pulled down far
  27. * enough to kick off the refreshing process. Once the async operation
  28. * has completed and the refreshing should end, call `complete()`.
  29. *
  30. * Note: Do not wrap the `ion-refresher` in a `*ngIf`. It will not render
  31. * properly this way. Please use the `enabled` property instead to
  32. * display or hide the refresher.
  33. *
  34. * @usage
  35. * ```html
  36. * <ion-content>
  37. *
  38. * <ion-refresher (ionRefresh)="doRefresh($event)">
  39. * <ion-refresher-content></ion-refresher-content>
  40. * </ion-refresher>
  41. *
  42. * </ion-content>
  43. * ```
  44. *
  45. * ```ts
  46. * @Component({...})
  47. * export class NewsFeedPage {
  48. *
  49. * doRefresh(refresher) {
  50. * console.log('Begin async operation', refresher);
  51. *
  52. * setTimeout(() => {
  53. * console.log('Async operation has ended');
  54. * refresher.complete();
  55. * }, 2000);
  56. * }
  57. *
  58. * }
  59. * ```
  60. *
  61. *
  62. * ## Refresher Content
  63. *
  64. * By default, Ionic provides the pulling icon and refreshing spinner that
  65. * looks best for the platform the user is on. However, you can change the
  66. * default icon and spinner, along with adding text for each state by
  67. * adding properties to the child `ion-refresher-content` component.
  68. *
  69. * ```html
  70. * <ion-content>
  71. *
  72. * <ion-refresher (ionRefresh)="doRefresh($event)">
  73. * <ion-refresher-content
  74. * pullingIcon="arrow-dropdown"
  75. * pullingText="Pull to refresh"
  76. * refreshingSpinner="circles"
  77. * refreshingText="Refreshing...">
  78. * </ion-refresher-content>
  79. * </ion-refresher>
  80. *
  81. * </ion-content>
  82. * ```
  83. *
  84. *
  85. * ## Further Customizing Refresher Content
  86. *
  87. * The `ion-refresher` component holds the refresh logic.
  88. * It requires a child component in order to display the content.
  89. * Ionic uses `ion-refresher-content` by default. This component
  90. * displays the refresher and changes the look depending
  91. * on the refresher's state. Separating these components
  92. * allows developers to create their own refresher content
  93. * components. You could replace our default content with
  94. * custom SVG or CSS animations.
  95. *
  96. * @demo /docs/demos/src/refresher/
  97. *
  98. */
  99. var Refresher = (function () {
  100. function Refresher(_plt, _content, _zone, gestureCtrl) {
  101. this._plt = _plt;
  102. this._content = _content;
  103. this._zone = _zone;
  104. this._appliedStyles = false;
  105. this._lastCheck = 0;
  106. this._isEnabled = true;
  107. this._top = '';
  108. /**
  109. * The current state which the refresher is in. The refresher's states include:
  110. *
  111. * - `inactive` - The refresher is not being pulled down or refreshing and is currently hidden.
  112. * - `pulling` - The user is actively pulling down the refresher, but has not reached the point yet that if the user lets go, it'll refresh.
  113. * - `cancelling` - The user pulled down the refresher and let go, but did not pull down far enough to kick off the `refreshing` state. After letting go, the refresher is in the `cancelling` state while it is closing, and will go back to the `inactive` state once closed.
  114. * - `ready` - The user has pulled down the refresher far enough that if they let go, it'll begin the `refreshing` state.
  115. * - `refreshing` - The refresher is actively waiting on the async operation to end. Once the refresh handler calls `complete()` it will begin the `completing` state.
  116. * - `completing` - The `refreshing` state has finished and the refresher is in the process of closing itself. Once closed, the refresher will go back to the `inactive` state.
  117. */
  118. this.state = STATE_INACTIVE;
  119. /**
  120. * The Y coordinate of where the user started to the pull down the content.
  121. */
  122. this.startY = null;
  123. /**
  124. * The current touch or mouse event's Y coordinate.
  125. */
  126. this.currentY = null;
  127. /**
  128. * The distance between the start of the pull and the current touch or
  129. * mouse event's Y coordinate.
  130. */
  131. this.deltaY = null;
  132. /**
  133. * A number representing how far down the user has pulled.
  134. * The number `0` represents the user hasn't pulled down at all. The
  135. * number `1`, and anything greater than `1`, represents that the user
  136. * has pulled far enough down that when they let go then the refresh will
  137. * happen. If they let go and the number is less than `1`, then the
  138. * refresh will not happen, and the content will return to it's original
  139. * position.
  140. */
  141. this.progress = 0;
  142. /**
  143. * @input {number} The min distance the user must pull down until the
  144. * refresher can go into the `refreshing` state. Default is `60`.
  145. */
  146. this.pullMin = 60;
  147. /**
  148. * @input {number} The maximum distance of the pull until the refresher
  149. * will automatically go into the `refreshing` state. By default, the pull
  150. * maximum will be the result of `pullMin + 60`.
  151. */
  152. this.pullMax = this.pullMin + 60;
  153. /**
  154. * @input {number} How many milliseconds it takes to close the refresher. Default is `280`.
  155. */
  156. this.closeDuration = 280;
  157. /**
  158. * @input {number} How many milliseconds it takes the refresher to to snap back to the `refreshing` state. Default is `280`.
  159. */
  160. this.snapbackDuration = 280;
  161. /**
  162. * @output {event} Emitted when the user lets go and has pulled down
  163. * far enough, which would be farther than the `pullMin`, then your refresh hander if
  164. * fired and the state is updated to `refreshing`. From within your refresh handler,
  165. * you must call the `complete()` method when your async operation has completed.
  166. */
  167. this.ionRefresh = new core_1.EventEmitter();
  168. /**
  169. * @output {event} Emitted while the user is pulling down the content and exposing the refresher.
  170. */
  171. this.ionPull = new core_1.EventEmitter();
  172. /**
  173. * @output {event} Emitted when the user begins to start pulling down.
  174. */
  175. this.ionStart = new core_1.EventEmitter();
  176. this._events = new ui_event_manager_1.UIEventManager(_plt);
  177. _content._hasRefresher = true;
  178. this._gesture = gestureCtrl.createGesture({
  179. name: gesture_controller_1.GESTURE_REFRESHER,
  180. priority: gesture_controller_1.GESTURE_PRIORITY_REFRESHER
  181. });
  182. }
  183. Object.defineProperty(Refresher.prototype, "enabled", {
  184. /**
  185. * @input {boolean} If the refresher is enabled or not. This should be used in place of an `ngIf`. Default is `true`.
  186. */
  187. get: function () {
  188. return this._isEnabled;
  189. },
  190. set: function (val) {
  191. this._isEnabled = util_1.isTrueProperty(val);
  192. this._setListeners(this._isEnabled);
  193. },
  194. enumerable: true,
  195. configurable: true
  196. });
  197. Refresher.prototype._onStart = function (ev) {
  198. // if multitouch then get out immediately
  199. if (ev.touches && ev.touches.length > 1) {
  200. return false;
  201. }
  202. if (this.state !== STATE_INACTIVE) {
  203. return false;
  204. }
  205. var scrollHostScrollTop = this._content.getContentDimensions().scrollTop;
  206. // if the scrollTop is greater than zero then it's
  207. // not possible to pull the content down yet
  208. if (scrollHostScrollTop > 0) {
  209. return false;
  210. }
  211. if (!this._gesture.canStart()) {
  212. return false;
  213. }
  214. var coord = dom_1.pointerCoord(ev);
  215. (void 0) /* console.debug */;
  216. if (this._content.contentTop > 0) {
  217. var newTop = this._content.contentTop + 'px';
  218. if (this._top !== newTop) {
  219. this._top = newTop;
  220. }
  221. }
  222. this.startY = this.currentY = coord.y;
  223. this.progress = 0;
  224. this.state = STATE_INACTIVE;
  225. return true;
  226. };
  227. Refresher.prototype._onMove = function (ev) {
  228. // this method can get called like a bazillion times per second,
  229. // so it's built to be as efficient as possible, and does its
  230. // best to do any DOM read/writes only when absolutely necessary
  231. var _this = this;
  232. // if multitouch then get out immediately
  233. if (ev.touches && ev.touches.length > 1) {
  234. return 1;
  235. }
  236. if (!this._gesture.canStart()) {
  237. return 0;
  238. }
  239. // do nothing if it's actively refreshing
  240. // or it's in the process of closing
  241. // or this was never a startY
  242. if (this.startY === null || this.state === STATE_REFRESHING || this.state === STATE_CANCELLING || this.state === STATE_COMPLETING) {
  243. return 2;
  244. }
  245. // if we just updated stuff less than 16ms ago
  246. // then don't check again, just chillout plz
  247. var now = Date.now();
  248. if (this._lastCheck + 16 > now) {
  249. return 3;
  250. }
  251. // remember the last time we checked all this
  252. this._lastCheck = now;
  253. // get the current pointer coordinates
  254. var coord = dom_1.pointerCoord(ev);
  255. this.currentY = coord.y;
  256. // it's now possible they could be pulling down the content
  257. // how far have they pulled so far?
  258. this.deltaY = (coord.y - this.startY);
  259. // don't bother if they're scrolling up
  260. // and have not already started dragging
  261. if (this.deltaY <= 0) {
  262. // the current Y is higher than the starting Y
  263. // so they scrolled up enough to be ignored
  264. this.progress = 0;
  265. if (this.state !== STATE_INACTIVE) {
  266. this._zone.run(function () {
  267. _this.state = STATE_INACTIVE;
  268. });
  269. }
  270. if (this._appliedStyles) {
  271. // reset the styles only if they were applied
  272. this._setCss(0, '', false, '');
  273. return 5;
  274. }
  275. return 6;
  276. }
  277. if (this.state === STATE_INACTIVE) {
  278. // this refresh is not already actively pulling down
  279. // get the content's scrollTop
  280. var scrollHostScrollTop = this._content.getContentDimensions().scrollTop;
  281. // if the scrollTop is greater than zero then it's
  282. // not possible to pull the content down yet
  283. if (scrollHostScrollTop > 0) {
  284. this.progress = 0;
  285. this.startY = null;
  286. return 7;
  287. }
  288. // content scrolled all the way to the top, and dragging down
  289. this.state = STATE_PULLING;
  290. }
  291. // prevent native scroll events
  292. ev.preventDefault();
  293. // the refresher is actively pulling at this point
  294. // move the scroll element within the content element
  295. this._setCss(this.deltaY, '0ms', true, '');
  296. if (!this.deltaY) {
  297. // don't continue if there's no delta yet
  298. this.progress = 0;
  299. return 8;
  300. }
  301. // so far so good, let's run this all back within zone now
  302. this._zone.run(function () {
  303. _this._onMoveInZone();
  304. });
  305. };
  306. Refresher.prototype._onMoveInZone = function () {
  307. // set pull progress
  308. this.progress = (this.deltaY / this.pullMin);
  309. // emit "start" if it hasn't started yet
  310. if (!this._didStart) {
  311. this._didStart = true;
  312. this.ionStart.emit(this);
  313. }
  314. // emit "pulling" on every move
  315. this.ionPull.emit(this);
  316. // do nothing if the delta is less than the pull threshold
  317. if (this.deltaY < this.pullMin) {
  318. // ensure it stays in the pulling state, cuz its not ready yet
  319. this.state = STATE_PULLING;
  320. return 2;
  321. }
  322. if (this.deltaY > this.pullMax) {
  323. // they pulled farther than the max, so kick off the refresh
  324. this._beginRefresh();
  325. return 3;
  326. }
  327. // pulled farther than the pull min!!
  328. // it is now in the `ready` state!!
  329. // if they let go then it'll refresh, kerpow!!
  330. this.state = STATE_READY;
  331. return 4;
  332. };
  333. Refresher.prototype._onEnd = function () {
  334. // only run in a zone when absolutely necessary
  335. var _this = this;
  336. if (this.state === STATE_READY) {
  337. this._zone.run(function () {
  338. // they pulled down far enough, so it's ready to refresh
  339. _this._beginRefresh();
  340. });
  341. }
  342. else if (this.state === STATE_PULLING) {
  343. this._zone.run(function () {
  344. // they were pulling down, but didn't pull down far enough
  345. // set the content back to it's original location
  346. // and close the refresher
  347. // set that the refresh is actively cancelling
  348. _this.cancel();
  349. });
  350. }
  351. // reset on any touchend/mouseup
  352. this.startY = null;
  353. };
  354. Refresher.prototype._beginRefresh = function () {
  355. // assumes we're already back in a zone
  356. // they pulled down far enough, so it's ready to refresh
  357. this.state = STATE_REFRESHING;
  358. // place the content in a hangout position while it thinks
  359. this._setCss(this.pullMin, (this.snapbackDuration + 'ms'), true, '');
  360. // emit "refresh" because it was pulled down far enough
  361. // and they let go to begin refreshing
  362. this.ionRefresh.emit(this);
  363. };
  364. /**
  365. * Call `complete()` when your async operation has completed.
  366. * For example, the `refreshing` state is while the app is performing
  367. * an asynchronous operation, such as receiving more data from an
  368. * AJAX request. Once the data has been received, you then call this
  369. * method to signify that the refreshing has completed and to close
  370. * the refresher. This method also changes the refresher's state from
  371. * `refreshing` to `completing`.
  372. */
  373. Refresher.prototype.complete = function () {
  374. this._close(STATE_COMPLETING, '120ms');
  375. };
  376. /**
  377. * Changes the refresher's state from `refreshing` to `cancelling`.
  378. */
  379. Refresher.prototype.cancel = function () {
  380. this._close(STATE_CANCELLING, '');
  381. };
  382. Refresher.prototype._close = function (state, delay) {
  383. var timer;
  384. function close(ev) {
  385. // closing is done, return to inactive state
  386. if (ev) {
  387. clearTimeout(timer);
  388. }
  389. this.state = STATE_INACTIVE;
  390. this.progress = 0;
  391. this._didStart = this.startY = this.currentY = this.deltaY = null;
  392. this._setCss(0, '0ms', false, '');
  393. }
  394. // create fallback timer incase something goes wrong with transitionEnd event
  395. timer = setTimeout(close.bind(this), 600);
  396. // create transition end event on the content's scroll element
  397. this._content.onScrollElementTransitionEnd(close.bind(this));
  398. // reset set the styles on the scroll element
  399. // set that the refresh is actively cancelling/completing
  400. this.state = state;
  401. this._setCss(0, '', true, delay);
  402. if (this._pointerEvents) {
  403. this._pointerEvents.stop();
  404. }
  405. };
  406. Refresher.prototype._setCss = function (y, duration, overflowVisible, delay) {
  407. this._appliedStyles = (y > 0);
  408. var content = this._content;
  409. var Css = this._plt.Css;
  410. content.setScrollElementStyle(Css.transform, ((y > 0) ? 'translateY(' + y + 'px) translateZ(0px)' : 'translateZ(0px)'));
  411. content.setScrollElementStyle(Css.transitionDuration, duration);
  412. content.setScrollElementStyle(Css.transitionDelay, delay);
  413. content.setScrollElementStyle('overflow', (overflowVisible ? 'hidden' : ''));
  414. };
  415. Refresher.prototype._setListeners = function (shouldListen) {
  416. this._events.unlistenAll();
  417. this._pointerEvents = null;
  418. if (shouldListen) {
  419. this._pointerEvents = this._events.pointerEvents({
  420. element: this._content.getScrollElement(),
  421. pointerDown: this._onStart.bind(this),
  422. pointerMove: this._onMove.bind(this),
  423. pointerUp: this._onEnd.bind(this),
  424. zone: false
  425. });
  426. }
  427. };
  428. /**
  429. * @hidden
  430. */
  431. Refresher.prototype.ngOnInit = function () {
  432. // bind event listeners
  433. // save the unregister listener functions to use onDestroy
  434. this._setListeners(this._isEnabled);
  435. };
  436. /**
  437. * @hidden
  438. */
  439. Refresher.prototype.ngOnDestroy = function () {
  440. this._setListeners(false);
  441. this._events.destroy();
  442. this._gesture.destroy();
  443. };
  444. Refresher.decorators = [
  445. { type: core_1.Directive, args: [{
  446. selector: 'ion-refresher',
  447. host: {
  448. '[class.refresher-active]': 'state !== "inactive"',
  449. '[style.top]': '_top'
  450. }
  451. },] },
  452. ];
  453. /** @nocollapse */
  454. Refresher.ctorParameters = function () { return [
  455. { type: platform_1.Platform, },
  456. { type: content_1.Content, decorators: [{ type: core_1.Host },] },
  457. { type: core_1.NgZone, },
  458. { type: gesture_controller_1.GestureController, },
  459. ]; };
  460. Refresher.propDecorators = {
  461. 'pullMin': [{ type: core_1.Input },],
  462. 'pullMax': [{ type: core_1.Input },],
  463. 'closeDuration': [{ type: core_1.Input },],
  464. 'snapbackDuration': [{ type: core_1.Input },],
  465. 'enabled': [{ type: core_1.Input },],
  466. 'ionRefresh': [{ type: core_1.Output },],
  467. 'ionPull': [{ type: core_1.Output },],
  468. 'ionStart': [{ type: core_1.Output },],
  469. };
  470. return Refresher;
  471. }());
  472. exports.Refresher = Refresher;
  473. var STATE_INACTIVE = 'inactive';
  474. var STATE_PULLING = 'pulling';
  475. var STATE_READY = 'ready';
  476. var STATE_REFRESHING = 'refreshing';
  477. var STATE_CANCELLING = 'cancelling';
  478. var STATE_COMPLETING = 'completing';
  479. });
  480. //# sourceMappingURL=refresher.js.map