/
controller.js
166 lines (146 loc) · 5.19 KB
/
controller.js
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
var global = (typeof window !== 'undefined') ? window : {},
Ember = global.Ember;
// Need to track
// 1) channel object
// 2) event bindings which consist of
// - handler
// - event name
// - a unique string representing the target
//
// bindings: {
// 'channel-one': {
// channel: Pusher.Channel,
// eventBindings: {
// Ember.Route.toString(): [
// { handler: Function, eventName: String },
// { handler: Function, eventName: String }
// ]
// }
// }
// }
//
// wire(target, channelName, events)
// ================
// Initialize object in bindings if it's empty, with eventBindings: {}
// If eventBindings.length for the current target is 0
// connect to the channel
// store channel in the hash
// For each event in events
// bind the channel to the eventName
// store the handler and eventName in the eventBindings array for this channel and controller
// the key for storing is in target._pusherTargetId()
// (we store the eventName for when we might want to programmatically unwire)
//
//
// unwire(route):
// =================
// get the channel object
// for each handler, eventName in eventBindings for the current route
// call channel.unbind(eventName, handler)
// delete the routes record in EventBindings
// if eventBindings for this channel is empty
// unsubscribe from the channel
// delete the channel from bindings
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
var Controller = Ember.Controller.extend({
connection: null,
isDisconnected: true,
isConnected: Ember.computed.not('isDisconnected'),
init: function() {
this._super();
this.set('bindings', {});
},
// Called by the application initializer
didCreatePusher: function(pusher) {
this.set('connection', pusher);
pusher.connection.bind('connected', __bind(this._didConnect, this));
pusher.connection.bind('disconnected', __bind(this._didDisconnect, this));
pusher.connection.bind('unavailable', __bind(this._didDisconnect, this));
},
// @events a hash in the form { channel-name: ['event1', 'event2'] }
// @target any object that responds to send() and _pusherEventsId()
wire: function(target, channelName, events) {
Ember.assert("Did you forget to extend the EmberPusher.Bindings mixin in " +
"your class receiving events?", !!target._pusherEventsId);
var channel = this.connectChannel(channelName),
bindings = this.get('bindings'),
targetId = target._pusherEventsId();
// Setup the eventBindings array for this target
if(!bindings[channelName].eventBindings[targetId])
bindings[channelName].eventBindings[targetId] = [];
// Iterate over the events and bind them
events.forEach(function(eventName) {
var normalizedEventName = Ember.String.camelize(eventName), handler;
handler = function(data) {
if(target.get('logPusherEvents')) {
console.log(target.constructor.toString() +
": Pusher event received", eventName, data);
}
target.send(Ember.String.camelize(eventName), data);
};
channel.bind(eventName, handler);
bindings[channelName].eventBindings[targetId].pushObject({
handler: handler,
eventName: eventName
});
});
},
connectChannel: function(channelName) {
var pusher = this.get('connection'),
bindings = this.get('bindings');
if(!bindings[channelName]) {
bindings[channelName] = { eventBindings: {} };
}
if(Ember.isEmpty(Object.keys(bindings[channelName].eventBindings))) {
bindings[channelName].channel = pusher.subscribe(channelName);
// Spit out a bunch of logging if asked
if(this.namespace && this.namespace.PUSHER_OPTS.logAllEvents) {
bindings[channelName].channel.bind_all(function(eventName, data) {
console.log(
"Pusher event received on " + channelName + ":",
eventName,
data
);
});
}
}
return bindings[channelName].channel;
},
unwire: function(target, channelName) {
var pusher = this.get('connection'),
bindings = this.get('bindings'),
targetId = target._pusherEventsId(),
channel = bindings[channelName].channel;
// Unbind all the events for this target
for(var binding in bindings[channelName].eventBindings[targetId]) {
channel.unbind(binding.eventName, binding.handler);
}
delete bindings[channelName].eventBindings[targetId];
// Unsubscribe from the channel if this is the last thing listening
if(bindings[channelName].eventBindings.length === 0) {
pusher.unsubscribe(channelName);
delete bindings[channelName];
return true;
}
return false;
},
channelFor: function(channelName) {
// debugger;
return this.get('bindings')[channelName].channel;
},
socketId: function() {
try {
return this.get('connection').connection.socket_id;
}
catch(error) {
console.warn(error);
}
}.property('isDisconnected'),
_didConnect: function() {
this.set('isDisconnected', false);
},
_didDisconnect: function() {
this.set('isDisconnected', true);
}
});
export { Controller };