<commit_before>import Vue from 'vue'

import QField from '../field/QField.js'

import { FormFieldMixin } from '../../mixins/form.js'
import { FileValueMixin } from '../../mixins/file.js'
import MaskMixin from '../../mixins/mask.js'
import CompositionMixin from '../../mixins/composition.js'
import ListenersMixin from '../../mixins/listeners.js'

import { stop } from '../../utils/event.js'
import { addFocusFn } from '../../utils/focus-manager.js'

export default Vue.extend({
  name: 'QInput',

  mixins: [
    QField,
    MaskMixin,
    CompositionMixin,
    FormFieldMixin,
    FileValueMixin,
    ListenersMixin
  ],

  props: {
    value: { required: false },

    shadowText: String,

    type: {
      type: String,
      default: 'text'
    },

    debounce: [String, Number],

    autogrow: Boolean, // makes a textarea

    inputClass: [Array, String, Object],
    inputStyle: [Array, String, Object]
  },

  watch: {
    value (v) {
      if (this.hasMask === true) {
        if (this.stopValueWatcher === true) {
          this.stopValueWatcher = false
          return
        }

        this.__updateMaskValue(v)
      }
      else if (this.innerValue !== v) {
        this.innerValue = v

        if (
          this.type === 'number' &&
          this.hasOwnProperty('tempValue') === true
        ) {
          if (this.typedNumber === true) {
            this.typedNumber = false
          }
          else {
            delete this.tempValue
          }
        }
      }

      // textarea only
      this.autogrow === true && this.$nextTick(this.__adjustHeight)
    },

    // some browsers lose the native input value
    // so we need to reattach it dynamically
    // (like type="password" <-> type="text"; see #12078)
    type () {
      if (this.$refs.input) {
        this.$refs.input.value = this.value
      }
    },

    autogrow (autogrow) {
      // textarea only
      if (autogrow === true) {
        this.$nextTick(this.__adjustHeight)
      }
      // if it has a number of rows set respect it
      else if (this.qAttrs.rows > 0 && this.$refs.input !== void 0) {
        const inp = this.$refs.input
        inp.style.height = 'auto'
      }
    },

    dense () {
      this.autogrow === true && this.$nextTick(this.__adjustHeight)
    }
  },

  data () {
    return { innerValue: this.__getInitialMaskedValue() }
  },

  computed: {
    isTextarea () {
      return this.type === 'textarea' || this.autogrow === true
    },

    isTypeText () {
      return this.isTextarea === true || ['text', 'search', 'url', 'tel', 'password'].includes(this.type)
    },

    fieldClass () {
      return `q-${this.isTextarea === true ? 'textarea' : 'input'}` +
        (this.autogrow === true ? ' q-textarea--autogrow' : '')
    },

    hasShadow () {
      return this.type !== 'file' &&
        typeof this.shadowText === 'string' &&
        this.shadowText.length > 0
    },

    onEvents () {
      const on = {
        ...this.qListeners,
        input: this.__onInput,
        paste: this.__onPaste,
        // Safari < 10.2 & UIWebView doesn't fire compositionend when
        // switching focus before confirming composition choice
        // this also fixes the issue where some browsers e.g. iOS Chrome
        // fires "change" instead of "input" on autocomplete.
        change: this.__onChange,
        blur: this.__onFinishEditing,
        focus: stop
      }

      on.compositionstart = on.compositionupdate = on.compositionend = this.__onComposition

      if (this.hasMask === true) {
        on.keydown = this.__onMaskedKeydown
      }

      if (this.autogrow === true) {
        on.animationend = this.__adjustHeight
      }

      return on
    },

    inputAttrs () {
      const attrs = {
        tabindex: 0,
        'data-autofocus': this.autofocus,
        rows: this.type === 'textarea' ? 6 : void 0,
        'aria-label': this.label,
        name: this.nameProp,
        ...this.qAttrs,
        id: this.targetUid,
        type: this.type,
        maxlength: this.maxlength,
        disabled: this.disable === true,
        readonly: this.readonly === true
      }

      if (this.autogrow === true) {
        attrs.rows = 1
      }

      return attrs
    }
  },

  methods: {
    focus () {
      addFocusFn(() => {
        const el = document.activeElement
        if (
          this.$refs.input !== void 0 &&
          this.$refs.input !== el &&
          // IE can have null document.activeElement
          (el === null || el.id !== this.targetUid)
        ) {
          this.$refs.input.focus({ preventScroll: true })
        }
      })
    },

    select () {
      this.$refs.input !== void 0 && this.$refs.input.select()
    },

    getNativeElement () {
      return this.$refs.input
    },

    __onPaste (e) {
      if (this.hasMask === true && this.reverseFillMask !== true) {
        const inp = e.target
        this.__moveCursorForPaste(inp, inp.selectionStart, inp.selectionEnd)
      }

      this.$emit('paste', e)
    },

    __onInput (e) {
      if (!e || !e.target || e.target.composing === true) {
        return
      }

      if (this.type === 'file') {
        this.$emit('input', e.target.files)
        return
      }

      const val = e.target.value

      if (this.hasMask === true) {
        this.__updateMaskValue(val, false, e.inputType)
      }
      else {
        this.__emitValue(val)

        if (this.isTypeText === true && e.target === document.activeElement) {
          const { selectionStart, selectionEnd } = e.target

          if (selectionStart !== void 0 && selectionEnd !== void 0) {
            this.$nextTick(() => {
              if (e.target === document.activeElement && val.indexOf(e.target.value) === 0) {
                e.target.setSelectionRange(selectionStart, selectionEnd)
              }
            })
          }
        }
      }

      // we need to trigger it immediately too,
      // to avoid "flickering"
      this.autogrow === true && this.__adjustHeight()
    },

    __emitValue (val, stopWatcher) {
      this.emitValueFn = () => {
        if (
          this.type !== 'number' &&
          this.hasOwnProperty('tempValue') === true
        ) {
          delete this.tempValue
        }

        if (this.value !== val && this.emitCachedValue !== val) {
          this.emitCachedValue = val

          stopWatcher === true && (this.stopValueWatcher = true)
          this.$emit('input', val)

          this.$nextTick(() => {
            this.emitCachedValue === val && (this.emitCachedValue = NaN)
          })
        }

        this.emitValueFn = void 0
      }

      if (this.type === 'number') {
        this.typedNumber = true
        this.tempValue = val
      }

      if (this.debounce !== void 0) {
        clearTimeout(this.emitTimer)
        this.tempValue = val
        this.emitTimer = setTimeout(this.emitValueFn, this.debounce)
      }
      else {
        this.emitValueFn()
      }
    },

    // textarea only
    __adjustHeight () {
      const inp = this.$refs.input
      if (inp !== void 0) {
        const parentStyle = inp.parentNode.style

        // reset height of textarea to a small size to detect the real height
        // but keep the total control size the same
        parentStyle.marginBottom = (inp.scrollHeight - 1) + 'px'
        inp.style.height = '1px'

        inp.style.height = inp.scrollHeight + 'px'
        parentStyle.marginBottom = ''
      }
    },

    __onChange (e) {
      this.__onComposition(e)

      clearTimeout(this.emitTimer)
      this.emitValueFn !== void 0 && this.emitValueFn()

      this.$emit('change', e)
    },

    __onFinishEditing (e) {
      e !== void 0 && stop(e)

      clearTimeout(this.emitTimer)
      this.emitValueFn !== void 0 && this.emitValueFn()

      this.typedNumber = false
      this.stopValueWatcher = false
      delete this.tempValue

      // we need to use setTimeout instead of this.$nextTick
      // to avoid a bug where focusout is not emitted for type date/time/week/...
      this.type !== 'file' && setTimeout(() => {
        if (this.$refs.input !== void 0) {
          this.$refs.input.value = this.innerValue !== void 0 ? this.innerValue : ''
        }
      })
    },

    __getCurValue () {
      return this.hasOwnProperty('tempValue') === true
        ? this.tempValue
        : (this.innerValue !== void 0 ? this.innerValue : '')
    },

    __getShadowControl (h) {
      return h('div', {
        staticClass: 'q-field__native q-field__shadow absolute-bottom no-pointer-events' +
          (this.isTextarea === true ? '' : ' text-no-wrap')
      }, [
        h('span', { staticClass: 'invisible' }, this.__getCurValue()),
        h('span', this.shadowText)
      ])
    },

    __getControl (h) {
      return h(this.isTextarea === true ? 'textarea' : 'input', {
        ref: 'input',
        staticClass: 'q-field__native q-placeholder',
        style: this.inputStyle,
        class: this.inputClass,
        attrs: this.inputAttrs,
        on: this.onEvents,
        domProps: this.type !== 'file'
          ? { value: this.__getCurValue() }
          : this.formDomProps
      })
    }
  },

  created () {
    this.emitCachedValue = NaN
  },

  mounted () {
    // textarea only
    this.autogrow === true && this.__adjustHeight()
  },

  beforeDestroy () {
    this.__onFinishEditing()
  }
})
<commit_msg>fix(QInput): update internal value if using mask and external value is changed from the cached one #12638 (#12723)<commit_after>import Vue from 'vue'

