All files / src BaseExpiryIcon.vue.js

3.84% Statements 1/26
0% Branches 0/16
0% Functions 0/8
3.84% Lines 1/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                    1x                                                                                                                                                    
// @ts-check
import { select } from "d3-selection";
import "d3-transition"; // load the plugin
import Vue from "vue";
 
/**
 * @typedef {import('d3-selection').BaseType} BaseType
 * @typedef {import('d3-selection').Selection<BaseType, BaseType, HTMLElement, any>} Selection
 */
 
const component = /** @type {V.Constructor<any, any> } */ (Vue).extend({
  name: "BaseExpiryIcon",
  props: {
    expiry: { type: Number, default: NaN },
    color: { type: String, default: "#545b62" }
  },
  /**
   * @return {{
   *   start: number,
   *   selection?: Selection
   * }}
   */
  data() { return { start: Date.now(), selection: undefined }; },
  computed: {
    /**
     * @return {string}
     */
    tooltip() {
      return (Number.isNaN(this.expiry)) ? "never" : (new Date(this.expiry)).toISOString();
    }
  },
  watch: {
    expiry() {
      this.restart();
    }
  },
  mounted() {
    // @ts-ignore I do not get this. select wants a string. What are we doing?
    this.selection = select(this.$refs.circle);
    this.restart();
  },
  beforeDestroy() {
    if (this.selection) {
      this.selection.interrupt();
    }
  },
  methods: {
    restart() {
      this.start = Date.now();
      this.update();
    },
    update() {
      const now = Date.now();
      if (this.selection && Number.isNaN(this.expiry)) {
        this.selection.interrupt().attr("stroke-dashoffset", 0);
      }
      else if (this.selection && now > this.expiry + 200) { // take rollback animation in account
        this.selection.interrupt().attr("stroke-dashoffset", 805);
      }
      else {
        let remain = this.expiry - now;
        const range = (this.expiry - this.start);
        const position = ((range - remain) / range) * 804;
        if (this.selection) {
          this.selection.interrupt()
          .transition()
          .call((transition) => {
            const current = (transition.selection().attr("stroke-dashoffset"));
            // @ts-ignore they're numbers here
            if ((current - position) > 10) {
              transition.duration(200)
              .attr("stroke-dashoffset", position);
              transition = transition.transition();
              remain -= 200;
            }
            transition.duration(remain)
            .attr("stroke-dashoffset", 805);
          });
        }
      }
    }
  }
});
export default component;