All outstanding updates
[webos-internals:skurriers-modifications.git] / messaging / messaging-poor-mans-twitter-client.patch
1 diff --git a/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js b/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
2 index 98ab9b2..275a4f9 100644
3 --- a/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
4 +++ b/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
5 @@ -1669,9 +1669,245 @@ var ChatviewAssistant = Class.create({
6                         this.addTextToClipboard(text);
7                 } else if (value == 'delete-cmd') {
8                         this.handleMessageDeleteFromContextMenu(messageId, index);
9 +               } else if (value === "twitter-retweet-cmd") {
10 +                       Mojo.Log.info("twitter-retweet-cmd");
11 +                       this.twitterRetweet(text);
12 +               } else if (value === "twitter-reply-cmd") {
13 +                       Mojo.Log.info("twitter-reply-cmd");
14 +                       this.twitterReply(text);
15 +               } else if (value === "twitter-leave-user-cmd") {
16 +                       Mojo.Log.info("twitter-leave-user-cmd");
17 +                       this.twitterLeaveUser(text);
18 +               } else if (/^twitter-user:/.test(value)) {
19 +                       var username = RegExp.rightContext;
20 +                       var url = "http://twitter.com/" + username;
21 +                       var params = {
22 +                               scene: "page",
23 +                               target: url
24 +                       };
25 +                       var request = new Mojo.Service.Request("palm://com.palm.applicationManager", {
26 +                               method: 'launch',
27 +                               parameters: {'id': "com.palm.app.browser", 'params': params}
28 +                       });
29 +               }
30 +       },
31 +
32 +       twitterSkipChain: function (body) {
33 +               var originally_from, chainlink, result;
34 +               var modified = false;
35 +               Mojo.Log.info("twitterSkipChain(%j)", body);
36 +               while (true) {
37 +                       // skip past any RT/via chains.
38 +                       if (/^\s*rt(?:\s*@\s*|\s+)([_A-Za-z0-9]+)(?:\s*:\s*|\s+)/i.test(body)) {
39 +                               // RT@user:... (space optional before or after @ and :)
40 +                               // RT user ...
41 +                               chainlink       = RegExp.match;
42 +                               originally_from = RegExp.$1;
43 +                               body            = RegExp.rightContext;
44 +                               Mojo.Log.info("twitterSkipChain: skipping 'RT' chain link: %j", chainlink);
45 +                               modified = true;
46 +                       }
47 +                       else if (/^\s*(?:[\(\[\{]\s*)?via(?:\s*@\s*|\s+)[_A-Za-z0-9]+(?:\s*[\)\]\}])?(?:\s*:\s*|\s+)/i.test(body)) {
48 +                               // (via@user):...
49 +                               //  via user  ...
50 +                               chainlink = RegExp.match;
51 +                               body      = RegExp.rightContext;
52 +                               Mojo.Log.info("twitterSkipChain: skipping 'via' chain link: %j", chainlink);
53 +                               modified = true;
54 +                       }
55 +                       else {
56 +                               break;
57 +                       }
58 +               }
59 +               if (modified) {
60 +                       result = {
61 +                               body: body,
62 +                               originally_from: originally_from
63 +                       };
64 +               }
65 +               Mojo.Log.info("twitterSkipChain: returning %j", result);
66 +               return result;
67 +       },
68 +
69 +       twitterParseMessage: function (text) {
70 +               var from, originally_from, body, chain, result, match;
71 +               var mentioned = {};
72 +               var theMentioned = [];
73 +               var addMention = function (username) {
74 +                       Mojo.Log.info("ADDMENTION: %s", username);
75 +                       var usernameLower = username.toLowerCase();
76 +                       Mojo.Log.info("ADDMENTION: %s", usernameLower);
77 +                       if (!(usernameLower in mentioned)) {
78 +                               Mojo.Log.info(":)");
79 +                               mentioned[usernameLower] = true;
80 +                               theMentioned.push(username);
81 +                       }
82 +               };
83 +               Mojo.Log.info("twitterParseMessage(%j)", text);
84 +               if (/^Direct from (\S+):\s*(.*)/i.test(text)) {
85 +                       from = RegExp.$1;
86 +                       body = RegExp.$2;
87 +                       result = {
88 +                               direct: true,
89 +                               from: from,
90 +                               body: body,
91 +                               mentioned: theMentioned
92 +                       };
93 +                       addMention(from);
94 +               }
95 +               else if (/^(\S+):\s*(.*)/.test(text)) {
96 +                       from = RegExp.$1;
97 +                       originally_from = from;
98 +                       body = RegExp.$2;
99 +                       chain = this.twitterSkipChain(body);
100 +                       if (chain) {
101 +                               if ("originally_from" in chain) {
102 +                                       originally_from = chain.originally_from;
103 +                               }
104 +                               body = chain.body;
105 +                       }
106 +                       result = {
107 +                               direct: false, 
108 +                               from: from,
109 +                               originally_from: originally_from,
110 +                               body: body,
111 +                               mentioned: theMentioned
112 +                       };
113 +                       addMention(from);
114 +                       addMention(originally_from);
115 +               }
116 +
117 +               var match;
118 +               var rx_user = /\@([_A-Za-z0-9]+)/g;
119 +               while ((match = rx_user.exec(text)) !== null) {
120 +                       addMention(match[1]);
121 +               }
122 +
123 +               Mojo.Log.info("twitterParseMessage: returning %j", result);
124 +               return result;
125 +       },
126 +
127 +       twitterRetweet: function (text) {
128 +               Mojo.Log.info("twitterRetweet(%j)", text);
129 +               var tweet = this.twitterParseMessage(text);
130 +               if (tweet) {
131 +                       Mojo.Log.info("twitterRetweet: is an actionable tweet.");
132 +                       if (tweet.direct) {
133 +                               this.twitterErrorDialog("You cannot retweet a direct message.");
134 +                       }
135 +                       else {
136 +                               if (tweet.originally_from === tweet.from) {
137 +                                       this.twitterSetTextFieldValue(
138 +                                               "RT @" + tweet.originally_from + ": " + tweet.body
139 +                                       );
140 +                               }
141 +                               else {
142 +                                       this.twitterSetTextFieldValue(
143 +                                               "RT @" + tweet.originally_from +
144 +                                                       " via @" + tweet.from + ": " + tweet.body
145 +                                       );
146 +                               }
147 +                       }
148 +               }
149 +               else {
150 +                       Mojo.Log.info("twitterRetweet: is not an actionable tweet.");
151 +               }
152 +       },
153 +
154 +       twitterErrorDialog: function (error) {
155 +               this.controller.showAlertDialog({
156 +                       onChoose: function () { },
157 +                       title: $L("Error"),
158 +                       message: $L(error),
159 +                       preventCancel: false,
160 +                       choices: [{ label: $L('Dismiss'), value: 'Dismiss' }]
161 +               });
162 +       },
163 +       
164 +       twitterWarningDialog: function (warning) {
165 +               this.controller.showAlertDialog({
166 +                       onChoose: function () { },
167 +                       title: $L("Warning"),
168 +                       message: $L(warning),
169 +                       preventCancel: false,
170 +                       choices: [{ label: $L('OK'), value: 'OK' }]
171 +               });
172 +       },
173 +
174 +       twitterSetTextFieldValue: function (text) {
175 +               var self = this;
176 +               var value = this.messageTextElement.value;
177 +               if (/\S/.test(value)) {
178 +                       this.controller.showAlertDialog({
179 +                               onChoose: function (choice) {
180 +                                       if (choice) {
181 +                                               self.twitterSetTextFieldValueRaw(text);
182 +                                       }
183 +                               },
184 +                               title: "Erase existing message?",
185 +                               message: "Your current message:\n" + value,
186 +                               preventCancel: false,
187 +                               choices: [{ label: $L('Yes'), value: true },
188 +                                         { label: $L('No'),  value: false }]
189 +                       });
190 +               }
191 +               else {
192 +                       this.twitterSetTextFieldValueRaw(text);
193 +               }
194 +       },
195 +
196 +       twitterSetTextFieldValueRaw: function (text) {
197 +               this.setTextFieldValue(text);
198 +               this.moveCursorToEndOfTextField();
199 +               if (text.length > 140) {
200 +                       this.twitterWarningDialog("Your submission is longer than 140 characters. " + 
201 +                                                 "Please shorten before sending.");
202 +               }
203 +       },
204 +
205 +       twitterReply: function (text) {
206 +               Mojo.Log.info("twitterReply(%j)", text);
207 +               var tweet = this.twitterParseMessage(text);
208 +               if (tweet) {
209 +                       Mojo.Log.info("twitterReply: is an actionable tweet.");
210 +                       if (tweet.direct) {
211 +                               this.twitterSetTextFieldValue("D " + tweet.from + " ");
212 +                       }
213 +                       else {
214 +                               this.twitterSetTextFieldValue("@" + tweet.from + " ");
215 +                       }
216 +               }
217 +               else {
218 +                       Mojo.Log.info("twitterReply: is not an actionable tweet.");
219                 }
220         },
221         
222 +       twitterLeaveUser: function (text) {
223 +               Mojo.Log.info("twitterLeaveUser(%j)", text);
224 +               var tweet = this.twitterParseMessage(text);
225 +               if (tweet) {
226 +                       Mojo.Log.info("twitterLeaveUser: is an actionable tweet.");
227 +                       if (tweet.direct) {
228 +                               this.twitterSetTextFieldValue("leave " + tweet.from);
229 +                       }
230 +                       else {
231 +                               this.twitterSetTextFieldValue("leave " + tweet.from);
232 +                       }
233 +               }
234 +               else {
235 +                       Mojo.Log.info("twitterLeaveUser: is not an actionable tweet.");
236 +               }
237 +       },
238 +
239 +       moveCursorToEndOfTextField: function () {
240 +               var widget = this.controller.get('messageTextWidget');
241 +               if (widget) {
242 +                       widget = widget.mojo;
243 +               }
244 +               var len = widget.getValue().length;
245 +               widget.setCursorPosition(len, len);
246 +       },
247 +
248         /**
249          * context menu handler for tap on MMS in chat list
250          * 
251 diff --git a/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js.rej b/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js.rej
252 new file mode 100644
253 index 0000000..ae38b4e
254 --- /dev/null
255 +++ b/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js.rej
256 @@ -0,0 +1,61 @@
257 +***************
258 +*** 1807,1821 ****
259 +                       
260 +                       var composeParams;
261 +                       if ((messageType === "SMS") || (messageType === "IM")) {
262 +                               this.controller.popupSubmenu({
263 +                                       onChoose: this.handleContextMenuSelectSmsIm.bind(this, event.item.textForCopying, messageId, event.index),
264 +                                       placeNear: eventTarget.target,
265 +-                                      items: [
266 +-                                              {label: $L('Forward'), command: 'forward-cmd'},
267 +-                                              {label: $L('Forward Via Email'), command: 'forward-as-email-cmd'},
268 +-                                              {label: $L('Copy Text'), command: 'copy-cmd'},
269 +-                                              {label: $L('Delete'), command: 'delete-cmd'}
270 +-                                      ]
271 +                               });
272 +  
273 +                       } else if (messageType === "MMS") {
274 +--- 2043,2085 ----
275 +                       
276 +                       var composeParams;
277 +                       if ((messageType === "SMS") || (messageType === "IM")) {
278 ++                              var menuItems = [
279 ++                                      {label: $L('Forward'), command: 'forward-cmd'},
280 ++                                      {label: $L('Forward Via Email'), command: 'forward-as-email-cmd'},
281 ++                                      {label: $L('Copy Text'), command: 'copy-cmd'},
282 ++                                      {label: $L('Delete'), command: 'delete-cmd'}
283 ++                              ];
284 ++                              var lcDisplayName = this.chatDisplayName.toLowerCase();
285 ++                              if (lcDisplayName === "twitter" ||
286 ++                                  lcDisplayName === "40404") {
287 ++                                      var text = event.item.textForCopying;
288 ++                                      Mojo.Log.info("MOO");
289 ++                                      var tweet = this.twitterParseMessage(text);
290 ++                                      if (tweet) {
291 ++                                              if (tweet.direct) {
292 ++                                                      menuItems.push({ label: $L('DM Reply'),
293 ++                                                                       command: 'twitter-reply-cmd' });
294 ++                                              }
295 ++                                              else {
296 ++                                                      menuItems.push({ label: $L('Retweet'),
297 ++                                                                       command: 'twitter-retweet-cmd' });
298 ++                                                      menuItems.push({ label: $L('Tweet Reply'),
299 ++                                                                       command: 'twitter-reply-cmd' });
300 ++                                              }
301 ++                                              menuItems.push({ label: $L('Leave User'),
302 ++                                                               command: 'twitter-leave-user-cmd' });
303 ++                                              tweet.mentioned.forEach(function (username) {
304 ++                                                      menuItems.push({
305 ++                                                              label: "@" + username,
306 ++                                                              command: 'twitter-user:' + username
307 ++                                                      });
308 ++                                              });
309 ++                                      }
310 ++                              }
311 +                               this.controller.popupSubmenu({
312 +                                       onChoose: this.handleContextMenuSelectSmsIm.bind(this, event.item.textForCopying, messageId, event.index),
313 +                                       placeNear: eventTarget.target,
314 ++                                      items: menuItems
315 +                               });
316 +  
317 +                       } else if (messageType === "MMS") {