import QField from '../field/QField.js'

import { FormFieldMixin } from '../../mixins/form.js'
import { FileValueMixin } from '../../mixins/file.js'
import MaskMixin from '../../mixins/mask.js'
import CompositionMixin from '../../mixins/composition.js'
import ListenersMixin from '../../mixins/listeners.js'

import { stop } from '../../utils/event.js'
import { addFocusFn } from '../../utils/focus-manager.js'

export default Vue.extend({
  name: 'QInput',

  mixins: [
    QField,
    MaskMixin,
    CompositionMixin,
    FormFieldMixin,
    FileValueMixin,
    ListenersMixin
  ],

  props: {
    value: { required: false },

    shadowText: String,

    type: {
      type: String,
      default: 'text'
    },

    debounce: [String, Number],

    autogrow: Boolean, // makes a textarea

    inputClass: [Array, String, Object],
    inputStyle: [Array, String, Object]
  },

  watch: {
    value (v) {
      if (this.hasMask === true) {
        if (this.stopValueWatcher === true) {
          this.stopValueWatcher = false

          if (String(v) === this.emitCachedValue) {
            return
          }
        }

        this.__updateMaskValue(v)
      }
      else if (this.innerValue !== v) {
        this.innerValue = v

        if (
          this.type === 'number' &&
          this.hasOwnProperty('tempValue') === true
        ) {
          if (this.typedNumber === true) {
            this.typedNumber = false
          }
          else {
            delete this.tempValue
          }
        }
      }

      // textarea only
      this.autogrow === true && this.$nextTick(this.__adjustHeight)
    },

    // some browsers lose the native input value
    // so we need to reattach it dynamically
    // (like type="password" <-> type="text"; see #12078)
    type () {
      if (this.$refs.input) {
        this.$refs.input.value = this.value
      }
    },

    autogrow (autogrow) {
      // textarea only
      if (autogrow === true) {
        this.$nextTick(this.__adjustHeight)
      }
      // if it has a number of rows set respect it
      else if (this.qAttrs.rows > 0 && this.$refs.input !== void 0) {
        const inp = this.$refs.input
        inp.style.height = 'auto'
      }
    },

    dense () {
      this.autogrow === true && this.$nextTick(this.__adjustHeight)
    }
  },

  data () {
    return { innerValue: this.__getInitialMaskedValue() }
  },

  computed: {
    isTextarea () {
      return this.type === 'textarea' || this.autogrow === true
    },

    isTypeText () {
      return this.isTextarea === true || ['text', 'search', 'url', 'tel', 'password'].includes(this.type)
    },

    fieldClass () {
      return `q-${this.isTextarea === true ? 'textarea' : 'input'}` +
        (this.autogrow === true ? ' q-textarea--autogrow' : '')
    },

    hasShadow () {
      return this.type !== 'file' &&
        typeof this.shadowText === 'string' &&
        this.shadowText.length > 0
    },

    onEvents () {
      const on = {
        ...this.qListeners,
        input: this.__onInput,
        paste: this.__onPaste,
        // Safari < 10.2 & UIWebView doesn't fire compositionend when
        // switching focus before confirming composition choice
        // this also fixes the issue where some browsers e.g. iOS Chrome
        // fires "change" instead of "input" on autocomplete.
        change: this.__onChange,
        blur: this.__onFinishEditing,
        focus: stop
      }

      on.compositionstart = on.compositionupdate = on.compositionend = this.__onComposition

      if (this.hasMask === true) {
        on.keydown = this.__onMaskedKeydown
      }

      if (this.autogrow === true) {
        on.animationend = this.__adjustHeight
      }

      return on
    },

    inputAttrs () {
      const attrs = {
        tabindex: 0,
        'data-autofocus': this.autofocus,
        rows: this.type === 'textarea' ? 6 : void 0,
        'aria-label': this.label,
        name: this.nameProp,
        ...this.qAttrs,
        id: this.targetUid,
        type: this.type,
        maxlength: this.maxlength,
        disabled: this.disable === true,
        readonly: this.readonly === true
      }

      if (this.autogrow === true) {
        attrs.rows = 1
      }

      return attrs
    }
  },

  methods: {
    focus () {
      addFocusFn(() => {
        const el = document.activeElement
        if (
          this.$refs.input !== void 0 &&
          this.$refs.input !== el &&
          // IE can have null document.activeElement
          (el === null || el.id !== this.targetUid)
        ) {
          this.$refs.input.focus({ preventScroll: true })
        }
      })
    },

    select () {
      this.$refs.input !== void 0 && this.$refs.input.select()
    },

    getNativeElement () {
      return this.$refs.input
    },

    __onPaste (e) {
      if (this.hasMask === true && this.reverseFillMask !== true) {
        const inp = e.target
        this.__moveCursorForPaste(inp, inp.selectionStart, inp.selectionEnd)
      }

      this.$emit('paste', e)
    },

    __onInput (e) {
      if (!e || !e.target || e.target.composing === true) {
        return
      }

      if (this.type === 'file') {
        this.$emit('input', e.target.files)
        return
      }

      const val = e.target.value

      if (this.hasMask === true) {
        this.__updateMaskValue(val, false, e.inputType)
      }
      else {
        this.__emitValue(val)

        if (this.isTypeText === true && e.target === document.activeElement) {
          const { selectionStart, selectionEnd } = e.target

          if (selectionStart !== void 0 && selectionEnd !== void 0) {
            this.$nextTick(() => {
              if (e.target === document.activeElement && val.indexOf(e.target.value) === 0) {
                e.target.setSelectionRange(selectionStart, selectionEnd)
              }
            })
          }
        }
      }

      // we need to trigger it immediately too,
      // to avoid "flickering"
      this.autogrow === true && this.__adjustHeight()
    },

    __emitValue (val, stopWatcher) {
      this.emitValueFn = () => {
        if (
          this.type !== 'number' &&
          this.hasOwnProperty('tempValue') === true
        ) {
          delete this.tempValue
        }

        if (this.value !== val && this.emitCachedValue !== val) {
          this.emitCachedValue = val

          stopWatcher === true && (this.stopValueWatcher = true)
          this.$emit('input', val)

          this.$nextTick(() => {
            this.emitCachedValue === val && (this.emitCachedValue = NaN)
          })
        }

        this.emitValueFn = void 0
      }

      if (this.type === 'number') {
        this.typedNumber = true
        this.tempValue = val
      }

      if (this.debounce !== void 0) {
        clearTimeout(this.emitTimer)
        this.tempValue = val
        this.emitTimer = setTimeout(this.emitValueFn, this.debounce)
      }
      else {
        this.emitValueFn()
      }
    },

    // textarea only
    __adjustHeight () {
      const inp = this.$refs.input
      if (inp !== void 0) {
        const parentStyle = inp.parentNode.style

        // reset height of textarea to a small size to detect the real height
        // but keep the total control size the same
        parentStyle.marginBottom = (inp.scrollHeight - 1) + 'px'
        inp.style.height = '1px'

        inp.style.height = inp.scrollHeight + 'px'
        parentStyle.marginBottom = ''
      }
    },

    __onChange (e) {
      this.__onComposition(e)

      clearTimeout(this.emitTimer)
      this.emitValueFn !== void 0 && this.emitValueFn()

      this.$emit('change', e)
    },

    __onFinishEditing (e) {
      e !== void 0 && stop(e)

      clearTimeout(this.emitTimer)
      this.emitValueFn !== void 0 && this.emitValueFn()

      this.typedNumber = false
      this.stopValueWatcher = false
      delete this.tempValue

      // we need to use setTimeout instead of this.$nextTick
      // to avoid a bug where focusout is not emitted for type date/time/week/...
      this.type !== 'file' && setTimeout(() => {
        if (this.$refs.input !== void 0) {
          this.$refs.input.value = this.innerValue !== void 0 ? this.innerValue : ''
        }
      })
    },

    __getCurValue () {
      return this.hasOwnProperty('tempValue') === true
        ? this.tempValue
        : (this.innerValue !== void 0 ? this.innerValue : '')
    },

    __getShadowControl (h) {
      return h('div', {
        staticClass: 'q-field__native q-field__shadow absolute-bottom no-pointer-events' +
          (this.isTextarea === true ? '' : ' text-no-wrap')
      }, [
        h('span', { staticClass: 'invisible' }, this.__getCurValue()),
        h('span', this.shadowText)
      ])
    },

    __getControl (h) {
      return h(this.isTextarea === true ? 'textarea' : 'input', {
        ref: 'input',
        staticClass: 'q-field__native q-placeholder',
        style: this.inputStyle,
        class: this.inputClass,
        attrs: this.inputAttrs,
        on: this.onEvents,
        domProps: this.type !== 'file'
          ? { value: this.__getCurValue() }
          : this.formDomProps
      })
    }
  },

  created () {
    this.emitCachedValue = NaN
  },

  mounted () {
    // textarea only
    this.autogrow === true && this.__adjustHeight()
  },

  beforeDestroy () {
    this.__onFinishEditing()
  }
})
<|endoftext|>


