~jonas-drange/online-services-common-js/navbar-autocomplete

« back to all changes in this revision

Viewing changes to build/musicstore-status/musicstore-status.js

  • Committer: Stephen Stewart
  • Date: 2014-02-22 23:57:25 UTC
  • mfrom: (18.1.2 trunk)
  • Revision ID: stephen.stewart@canonical.com-20140222235725-iw6f15t9umws19xd
mergeĀ lp:~stephen-stewart/online-services-common-js/remove-u1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
YUI.add('musicstore-status', function (Y, NAME) {
2
 
 
3
 
"use strict";
4
 
/**
5
 
* DownloadStatus class constructor
6
 
*
7
 
* TODO Refactor: don't touch the DOM so much, store values in local object
8
 
*
9
 
* Class to monitor a list of downloads represented in rows of a table,
10
 
* state is stored as data attributes on those rows. Once all downloads have
11
 
* reached a 'completed state' polling stops but can be restarted at user
12
 
* request by clicking on a table row.
13
 
*
14
 
* @constructor
15
 
*/
16
 
/* Any frequently used shortcuts, strings and constants */
17
 
var ONEERROR = "one:error";
18
 
 
19
 
 
20
 
function DownloadStatus() {
21
 
    DownloadStatus.superclass.constructor.apply(this, arguments);
22
 
}
23
 
 
24
 
DownloadStatus.NAME = "downloadStatus";
25
 
 
26
 
DownloadStatus.ATTRS = {
27
 
    dataNodes: { value: null },
28
 
 
29
 
    pollingInterval: {
30
 
        value: 10000, // 10 seconds
31
 
        validator: function(val) {
32
 
            return Y.Lang.isNumber(val);
33
 
        },
34
 
        setter: function(val) {
35
 
            this.pollingInterval = val;
36
 
            return val;
37
 
        },
38
 
        lazyAdd: false
39
 
    },
40
 
 
41
 
    // comepleted states used as a based for when to stop polling.
42
 
    completedStates: {
43
 
        value: [
44
 
            "complete",
45
 
            "error",
46
 
            "unknown",
47
 
            "downloaded-not-present"
48
 
        ]}
49
 
};
50
 
 
51
 
// Get nodes within the srcNode.
52
 
DownloadStatus.HTML_PARSER = {
53
 
    // DataNodes which will have the data attrs.
54
 
    dataNodes: ['tbody tr']
55
 
};
56
 
 
57
 
Y.extend(DownloadStatus, Y.Widget, {
58
 
 
59
 
    // set up instance specific state
60
 
    initializer: function(config) {
61
 
        if (config.statusCheckUrl && config.statusCheckUrl.length) {
62
 
            this.statusCheckUrl = config.statusCheckUrl;
63
 
        } else {
64
 
            throw new Error("one-musicstore-status: need a status check url");
65
 
        }
66
 
    },
67
 
 
68
 
    bindUI: function() {
69
 
        var bb = this.get("boundingBox");
70
 
        this.pollNotification = bb.one(".notification");
71
 
        this.pollNotification.one(".cta").on("click", function() {
72
 
            this.checkStatus(false);
73
 
        }, this);
74
 
    },
75
 
 
76
 
    syncUI: function() {
77
 
        this.interval = null;
78
 
        this.setPollTimer();
79
 
        this.checkStatus(false);
80
 
    },
81
 
 
82
 
    destructor: function() {
83
 
        clearInterval(this.interval);
84
 
    },
85
 
 
86
 
    /**
87
 
     * Enum for css class name values
88
 
     * @readonly
89
 
     * @enum {string}
90
 
     */
91
 
    SELECTORS: {
92
 
    // The data attribute for the dld key
93
 
        dldIdAttrKey: "data-dld-id",
94
 
        // The data attrubyte for the status.
95
 
        dldStatusAttrKey: "data-dld-status",
96
 
        // Description node selector
97
 
        dldStatusDescSel: ".dld-status-desc",
98
 
        // Where to find the class prefixed by classStatusPrefix
99
 
        dldStatusClassSel: ".dld-status"
100
 
    },
101
 
 
102
 
    /**
103
 
     * DownloadStatus's common class prefix for statuses.
104
 
     * @type {string}
105
 
     */
106
 
    CLASS_STATUS_PREFIX: "status-",
107
 
 
108
 
    /**
109
 
     * Maximum poll count
110
 
     * @type {number}
111
 
     */
112
 
    POLL_MAX: 30,
113
 
 
114
 
    /**
115
 
     * Poll count store for downloads
116
 
     * @type {Object}
117
 
     */
118
 
    pollCount: 0,
119
 
 
120
 
    setPollTimer: function() {
121
 
        this.interval = setInterval(Y.bind(this.checkStatus, this), this.pollingInterval);
122
 
    },
123
 
 
124
 
    /**
125
 
     * parse the nodes for status data
126
 
     */
127
 
    getStatusData: function() {
128
 
 
129
 
        var dldData = {},
130
 
        dldIdAttrKey = this.SELECTORS.dldIdAttrKey,
131
 
        completedStates = Y.Array(this.get("completedStates"));
132
 
 
133
 
        this.get("dataNodes").each(function(node) {
134
 
            var key = node.getAttribute(dldIdAttrKey),
135
 
            dldStatusAttrKey = this.SELECTORS.dldStatusAttrKey,
136
 
            nodeStatus = node.getAttribute(dldStatusAttrKey);
137
 
 
138
 
            // don't ask about stuff which is polled out or completed
139
 
            if ( Y.Array.indexOf(completedStates, nodeStatus) === -1) {
140
 
                dldData[key] = {};
141
 
                dldData[key].status = this.parseNode(node);
142
 
            }
143
 
        }, this);
144
 
 
145
 
        return dldData;
146
 
    },
147
 
 
148
 
    parseNode: function(node) {
149
 
        var dldStatusAttrKey = this.SELECTORS.dldStatusAttrKey;
150
 
        return node.getAttribute(dldStatusAttrKey);
151
 
    },
152
 
 
153
 
    checkStatus: function(poll) {
154
 
        // Get data for all the downloads
155
 
        if (this.pollCount < this.POLL_MAX || poll === false) {
156
 
            var data = this.getStatusData();
157
 
 
158
 
            if (Y.Object.isEmpty(data)) {
159
 
                this.removeTimer();
160
 
                return;
161
 
            }
162
 
 
163
 
            this.postDownloadData(data);
164
 
            this.pollCount++;
165
 
        } else {
166
 
            this.removeTimer();
167
 
            this.pollNotification.addClass("show");
168
 
        }
169
 
    },
170
 
 
171
 
    /**
172
 
     * postDownloadData. Send the download data...
173
 
     *
174
 
     * @param {Object} dldData all the data on the downloads
175
 
     * @param {?Object} io Y.IO object
176
 
     */
177
 
    postDownloadData: function(dldData, io) {
178
 
        io = io || new Y.IO();
179
 
        var cfg = {
180
 
            context: this,
181
 
            data: {'song_list': Y.JSON.stringify(dldData),
182
 
                'csrfmiddlewaretoken': YUI.Env.CSRF_TOKEN},
183
 
                method: "POST",
184
 
                on: {
185
 
                    "success": this.onSuccess,
186
 
                    "failure": this.onFailure
187
 
                }
188
 
 
189
 
        }, request;
190
 
        request = io.send(this.statusCheckUrl, cfg);
191
 
    },
192
 
 
193
 
    /**
194
 
     * onSuccess
195
 
     *
196
 
     * Take the response data from the statusCheck service and store the
197
 
     * values in the attributes of the download elements, as well as
198
 
     * setting relevant classes and content
199
 
     *
200
 
     */
201
 
    onSuccess: function(tid, response) {
202
 
        var respData = Y.JSON.parse(response.responseText),
203
 
            srcNode = this.get("srcNode"),
204
 
            dldIdAttrKey = this.SELECTORS.dldIdAttrKey,
205
 
            dldStatusAttrKey = this.SELECTORS.dldStatusAttrKey,
206
 
            continuePolling = false,
207
 
            completedStates = Y.Array(this.get("completedStates")),
208
 
            key,
209
 
            selector,
210
 
            dataNode,
211
 
            oldStatus,
212
 
            descNode,
213
 
            descStatusClassNode,
214
 
            nodeStatus,
215
 
            classStatusPrefix;
216
 
 
217
 
        for (key in respData) {
218
 
            selector = '['+ dldIdAttrKey + '="' + key + '"]';
219
 
            dataNode = srcNode.one(selector),
220
 
            oldStatus = dataNode.getAttribute(dldStatusAttrKey),
221
 
            descStatusClassNode = dataNode.one(this.SELECTORS.dldStatusClassSel),
222
 
            descNode = dataNode.one(this.SELECTORS.dldStatusDescSel),
223
 
            nodeStatus = respData[key].status.toLowerCase(),
224
 
            classStatusPrefix = this.CLASS_STATUS_PREFIX;
225
 
 
226
 
 
227
 
            if (dataNode) {
228
 
                if (oldStatus !== nodeStatus) {
229
 
 
230
 
                    if (descStatusClassNode) {
231
 
                        // Remove current status
232
 
                        descStatusClassNode.removeClass(classStatusPrefix + oldStatus);
233
 
                        // Replace with new status
234
 
                        descStatusClassNode.addClass(classStatusPrefix + nodeStatus);
235
 
                    }
236
 
 
237
 
                    // Update description
238
 
                    if (descNode) {
239
 
                        descNode.set("text", respData[key].status_desc);
240
 
                    }
241
 
                    // Update status attr
242
 
                    dataNode.setAttribute(dldStatusAttrKey, nodeStatus);
243
 
                }
244
 
            }
245
 
 
246
 
 
247
 
            if ( Y.Array.indexOf(completedStates, nodeStatus) === -1 ) {
248
 
                continuePolling = true;
249
 
            }
250
 
        }
251
 
 
252
 
        // if we're all complete, remove the poll timer
253
 
        if (!continuePolling) {
254
 
            this.removeTimer();
255
 
        }
256
 
 
257
 
        if (!continuePolling && this.pollNotification && this.pollNotification.hasClass("show")) {
258
 
            this.pollNotification.removeClass("show");
259
 
        }
260
 
 
261
 
        // Return continuePolling to add testing.
262
 
        return continuePolling;
263
 
    },
264
 
 
265
 
    onFailure: function () {
266
 
        Y.Global.fire(ONEERROR);
267
 
    },
268
 
 
269
 
    /**
270
 
     * remove the timer (stop polling) once we've reached POLL_MAX or
271
 
     * all items are at a complete status
272
 
     */
273
 
    removeTimer: function() {
274
 
        if (this.interval) {
275
 
            clearInterval(this.interval);
276
 
            delete this.interval;
277
 
        }
278
 
    }
279
 
 
280
 
});
281
 
 
282
 
Y.namespace("U1MS").DownloadStatus = DownloadStatus;
283
 
 
284
 
 
285
 
}, '@VERSION@', {"requires": ["widget", "io", "json"]});