|
1 | | -// -- TODO -- |
2 | | -// |
3 | | -// - https://developer.layer.com/docs/ios/integration |
4 | | -// - AddressBook = Presence/State + ChannelGroups |
5 | | -// - Notifications = History + PubSub |
6 | | -// - Messages = History + PubSub |
7 | | -// - Groups = History + PubSub |
8 | | -// - TypeingIndicator = ??? |
9 | | -// |
10 | | -// - Signals = PubSub |
11 | | -// - History = History |
12 | | -// |
13 | | -// -- TODO -- |
14 | | - |
15 | 1 | 'use strict'; |
16 | 2 |
|
17 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
18 | | -// AngularJS Chat Module |
19 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
20 | | -angular.module( 'chat', [] ); |
| 3 | +angular.module('chat', []); |
21 | 4 |
|
22 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
23 | 5 | // Common JS |
24 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
25 | 6 | if (typeof(exports) !== 'undefined') exports.chat = angular.module('chat'); |
26 | 7 |
|
27 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
28 | | -// >$ telnet nyancat.dakko.us |
29 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
30 | | -// |
31 | | -// ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄ |
32 | | -// █░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░█ |
33 | | -// █░▒▒▒▒▒▒▒▒▒▒▄▓▓▄▒▒▒▒░░▄▓▓▄ |
34 | | -// ▄▄▄ █░▒▒▒▒▒▒▒▒▒▒█▓▓▓▓▄▄▄▄▄▓▓▓▓ |
35 | | -// █▓▓█▄▄█░▒▒▒▒▒▒▒▒▒▒▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄ |
36 | | -// ▀▄▄▓▓█░▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▀ ▓▓▓▓▀ ▓▓▓▓ |
37 | | -// ▀▀█░▒▒▒▒▒▒▒▒▒▀▓▒▒▓▀▓▓▓▀▓▓▀▓▒▒█ |
38 | | -// ▄█░░▒▒▒▒▒▒▒▒▒▀▓▓▓▄▄▄▄▄▄▄▄▓▓▀ |
39 | | -// ▄▀▓▀█▄▄▄▄▄▄▄▄▄▄▄▄██████▀█▀▀ |
40 | | -// █▄▄▀ █▄▄▀ █▄▄▀ ▀▄▄█ |
41 | | -// |
42 | | - |
43 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
44 | | -// Messages it's important to remember that you can |
45 | | -// be deprived of your sanity listening to U2. |
46 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
| 8 | +// define Angular Message module |
47 | 9 | angular.module('chat').service( 'Messages', [ 'ChatCore', function(ChatCore) { |
48 | | - var Messages = this; |
49 | 10 |
|
50 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 11 | + var self = this; |
| 12 | + |
51 | 13 | // Send Messages |
52 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
53 | | - Messages.send = function(message) { |
| 14 | + self.send = function(message) { |
| 15 | + |
54 | 16 | if (!message.data) return; |
55 | 17 |
|
56 | 18 | ChatCore.publish({ |
57 | | - channel : message.to || 'global' |
58 | | - , message : message.data |
59 | | - , meta : ChatCore.user() |
| 19 | + to: message.to || 'global', |
| 20 | + message: message.data, |
| 21 | + user: ChatCore.user() |
60 | 22 | }); |
| 23 | + |
61 | 24 | }; |
62 | 25 |
|
63 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
64 | 26 | // Receive Messages |
65 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
66 | | - Messages.receive = function(fn) { |
67 | | - function receiver(response) { |
68 | | - response.data.m.forEach(function(msg){ |
69 | | - // Ignore messages without User Data |
70 | | - // TODO |
71 | | - if (!(msg.d && msg.u && msg.u.id)) return; |
72 | | - fn({ |
73 | | - data : msg.d |
74 | | - , id : msg.p.t |
75 | | - , user : msg.u |
76 | | - , self : msg.u.id == ChatCore.user().id |
77 | | - }); |
78 | | - }); |
79 | | - } |
80 | | - |
81 | | - Messages.subscription = ChatCore.subscribe({ |
82 | | - channels : [ 'global', ChatCore.user().id ].join(','), |
83 | | - message : receiver |
84 | | - }); |
| 27 | + self.receive = function(fn) { |
| 28 | + self.subscription = ChatCore.subscribe(fn); |
85 | 29 | }; |
86 | 30 |
|
87 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
88 | | - // Set/Get User and Save the World from that Bruce Willis movie. |
89 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
90 | | - Messages.user = function(data) { |
91 | | - return ChatCore.user(data); |
| 31 | + // Set/Get User |
| 32 | + self.user = function(data) { |
| 33 | + return ChatCore.user(data); |
92 | 34 | }; |
93 | 35 |
|
94 | | -} ] ); |
| 36 | + return self; |
95 | 37 |
|
96 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
97 | | -// AddressBook |
98 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
99 | | -angular.module('chat').service( 'AddressBook', function() { |
| 38 | +}]); |
100 | 39 |
|
101 | | -} ); |
| 40 | +// AngularJS Chat Core Service |
| 41 | +angular.module('chat').service('ChatCore', |
| 42 | + ['$rootScope', '$http', 'config', |
| 43 | + function($rootScope, $http, config) { |
102 | 44 |
|
| 45 | + var user = { |
| 46 | + id: uuid(), |
| 47 | + name: 'Anonymous' |
| 48 | + }; |
| 49 | + |
| 50 | + var self = this; |
| 51 | + |
| 52 | + self.rltm = rltm(config.rltm); |
| 53 | + |
| 54 | + // the global room everyone is in |
| 55 | + self.roomGlobal; |
| 56 | + |
| 57 | + // my own private rooms |
| 58 | + self.roomPrivate; |
| 59 | + |
| 60 | + // everyone elses private rooms |
| 61 | + self.rooms = {}; |
| 62 | + |
| 63 | + // Set User Data |
| 64 | + self.user = function(data) { |
| 65 | + |
| 66 | + if (data) { |
| 67 | + angular.extend(user, data); |
| 68 | + } |
103 | 69 |
|
104 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
105 | | -// AngularJS Chat Core Service |
106 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
107 | | -angular.module('chat').service( 'ChatCore', [ '$http', 'config', function( |
108 | | - $http, |
109 | | - config |
110 | | -) { |
111 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
112 | | - // API Keys |
113 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
114 | | - var pubkey = config.pubnub['publish-key'] |
115 | | - , subkey = config.pubnub['subscribe-key'] |
116 | | - , user = { id : uuid(), name : 'Nameless' }; |
117 | | - |
118 | | - var ChatCore = this; |
119 | | - |
120 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
121 | | - // Set User Data and we have to go Back to The Future. |
122 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
123 | | - ChatCore.user = function(data) { |
124 | | - if (data) angular.extend( user, data ); |
125 | 70 | return user; |
126 | | - }; |
127 | 71 |
|
128 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
129 | | - // Publish via PubNub |
130 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
131 | | - ChatCore.publish = function(setup) { |
132 | | - var meta = setup.meta || ChatCore.user() |
133 | | - , userid = ChatCore.user().id || 'nil'; |
134 | | - |
135 | | - var request = { |
136 | | - method : 'GET' |
137 | | - , params : { meta : meta, uuid : userid } |
138 | | - , timeout : setup.timeout || 5000 |
139 | | - , success : function(){} |
140 | | - , fail : function(){} |
141 | | - }; |
142 | | - |
143 | | -// |
144 | | - request.url = [ |
145 | | - 'https://pubsub.pubnub.com' |
146 | | - , '/publish/', pubkey |
147 | | - , '/', subkey |
148 | | - , '/0/', setup.channel |
149 | | - , '/0/', encodeURIComponent(JSON.stringify(setup.message)) |
150 | | - ].join(''); |
151 | | - |
152 | | - $http(request).then( request.success, request.fail ); |
153 | 72 | }; |
154 | 73 |
|
155 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
156 | | - // Subscribe via PubNub |
157 | | - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
158 | | - ChatCore.subscribe = function(setup) { |
159 | | - var channels = setup.channels || 'a' |
160 | | - , groups = setup.groups || '' |
161 | | - , message = setup.message || function(){} |
162 | | - , timeout = setup.timeout || 290000 |
163 | | - , timetoken = setup.timetoken || '0' |
164 | | - , windowing = setup.windowing || 10 |
165 | | - , userid = ChatCore.user().id || 'nil' |
166 | | - , userstate = ChatCore.user() || {} |
167 | | - , stop = false |
168 | | - , origin = 'ps'+(Math.random()+'').split('.')[1]+'.pubnub.com'; |
169 | | - |
170 | | - // Request Object |
171 | | - var request = { |
172 | | - method : 'GET' |
173 | | - , url : '' |
174 | | - , params : { uuid : userid, state : userstate } |
175 | | - , timeout : timeout |
176 | | - , success : next |
177 | | - , fail : function(){ timetoken = '0'; next() } |
178 | | - }; |
179 | | - |
180 | | - // Channel Groups |
181 | | - if (groups) request.params['channel-group'] = groups; |
182 | | - |
183 | | - // Subscribe Loop |
184 | | - function next(response) { |
185 | | - if (stop) return; |
186 | | - if (response) { |
187 | | - timetoken = timetoken == '0' ? 1000 : response.data.t.t; |
188 | | - message(response); |
| 74 | + // Publish over network |
| 75 | + self.publish = function(setup) { |
| 76 | + |
| 77 | + var user = setup.user || self.user(); |
| 78 | + |
| 79 | + var data = setup.data; |
| 80 | + |
| 81 | + if(setup.to) { |
| 82 | + |
| 83 | + if(!self.rooms[setup.to]) { |
| 84 | + self.rooms[setup.to] = self.rltm.join(setup.to); |
189 | 85 | } |
190 | 86 |
|
191 | | - request.url = [ |
192 | | - 'https://', origin |
193 | | - , '/v2/subscribe/', subkey |
194 | | - , '/', channels |
195 | | - , '/0/', timetoken |
196 | | - ].join(''); |
| 87 | + return self.rooms[setup.to].publish({ |
| 88 | + data: setup.message, |
| 89 | + user: user |
| 90 | + }); |
197 | 91 |
|
198 | | - setTimeout( function() { |
199 | | - $http(request).then( request.success, request.fail ); |
200 | | - }, windowing ); |
201 | | - } |
| 92 | + } else { |
| 93 | + |
| 94 | + return self.roomGlobal.publish({ |
| 95 | + data: setup.message, |
| 96 | + user: user |
| 97 | + }); |
202 | 98 |
|
203 | | - // Cancel Subscription |
204 | | - function unsubscribe() { |
205 | | - stop = true; |
206 | 99 | } |
207 | 100 |
|
208 | | - // Start Subscribe Loop |
209 | | - next(); |
| 101 | + }; |
| 102 | + |
| 103 | + // Subscribe to new messages |
| 104 | + self.subscribe = function(fn) { |
| 105 | + |
| 106 | + console.log('i am ', self.user().id) |
| 107 | + |
| 108 | + self.roomGlobal = self.rltm.join('global'); |
| 109 | + self.roomPrivate = self.rltm.join(self.user().id); |
| 110 | + |
| 111 | + self.roomGlobal.on('message', function(uuid, data) { |
| 112 | + |
| 113 | + console.log('public messages', data) |
| 114 | + |
| 115 | + fn(data, false); |
| 116 | + $rootScope.$apply(); |
| 117 | + }); |
| 118 | + |
| 119 | + self.roomPrivate.on('message', function(uuid, data) { |
| 120 | + |
| 121 | + console.log('private messages', data) |
| 122 | + |
| 123 | + fn(data, true); |
| 124 | + $rootScope.$apply(); |
| 125 | + |
| 126 | + }); |
| 127 | + |
| 128 | + return self.room; |
210 | 129 |
|
211 | | - // Allow Cancelling Subscriptions |
212 | | - return { |
213 | | - unsubscribe : unsubscribe |
214 | | - }; |
215 | 130 | }; |
216 | | -} ] ); |
217 | 131 |
|
218 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
219 | | -// UUID |
220 | | -// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
| 132 | +}]); |
| 133 | + |
| 134 | +// UUID utility |
221 | 135 | function uuid() { |
222 | 136 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, |
223 | 137 | function(c) { |
|
0 commit comments