<commit_before>/**
 * Created by ArunaTebel on 8/31/2015.
 */

var OfflinkJs = angular.module('OfflinkJs', ['LocalStorageModule']);
OfflinkJs.factory("ConnectionDetectorService", [function () {

    var conDetectFunction = URL.createObjectURL(new Blob(['(',
            function () {
                var conDetectURL = "";
                addEventListener('message', function (e) {
                    switch (e.data.msg) {
                        case 'REGISTER':
                            conDetectURL = e.data.url;
                            setInterval(detectConnectivity, 3000);
                            break;
                        case 'POLL':
                            return getConnectionStatus();
                            break;
                    }
                }, false);

                function detectConnectivity() {
                    var http = new XMLHttpRequest();
                    http.open('HEAD', conDetectURL);
                    http.onreadystatechange = function () {
                        if (this.readyState == this.DONE) {
                            connectionStatus = this.status;
                            self.postMessage(this.status);
                        }
                    };
                    if (conDetectURL != "") {
                        http.send();
                    }
                }
            }.toString(),

            ')()'], {type: 'application/javascript'})
    );

    var callbackFunc = null;
    var connectionStatus = "";

    var worker = new Worker(conDetectFunction);
    URL.revokeObjectURL(conDetectFunction);
    worker.addEventListener('message', function (e) {
        callbackFunc(e.data);
        connectionStatus = e.data;
    }, false);

    return {
        register: function (url, callback) {
            callbackFunc = callback;
            var msg = {
                msg: "REGISTER",
                url: url
            };
            worker.postMessage(msg);
        },
        getConnectionStatus: function () {
            return connectionStatus;
        }
    };

}]);

OfflinkJs.config(['$httpProvider', 'localStorageServiceProvider', function ($httpProvider, localStorageServiceProvider) {
    $httpProvider.interceptors.push('cacheInterceptor');
    localStorageServiceProvider
        .setPrefix('flnk')
        .setNotify(true, true);
}]);

OfflinkJs.factory('ServiceWorkerService', [function () {
    var res = [];
    return {
        register: function (path) {
            if ('serviceWorker' in navigator) {
                navigator.serviceWorker.getRegistration().then(function(r){
                    console.log("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR : " + r);
                    if(r){
                        console.log("FUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUCK!");
                        r.unregister(path).then(function(boolean){
                            navigator.serviceWorker.register(path).then(function (reg) {
                                if (reg.installing) {
                                    console.log('Service worker installing');
                                } else if (reg.waiting) {
                                    console.log('Service worker installed');
                                } else if (reg.active) {
                                    console.log('Service worker active');
                                }

                            }).catch(function (error) {
                                // registration failed
                                console.log('Registration failed with ' + error);
                            });
                        });
                    }else{
                        console.log("NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!");
                        navigator.serviceWorker.register(path).then(function (reg) {
                            if (reg.installing) {
                                console.log('Service worker installing');
                            } else if (reg.waiting) {
                                console.log('Service worker installed');
                            } else if (reg.active) {
                                console.log('Service worker active');
                            }

                        }).catch(function (error) {
                            // registration failed
                            console.log('Registration failed with ' + error);
                        });
                    }
                });

            }
        }
    };
}]);

OfflinkJs.factory('cacheInterceptor', ['localStorageService', function (localStorageService) {
    return {
        request: function (config) {
            if (config.flnk_cache) {
                localStorageService.set(config.req_prefix + "." + Date.now(), config);
            }
            return config;
        }
    };
}]);

OfflinkJs.factory('flnkSynchronizer', ['$http', 'localStorageService', function ($http, localStorageService) {
    return {
        sync: function (prefix) {
            var lsKeys = localStorageService.keys();
            angular.forEach(lsKeys, function (value, key) {
                if (prefix === value.split(".")[0]) {
                    var config = localStorageService.get(value);
                    $http.post(config.url,
                        config.data
                    ).
                        then(function (response) {
                        }, function (response) {
                        });
                }
            });
            return lsKeys;
        }
    };
}]);

OfflinkJs.factory('flnkDatabaseService', [function () {
    var _db = null;
    var promise;
    return {
        init: function (schemaBuilder) {
            promise = schemaBuilder.connect();
            promise.then(function (db) {
                _db = db;
            });
            return promise;
        },
        insert: function (tableName, data) {
            var table, row;
            if (_db != null) {
                table = _db.getSchema().table(tableName);
                row = table.createRow(data);
                return _db.insertOrReplace().into(table).values([row]).exec();
            } else {
                return promise.then(function (db) {
                    _db = db;
                    table = _db.getSchema().table(tableName);
                    row = table.createRow(data);
                    return _db.insertOrReplace().into(table).values([row]).exec();
                });
                //return schemaBuilder.connect().then(function (db) {
                //    console.log("muwahaha");
                //    _db = db;
                //    table = _db.getSchema().table(tableName);
                //    row = table.createRow(data);
                //    return _db.insertOrReplace().into(table).values([row]).exec();
                //});
            }
        },

        read: function (tableName, selectParam) {
            var table;
            //angular.forEach(selectParam,function(param){
            //        console.log(param);
            //    }
            // );
            if (_db != null) {
                table = _db.getSchema().table(tableName);
                return _db.select.apply(this, selectParam).from(table).exec();
                /**
                 * TODO: add query parameters
                 */
                //return _db.select().from(table).where(item.done.eq(false)).exec();
            } else {
                return promise.then(function (db) {
                    _db = db;
                    table = _db.getSchema().table(tableName);
                    return _db.select().from(table).exec();
                });
                //return schemaBuilder.connect().then(function (db) {
                //    _db = db;
                //    table = _db.getSchema().table(tableName);
                //    return _db.select().from(table).exec();
                //});
            }
        }

    };
}]);

<commit_msg>Update offlinksJs.js<commit_after>/**
 * Created by ArunaTebel on 8/31/2015.
 */

var OfflinkJs = angular.module('OfflinkJs', ['LocalStorageModule']);
OfflinkJs.factory("ConnectionDetectorService", [function () {

    var conDetectFunction = URL.createObjectURL(new Blob(['(',
            function () {
                var conDetectURL = "";
                addEventListener('message', function (e) {
                    switch (e.data.msg) {
                        case 'REGISTER':
                            conDetectURL = e.data.url;
                            setInterval(detectConnectivity, 3000);
                            break;
                        case 'POLL':
                            return getConnectionStatus();
                            break;
                    }
                }, false);

                function detectConnectivity() {
                    var http = new XMLHttpRequest();
                    http.open('HEAD', conDetectURL);
                    http.onreadystatechange = function () {
                        if (this.readyState == this.DONE) {
                            connectionStatus = this.status;
                            self.postMessage(this.status);
                        }
                    };
                    if (conDetectURL != "") {
                        http.send();
                    }
                }
            }.toString(),

            ')()'], {type: 'application/javascript'})
    );

    var callbackFunc = null;
    var connectionStatus = "";

    var worker = new Worker(conDetectFunction);
    URL.revokeObjectURL(conDetectFunction);
    worker.addEventListener('message', function (e) {
        callbackFunc(e.data);
        connectionStatus = e.data;
    }, false);

    return {
        register: function (url, callback) {
            callbackFunc = callback;
            var msg = {
                msg: "REGISTER",
                url: url
            };
            worker.postMessage(msg);
        },
        getConnectionStatus: function () {
            return connectionStatus;
        }
    };

}]);

OfflinkJs.config(['$httpProvider', 'localStorageServiceProvider', function ($httpProvider, localStorageServiceProvider) {
    $httpProvider.interceptors.push('cacheInterceptor');
    localStorageServiceProvider
        .setPrefix('flnk')
        .setNotify(true, true);
}]);

OfflinkJs.factory('ServiceWorkerService', [function () {
    var res = [];
    return {
        register: function (path) {
            if ('serviceWorker' in navigator) {
                navigator.serviceWorker.getRegistration().then(function(r){
                    console.log("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR : " + r);
                    if(r){
                        console.log("FUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUCK!");
                        r.unregister(path).then(function(b){
                            console.log(b);
                            navigator.serviceWorker.register(path).then(function (reg) {
                                if (reg.installing) {
                                    console.log('Service worker installing');
                                } else if (reg.waiting) {
                                    console.log('Service worker installed');
                                } else if (reg.active) {
                                    console.log('Service worker active');
                                }

                            }).catch(function (error) {
                                // registration failed
                                console.log('Registration failed with ' + error);
                            });
                        }).catch(function(error){
                            console.log("haffa!!!!!!!!!!!!!!!!!!!!!" + error);
                        });
                    }else{
                        console.log("NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!");
                        navigator.serviceWorker.register(path).then(function (reg) {
                            if (reg.installing) {
                                console.log('Service worker installing');
                            } else if (reg.waiting) {
                                console.log('Service worker installed');
                            } else if (reg.active) {
                                console.log('Service worker active');
                            }

                        }).catch(function (error) {
                            // registration failed
                            console.log('Registration failed with ' + error);
                        });
                    }
                });

            }
        }
    };
}]);

OfflinkJs.factory('cacheInterceptor', ['localStorageService', function (localStorageService) {
    return {
        request: function (config) {
            if (config.flnk_cache) {
                localStorageService.set(config.req_prefix + "." + Date.now(), config);
            }
            return config;
        }
    };
}]);

OfflinkJs.factory('flnkSynchronizer', ['$http', 'localStorageService', function ($http, localStorageService) {
    return {
        sync: function (prefix) {
            var lsKeys = localStorageService.keys();
            angular.forEach(lsKeys, function (value, key) {
                if (prefix === value.split(".")[0]) {
                    var config = localStorageService.get(value);
                    $http.post(config.url,
                        config.data
                    ).
                        then(function (response) {
                        }, function (response) {
                        });
                }
            });
            return lsKeys;
        }
    };
}]);

OfflinkJs.factory('flnkDatabaseService', [function () {
    var _db = null;
    var promise;
    return {
        init: function (schemaBuilder) {
            promise = schemaBuilder.connect();
            promise.then(function (db) {
                _db = db;
            });
            return promise;
        },
        insert: function (tableName, data) {
            var table, row;
            if (_db != null) {
                table = _db.getSchema().table(tableName);
                row = table.createRow(data);
                return _db.insertOrReplace().into(table).values([row]).exec();
            } else {
                return promise.then(function (db) {
                    _db = db;
                    table = _db.getSchema().table(tableName);
                    row = table.createRow(data);
                    return _db.insertOrReplace().into(table).values([row]).exec();
                });
                //return schemaBuilder.connect().then(function (db) {
                //    console.log("muwahaha");
                //    _db = db;
                //    table = _db.getSchema().table(tableName);
                //    row = table.createRow(data);
                //    return _db.insertOrReplace().into(table).values([row]).exec();
                //});
            }
        },

        read: function (tableName, selectParam) {
            var table;
            //angular.forEach(selectParam,function(param){
            //        console.log(param);
            //    }
            // );
            if (_db != null) {
                table = _db.getSchema().table(tableName);
                return _db.select.apply(this, selectParam).from(table).exec();
                /**
                 * TODO: add query parameters
                 */
                //return _db.select().from(table).where(item.done.eq(false)).exec();
            } else {
                return promise.then(function (db) {
                    _db = db;
                    table = _db.getSchema().table(tableName);
                    return _db.select().from(table).exec();
                });
                //return schemaBuilder.connect().then(function (db) {
                //    _db = db;
                //    table = _db.getSchema().table(tableName);
                //    return _db.select().from(table).exec();
                //});
            }
        }

    };
}]);

<|endoftext|>


<commit_before>import React from 'react';
import MusicBrowser from 'components/MusicBrowser';
import HorizontalPlayer from 'components/HorizontalPlayer';
import styles from './styles.css';

export default class BrowserPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
  render() {
    return (

        <MusicBrowser />
        <PlayerControl playerComponent={HorizontalPlayer} />

    );
  }
}
<commit_msg>whoops, import PlayerControl in BrowserPage<commit_after>import React from 'react';
import HorizontalPlayer from 'components/HorizontalPlayer';
import MusicBrowser from 'components/MusicBrowser';
import PlayerControl from 'containers/PlayerControl';
import styles from './styles.css';

export default class BrowserPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
  render() {
    return (

        <MusicBrowser />
        <PlayerControl playerComponent={HorizontalPlayer} />

    );
  }
}
<|endoftext|>


<commit_before>import { takeLatest } from 'redux-saga';
import { fork, select, call, put } from 'redux-saga/effects';
import request from 'utils/request';
import * as actions from './actions';
import * as selectors from './selectors';
import * as c from './constants';

export function* submitEmail() {
  const email = yield select(selectors.selectEmail());
  const state = yield select(selectors.selectState());
  const registered = yield select(selectors.selectRegistered());

  const subscribeResult = yield call(
    request,
    c.SUBSCRIBE_EMAIL_URL,
    {
      method: 'POST',
      body: JSON.stringify({
        email_address: email.email,
        status: 'subscribed',
        merge_fields: { state, registered },
      }),
    }
  );
  let status = 'Server error. Try again later.';
  if (!subscribeResult.err) {
    if (subscribeResult.data.status === 'subscribed') {
      yield put(actions.closeModal());
    } else if (subscribeResult.data.title === 'Member Exists') {
      status = 'You were already subscribed.';
    } else if (subscribeResult.data.title === 'Invalid Resource') {
      status = subscribeResult.data.detail;
    }
  }
  yield put(actions.updateEmailStatus(status));
}

export function* postRegSaga() {
  yield fork(takeLatest, c.SUBMIT_EMAIL, submitEmail);
}

export default [
  postRegSaga,
];
<commit_msg>Capitalize merge field keys<commit_after>import { takeLatest } from 'redux-saga';
import { fork, select, call, put } from 'redux-saga/effects';
import request from 'utils/request';
import * as actions from './actions';
import * as selectors from './selectors';
import * as c from './constants';

export function* submitEmail() {
  const email = yield select(selectors.selectEmail());
  const state = yield select(selectors.selectState());
  const registered = yield select(selectors.selectRegistered());

  const subscribeResult = yield call(
    request,
    c.SUBSCRIBE_EMAIL_URL,
    {
      method: 'POST',
      body: JSON.stringify({
        email_address: email.email,
        status: 'subscribed',
        merge_fields: { STATE: state, REGISTERED: registered },
      }),
    }
  );
  let status = 'Server error. Try again later.';
  if (!subscribeResult.err) {
    if (subscribeResult.data.status === 'subscribed') {
      yield put(actions.closeModal());
    } else if (subscribeResult.data.title === 'Member Exists') {
      status = 'You were already subscribed.';
    } else if (subscribeResult.data.title === 'Invalid Resource') {
      status = subscribeResult.data.detail;
    }
  }
  yield put(actions.updateEmailStatus(status));
}

export function* postRegSaga() {
  yield fork(takeLatest, c.SUBMIT_EMAIL, submitEmail);
}

export default [
  postRegSaga,
];
<|endoftext|>


<commit_before>import Ember from "ember";

export default Ember.Controller.extend({
  needs: ["offer"],
  offer: Ember.computed.alias("controllers.offer.model"),
  item: Ember.computed.alias("model"),

  session: Ember.inject.service(),
  store: Ember.inject.service(),
  alert: Ember.inject.service(),
  customConfirm: Ember.inject.service(),
  confirm: Ember.inject.service(),
  offerId: null,
  itemId: null,
  packageId: null,
  noImage: Ember.computed.empty("item.images"),
  previewImage: null,
  addPhotoLabel: Ember.I18n.t("edit_images.add_photo"),
  isReady: false,
  isExpanded: false,
  backBtnVisible: true,
  loadingPercentage: Ember.I18n.t("edit_images.image_uploading"),
  uploadedFileDate: null,

  package: function() {
    return this.get("store").getById("package", this.get("packageId"));
  }.property("packageId"),

  previewMatchesFavourite: function() {
    return this.get("previewImage") === this.get("favouriteImage");
  }.property("previewImage", "favouriteImage"),

  images: function() {
    //The reason for sorting is because by default it's ordered by favourite
    //then id order. If another image is made favourite then deleted the first image
    //by id order is made favourite which can be second image in list which seems random.

    //Sort by id ascending except place new images id = 0 at end
    return (this.get("item.images") || Ember.A()).toArray().sort(function(a,b) {
      a = parseInt(a.get("id"));
      b = parseInt(b.get("id"));
      if (a === 0) { return 1; }
      if (b === 0) { return -1; }
      return a - b;
    });
  }.property("item.images.[]"),

  favouriteImage: function() {
    return this.get("package") ?
      this.get("package.image") :
      this.get("images").filterBy("favourite").get("firstObject");
  }.property("item.images.@each.favourite", "package.image"),

  initPreviewImage: function() {
    var image = this.get("package.image") || this.get("item.displayImage");
    if (image) {
      this.send("setPreview", image);
    }
  }.observes("package", "item", "item.images.@each").on("init"),

  //css related
  previewImageBgCss: function() {
    var css = this.get("instructionBoxCss");
    if (!this.get("previewImage")) {
      return css;
    }
    return css + "background-image:url(" + this.get("previewImage.imageUrl") + ");" +
      "background-size: " + (this.get("isExpanded") ? "contain" : "cover") + ";";
  }.property("previewImage", "isExpanded"),

  instructionBoxCss: function() {
    var height = Ember.$(window).height() * 0.6;
    return "min-height:" + height + "px;";
  }.property("previewImage", "isExpanded"),

  thumbImageCss: function() {
    var imgWidth = Math.min(120, Ember.$(window).width() / 4 - 14);
    return "width:" + imgWidth + "px; height:" + imgWidth + "px;";
  }.property(),

  noImageLink: function() {
    return this.get("noImage") && this.get("session.isAdminApp");
  }.property("noImage"),

  locale: function(str){
    return Ember.I18n.t(str);
  },

  createItem: function(donorCondition, withoutImage, identifier) {
    var _this = this;
    var loadingView = this.container.lookup('view:loading').append();
    var offer = this.get("offer");
    var item = this.get("store").createRecord("item", {
      offer: offer,
      donorCondition: donorCondition,
      state: "draft"
    });
    item.save()
      .then(() => {
        if(withoutImage) {
          loadingView.destroy();
          _this.transitionToRoute("review_item.accept", _this.get('offer'), item);
        }
        else
        {
          this.get("store").createRecord('image', {cloudinaryId: identifier, item: item, favourite: true}).save()
            .then(function() {
              _this.send("newItem", item)
              loadingView.destroy();
            });
        }
      })
      .catch(error => {
        item.unloadRecord();
        loadingView.destroy();
        throw error;
      });
  },

  deleteOffer: function(loadingView) {
    var controller = this;
    var offer = this.get("offer");
    offer.destroyRecord().then(function(){
      controller.transitionToRoute('my_list.reviewing');
    })
    .finally(() => loadingView.destroy());
  },

  cancelItem: function(controller, item) {
    var offer = item.get('offer');
    var loadingView = controller.container.lookup('view:loading').append();

    if(offer.get('itemCount') === 1){
      var delivery = offer.get("delivery");
      if(delivery)
        this.get("confirm").show(this.locale("edit_images.cancelling_item_will_cancel_offer"),
          () =>{
            var gogovanOrder = offer.get("delivery.gogovanOrder");
            if(gogovanOrder && gogovanOrder.get("isActive")){
              loadingView.destroy();
              controller.transitionToRoute("offer.cancel_gogovan", offer)
            }
            else
              this.deleteOffer(loadingView);
          }
        );
      else
        this.deleteOffer(loadingView);
    }
    else{
      offer.get('items').removeObject(item);
      item.destroyRecord().then(function(){
        controller.transitionToRoute("review_offer.items");
      })
      .finally(() => loadingView.destroy());
    }
  },

  removeImage: function(controller, item) {
    var _this = this;
    var img = item.get("images.firstObject");
    var loadingView = controller.container.lookup('view:loading').append();
    img.deleteRecord();
    img.save()
      .then(i => {
        i.unloadRecord();
        controller.transitionToRoute("item.edit_images", item);
      })
    .finally(() => loadingView.destroy());
  },

  confirmRemoveLastImage: function() {
    var item = this.get("item");
    this.get("customConfirm").show(this.locale("edit_images.last_image_with_item"),
      this.locale("edit_images.remove_image"), this.locale("edit_images.cancel_item"),
      () => this.cancelItem(this, item),
      () => this.removeImage(this, item)
    );
  },

  cannotRemoveImageAlert: function(){
    this.get("alert").show(this.locale("edit_images.cant_delete_last_image"));
  },

  actions: {
    next: function() {
      if(this.get("session.isAdminApp")) {
        this.transitionToRoute("review_item.accept", this.get('offer'), this.get('model'));
      } else {
        this.transitionToRoute("item.edit");
      }
    },

    //only used for admin
    nextWithoutImage: function() {
      var item = this.get("item")
      if(item){
        this.transitionToRoute("review_item.accept", this.get('offer'), item);
      }
      else{
        var defaultDonorCondition = this.get("store").all("donorCondition").sortBy("id").get("firstObject");
        this.createItem(defaultDonorCondition, true);
      }
    },

    back: function() {
      if(this.get("session.isAdminApp")) {
        this.transitionToRoute("review_offer.items");
      } else {
        if (this.get('offer.itemCount') === 0){
          this.transitionToRoute("offers");
        } else {
          this.transitionToRoute("offer.offer_details");
        }
      }
    },

    newItem: function(item) {
      if(this.get("session.isAdminApp")){
        this.transitionToRoute("item.edit_images", item.get("id"));
      } else {
        this.transitionToRoute("item.edit", item.get("id"));
      }
    },

    setPreview: function(image) {
      this.get("item.images").setEach("selected", false);
      image.set("selected", true);
      this.set("previewImage", image);
    },

    setFavourite: function() {
      if (this.get("package")) {
        var pkg = this.get("package");
        pkg.set("imageId", this.get("previewImage.id"));
        pkg.save()
          .catch(error => { pkg.rollback(); throw error; });
      } else {
        this.get("item.images").setEach("favourite", false);
        this.get("previewImage").set("favourite", true).save()
          .catch(error => {
            this.get("item.images").forEach(img => img.rollback());
            throw error;
          });
      }
    },

    deleteImage: function() {
      if (this.get("item.images.length") === 1)
      {
        this.get("session.isAdminApp") ? this.confirmRemoveLastImage()
          : this.cannotRemoveImageAlert();
        return;
      }
      else {
        this.get("confirm").show(Ember.I18n.t("edit_images.delete_confirm"), () => {
          var loadingView = this.container.lookup('view:loading').append();
          var img = this.get("previewImage");
          img.deleteRecord();
          img.save()
            .then(i => {
              i.unloadRecord();
              this.initPreviewImage();
              if (!this.get("favouriteImage")) {
                this.send("setFavourite");
              }
            })
            .catch(error => { this.get("previewImage").rollback(); throw error; })
            .finally(() => loadingView.destroy());
        });
      }
    },

    expandImage: function() {
      var value = this.get("isExpanded");
      this.set("isExpanded", !value);
    },

    //file upload
    triggerUpload: function() {
      if(navigator.userAgent.match(/iemobile/i))
      {
        //don't know why but on windows phone need to click twice in quick succession
        //for dialog to appear
        Ember.$("#photo-list input[type='file']").click().click();
      }
      else
      {
        Ember.$("#photo-list input[type='file']").trigger("click");
      }
    },

    uploadReady: function() {
      this.set("isReady", true);
    },

    uploadStart: function(e, data) {
      this.set("uploadedFileDate", data);
      Ember.$(".loading-indicator").show();
    },

    cancelUpload: function(){
      if(this.get("uploadedFileDate")){ this.get("uploadedFileDate").abort(); }
    },

    uploadProgress: function(e, data) {
      var progress = parseInt(data.loaded / data.total * 100, 10) || 0;
      this.set("addPhotoLabel", progress + "%");
      this.set("loadingPercentage", Ember.I18n.t("edit_images.image_uploading") + progress + "%");
    },

    uploadComplete: function() {
      this.set("uploadedFileDate", null);
      Ember.$(".loading-indicator.hide_image_loading").hide();
      this.set("addPhotoLabel", Ember.I18n.t("edit_images.add_photo"));
      this.set("loadingPercentage", Ember.I18n.t("edit_images.image_uploading"));
    },

    uploadSuccess: function(e, data) {
      var identifier = data.result.version + "/" + data.result.public_id + "." + data.result.format;
      var item = this.get("item");
      if (!item || this.get("item.isOffer")) {
        var defaultDonorCondition = this.get("store").all("donorCondition").sortBy("id").get("firstObject");
        this.createItem(defaultDonorCondition, false, identifier)
      } else {
        var favourite = item.get("images.length") === 0;
        var img = this.get("store").createRecord('image', {cloudinaryId: identifier, item: this.get("item"), favourite: favourite});
        img.save().catch(error => { img.unloadRecord(); throw error; });
      }
    }
  },

});
<commit_msg>fixed issue with image-loading screen<commit_after>import Ember from "ember";

export default Ember.Controller.extend({
  needs: ["offer"],
  offer: Ember.computed.alias("controllers.offer.model"),
  item: Ember.computed.alias("model"),

  session: Ember.inject.service(),
  store: Ember.inject.service(),
  alert: Ember.inject.service(),
  customConfirm: Ember.inject.service(),
  confirm: Ember.inject.service(),
  offerId: null,
  itemId: null,
  packageId: null,
  noImage: Ember.computed.empty("item.images"),
  previewImage: null,
  addPhotoLabel: Ember.I18n.t("edit_images.add_photo"),
  isReady: false,
  isExpanded: false,
  backBtnVisible: true,
  loadingPercentage: Ember.I18n.t("edit_images.image_uploading"),
  uploadedFileDate: null,

  package: function() {
    return this.get("store").getById("package", this.get("packageId"));
  }.property("packageId"),

  previewMatchesFavourite: function() {
    return this.get("previewImage") === this.get("favouriteImage");
  }.property("previewImage", "favouriteImage"),

  images: function() {
    //The reason for sorting is because by default it's ordered by favourite
    //then id order. If another image is made favourite then deleted the first image
    //by id order is made favourite which can be second image in list which seems random.

    //Sort by id ascending except place new images id = 0 at end
    return (this.get("item.images") || Ember.A()).toArray().sort(function(a,b) {
      a = parseInt(a.get("id"));
      b = parseInt(b.get("id"));
      if (a === 0) { return 1; }
      if (b === 0) { return -1; }
      return a - b;
    });
  }.property("item.images.[]"),

  favouriteImage: function() {
    return this.get("package") ?
      this.get("package.image") :
      this.get("images").filterBy("favourite").get("firstObject");
  }.property("item.images.@each.favourite", "package.image"),

  initPreviewImage: function() {
    var image = this.get("package.image") || this.get("item.displayImage");
    if (image) {
      this.send("setPreview", image);
    }
  }.observes("package", "item", "item.images.@each").on("init"),

  //css related
  previewImageBgCss: function() {
    var css = this.get("instructionBoxCss");
    if (!this.get("previewImage")) {
      return css;
    }
    return css + "background-image:url(" + this.get("previewImage.imageUrl") + ");" +
      "background-size: " + (this.get("isExpanded") ? "contain" : "cover") + ";";
  }.property("previewImage", "isExpanded"),

  instructionBoxCss: function() {
    var height = Ember.$(window).height() * 0.6;
    return "min-height:" + height + "px;";
  }.property("previewImage", "isExpanded"),

  thumbImageCss: function() {
    var imgWidth = Math.min(120, Ember.$(window).width() / 4 - 14);
    return "width:" + imgWidth + "px; height:" + imgWidth + "px;";
  }.property(),

  noImageLink: function() {
    return this.get("noImage") && this.get("session.isAdminApp");
  }.property("noImage"),

  locale: function(str){
    return Ember.I18n.t(str);
  },

  createItem: function(donorCondition, withoutImage, identifier) {
    var _this = this;
    var loadingView = this.container.lookup('view:loading').append();
    var offer = this.get("offer");
    var item = this.get("store").createRecord("item", {
      offer: offer,
      donorCondition: donorCondition,
      state: "draft"
    });
    item.save()
      .then(() => {
        if(withoutImage) {
          loadingView.destroy();
          _this.transitionToRoute("review_item.accept", _this.get('offer'), item);
        }
        else
        {
          this.get("store").createRecord('image', {cloudinaryId: identifier, item: item, favourite: true}).save()
            .then(function() {
              _this.send("newItem", item)
              loadingView.destroy();
            });
        }
      })
      .catch(error => {
        item.unloadRecord();
        loadingView.destroy();
        throw error;
      });
  },

  deleteOffer: function(loadingView) {
    var controller = this;
    var offer = this.get("offer");
    offer.destroyRecord().then(function(){
      controller.transitionToRoute('my_list.reviewing');
    })
    .finally(() => loadingView.destroy());
  },

  cancelItem: function(controller, item) {
    var offer = item.get('offer');
    var loadingView = controller.container.lookup('view:loading').append();

    if(offer.get('itemCount') === 1){
      var delivery = offer.get("delivery");
      if(delivery)
        this.get("confirm").show(this.locale("edit_images.cancelling_item_will_cancel_offer"),
          () =>{
            var gogovanOrder = offer.get("delivery.gogovanOrder");
            if(gogovanOrder && gogovanOrder.get("isActive")){
              loadingView.destroy();
              controller.transitionToRoute("offer.cancel_gogovan", offer)
            }
            else
              this.deleteOffer(loadingView);
          }
        );
      else
        this.deleteOffer(loadingView);
    }
    else{
      offer.get('items').removeObject(item);
      item.destroyRecord().then(function(){
        controller.transitionToRoute("review_offer.items");
      })
      .finally(() => loadingView.destroy());
    }
  },

  removeImage: function(controller, item) {
    var _this = this;
    var img = item.get("images.firstObject");
    var loadingView = controller.container.lookup('view:loading').append();
    img.deleteRecord();
    img.save()
      .then(i => {
        i.unloadRecord();
        controller.transitionToRoute("item.edit_images", item);
      })
    .finally(() => loadingView.destroy());
  },

  confirmRemoveLastImage: function() {
    var item = this.get("item");
    this.get("customConfirm").show(this.locale("edit_images.last_image_with_item"),
      this.locale("edit_images.remove_image"), this.locale("edit_images.cancel_item"),
      () => this.cancelItem(this, item),
      () => this.removeImage(this, item)
    );
  },

  cannotRemoveImageAlert: function(){
    this.get("alert").show(this.locale("edit_images.cant_delete_last_image"));
  },

  actions: {
    next: function() {
      if(this.get("session.isAdminApp")) {
        this.transitionToRoute("review_item.accept", this.get('offer'), this.get('model'));
      } else {
        this.transitionToRoute("item.edit");
      }
    },

    //only used for admin
    nextWithoutImage: function() {
      var item = this.get("item")
      if(item){
        this.transitionToRoute("review_item.accept", this.get('offer'), item);
      }
      else{
        var defaultDonorCondition = this.get("store").all("donorCondition").sortBy("id").get("firstObject");
        this.createItem(defaultDonorCondition, true);
      }
    },

    back: function() {
      if(this.get("session.isAdminApp")) {
        this.transitionToRoute("review_offer.items");
      } else {
        if (this.get('offer.itemCount') === 0){
          this.transitionToRoute("offers");
        } else {
          this.transitionToRoute("offer.offer_details");
        }
      }
    },

    newItem: function(item) {
      if(this.get("session.isAdminApp")){
        this.transitionToRoute("item.edit_images", item.get("id"));
      } else {
        this.transitionToRoute("item.edit", item.get("id"));
      }
    },

    setPreview: function(image) {
      this.get("item.images").setEach("selected", false);
      image.set("selected", true);
      this.set("previewImage", image);
    },

    setFavourite: function() {
      if (this.get("package")) {
        var pkg = this.get("package");
        pkg.set("imageId", this.get("previewImage.id"));
        pkg.save()
          .catch(error => { pkg.rollback(); throw error; });
      } else {
        this.get("item.images").setEach("favourite", false);
        this.get("previewImage").set("favourite", true).save()
          .catch(error => {
            this.get("item.images").forEach(img => img.rollback());
            throw error;
          });
      }
    },

    deleteImage: function() {
      if (this.get("item.images.length") === 1)
      {
        this.get("session.isAdminApp") ? this.confirmRemoveLastImage()
          : this.cannotRemoveImageAlert();
        return;
      }
      else {
        this.get("confirm").show(Ember.I18n.t("edit_images.delete_confirm"), () => {
          var loadingView = this.container.lookup('view:loading').append();
          var img = this.get("previewImage");
          img.deleteRecord();
          img.save()
            .then(i => {
              i.unloadRecord();
              this.initPreviewImage();
              if (!this.get("favouriteImage")) {
                this.send("setFavourite");
              }
            })
            .catch(error => { this.get("previewImage").rollback(); throw error; })
            .finally(() => loadingView.destroy());
        });
      }
    },

    expandImage: function() {
      var value = this.get("isExpanded");
      this.set("isExpanded", !value);
    },

    //file upload
    triggerUpload: function() {
      if(navigator.userAgent.match(/iemobile/i))
      {
        //don't know why but on windows phone need to click twice in quick succession
        //for dialog to appear
        Ember.$("#photo-list input[type='file']").click().click();
      }
      else
      {
        Ember.$("#photo-list input[type='file']").trigger("click");
      }
    },

    uploadReady: function() {
      this.set("isReady", true);
    },

    uploadStart: function(e, data) {
      this.set("uploadedFileDate", data);
      Ember.$(".loading-image-indicator").show();
    },

    cancelUpload: function(){
      if(this.get("uploadedFileDate")){ this.get("uploadedFileDate").abort(); }
    },

    uploadProgress: function(e, data) {
      var progress = parseInt(data.loaded / data.total * 100, 10) || 0;
      this.set("addPhotoLabel", progress + "%");
      this.set("loadingPercentage", Ember.I18n.t("edit_images.image_uploading") + progress + "%");
    },

    uploadComplete: function() {
      this.set("uploadedFileDate", null);
      Ember.$(".loading-image-indicator.hide_image_loading").hide();
      this.set("addPhotoLabel", Ember.I18n.t("edit_images.add_photo"));
      this.set("loadingPercentage", Ember.I18n.t("edit_images.image_uploading"));
    },

    uploadSuccess: function(e, data) {
      var identifier = data.result.version + "/" + data.result.public_id + "." + data.result.format;
      var item = this.get("item");
      if (!item || this.get("item.isOffer")) {
        var defaultDonorCondition = this.get("store").all("donorCondition").sortBy("id").get("firstObject");
        this.createItem(defaultDonorCondition, false, identifier)
      } else {
        var favourite = item.get("images.length") === 0;
        var img = this.get("store").createRecord('image', {cloudinaryId: identifier, item: this.get("item"), favourite: favourite});
        img.save().catch(error => { img.unloadRecord(); throw error; });
      }
    }
  },

});
<|endoftext|>


<commit_before>var paused = 0;

angular.module("gameApp", [])
    //called by ng-controller in receiver.html
    //creats instance of cast receiver
    .controller("appController", ["$scope", "keyPressHandlerService", function ($scope, keyPressHandlerService) {
        window.onload = function () {
            cast.receiver.logger.setLevelValue(0);
            window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
            console.log('Starting Receiver Manager');

            // handler for the 'ready' event
            castReceiverManager.onReady = function (event) {
                console.log('Received Ready event: ' + JSON.stringify(event.data));
                window.castReceiverManager.setApplicationState('Application status is ready...');
            };

            // handler for 'senderconnected' event
            castReceiverManager.onSenderConnected = function (event) {
                console.log('Received Sender Connected event: ' + event.data);
                console.log(window.castReceiverManager.getSender(event.data).userAgent);
            };

            // handler for 'senderdisconnected' event
            castReceiverManager.onSenderDisconnected = function (event) {
                console.log('Received Sender Disconnected event: ' + event.data);
                if (window.castReceiverManager.getSenders().length == 0) {
                    window.close();
                }
            };

            // handler for 'systemvolumechanged' event
            castReceiverManager.onSystemVolumeChanged = function (event) {
                console.log('Received System Volume Changed event: ' + event.data['level'] + ' ' +
                    event.data['muted']);
            };

            // create a CastMessageBus to handle messages for a custom namespace
            window.messageBus =
                window.castReceiverManager.getCastMessageBus(
                    'urn:x-cast:com.google.cast.sample.helloworld');

            // handler for the CastMessageBus message event
            //called when receiver created above gets data
            window.messageBus.onMessage = function (event) {
                //print received message for debugging
                console.log('Message [' + event.senderId + ']: ' + event.data);
                // display the message from the sender
                displayText(event.data);

                //if pause message received, toggle paused flag
                if (event.data == 80) {
                    //if not paused, raise flag and display "play"
                    if (paused == 1) {
                        paused = 0;
                        console.log("play!")
                    }
                    //if paused, reset flag and display "pause"
                    else {
                        console.log("pause!");
                        paused = 1;
                    }

                }

                //if not pause message, spend data to key press handler
                //simulate a key up AND key down to prevent continuous movement
                keyPressHandlerService.keyPress(event.data);
                keyPressHandlerService.keyRelease(event.data);

                // inform all senders on the CastMessageBus of the incoming message event
                // sender message listener will be invoked
                window.messageBus.send(event.senderId, event.data);
            }

            // initialize the CastReceiverManager with an application status message
            window.castReceiverManager.start({
                statusText: 'Application is starting'
            });
            console.log('Receiver Manager started');
        };

        // utility function to display the text message in the input field
        function displayText(text) {
            console.log(text);
            document.getElementById('message').innerText = text;
            window.castReceiverManager.setApplicationState(text);
        };

    }])

//initialize game canvase and start game
.directive("centipedeGame", ["$interval", "gameService", "renderService", "graphicsEngineService", function ($interval, gameService, renderService, graphicsEngineService) {
    return {
        restrict: 'A',
        template: '<canvas id="gameCanvas" width="1200" height="440" style="text-align: center; position: absolute; left:50%; top: 50%; transform: translate(-50%,-50%); "></canvas>',

        link: function (scope, element) {
            var intervalPromise;
            var animation = 0;
            var canvas = element.find('canvas')[0].getContext("2d");

            graphicsEngineService.initialise(canvas, 'App/img/graphics.png');
            gameService.initialise();

            //loop to keep game running
            //cycle through, updating animations
            function gameLoop() {

                animation++;

                if (animation == 4) {
                    animation = 0;
                }
                //if game is not paused, update the screen
                if (paused != 1) {
                    gameService.update(animation);
                    renderService.draw(animation);
                } else {
                    graphicsEngineService.drawText(
                        1,
                        170,
                        320,
                        "Paused!",
                        "#dfc223",
                        "48px Slackey");
                }

            }

            intervalPromise = $interval(gameLoop, 50);

            scope.$on("$destroy", function () {
                if (intervalPromise) {
                    $interval.cancel(intervalPromise);
                    intervalPromise = undefined;
                }
            });
        }
    }
    }]);<commit_msg>changing height<commit_after>var paused = 0;

angular.module("gameApp", [])
    //called by ng-controller in receiver.html
    //creats instance of cast receiver
    .controller("appController", ["$scope", "keyPressHandlerService", function ($scope, keyPressHandlerService) {
        window.onload = function () {
            cast.receiver.logger.setLevelValue(0);
            window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
            console.log('Starting Receiver Manager');

            // handler for the 'ready' event
            castReceiverManager.onReady = function (event) {
                console.log('Received Ready event: ' + JSON.stringify(event.data));
                window.castReceiverManager.setApplicationState('Application status is ready...');
            };

            // handler for 'senderconnected' event
            castReceiverManager.onSenderConnected = function (event) {
                console.log('Received Sender Connected event: ' + event.data);
                console.log(window.castReceiverManager.getSender(event.data).userAgent);
            };

            // handler for 'senderdisconnected' event
            castReceiverManager.onSenderDisconnected = function (event) {
                console.log('Received Sender Disconnected event: ' + event.data);
                if (window.castReceiverManager.getSenders().length == 0) {
                    window.close();
                }
            };

            // handler for 'systemvolumechanged' event
            castReceiverManager.onSystemVolumeChanged = function (event) {
                console.log('Received System Volume Changed event: ' + event.data['level'] + ' ' +
                    event.data['muted']);
            };

            // create a CastMessageBus to handle messages for a custom namespace
            window.messageBus =
                window.castReceiverManager.getCastMessageBus(
                    'urn:x-cast:com.google.cast.sample.helloworld');

            // handler for the CastMessageBus message event
            //called when receiver created above gets data
            window.messageBus.onMessage = function (event) {
                //print received message for debugging
                console.log('Message [' + event.senderId + ']: ' + event.data);
                // display the message from the sender
                displayText(event.data);

                //if pause message received, toggle paused flag
                if (event.data == 80) {
                    //if not paused, raise flag and display "play"
                    if (paused == 1) {
                        paused = 0;
                        console.log("play!")
                    }
                    //if paused, reset flag and display "pause"
                    else {
                        console.log("pause!");
                        paused = 1;
                    }

                }

                //if not pause message, spend data to key press handler
                //simulate a key up AND key down to prevent continuous movement
                keyPressHandlerService.keyPress(event.data);
                keyPressHandlerService.keyRelease(event.data);

                // inform all senders on the CastMessageBus of the incoming message event
                // sender message listener will be invoked
                window.messageBus.send(event.senderId, event.data);
            }

            // initialize the CastReceiverManager with an application status message
            window.castReceiverManager.start({
                statusText: 'Application is starting'
            });
            console.log('Receiver Manager started');
        };

        // utility function to display the text message in the input field
        function displayText(text) {
            console.log(text);
            document.getElementById('message').innerText = text;
            window.castReceiverManager.setApplicationState(text);
        };

    }])

//initialize game canvase and start game
.directive("centipedeGame", ["$interval", "gameService", "renderService", "graphicsEngineService", function ($interval, gameService, renderService, graphicsEngineService) {
    return {
        restrict: 'A',
        template: '<canvas id="gameCanvas" width="900" height="440" style="text-align: center; position: absolute; left:50%; top: 50%; transform: translate(-50%,-50%); "></canvas>',

        link: function (scope, element) {
            var intervalPromise;
            var animation = 0;
            var canvas = element.find('canvas')[0].getContext("2d");

            graphicsEngineService.initialise(canvas, 'App/img/graphics.png');
            gameService.initialise();

            //loop to keep game running
            //cycle through, updating animations
            function gameLoop() {

                animation++;

                if (animation == 4) {
                    animation = 0;
                }
                //if game is not paused, update the screen
                if (paused != 1) {
                    gameService.update(animation);
                    renderService.draw(animation);
                } else {
                    graphicsEngineService.drawText(
                        1,
                        170,
                        320,
                        "Paused!",
                        "#dfc223",
                        "48px Slackey");
                }

            }

            intervalPromise = $interval(gameLoop, 50);

            scope.$on("$destroy", function () {
                if (intervalPromise) {
                    $interval.cancel(intervalPromise);
                    intervalPromise = undefined;
                }
            });
        }
    }
    }]);<|endoftext|>