4 New, 2 updated patches.
[webos-internals:imagineer1981s-modifications.git] / messaging / messaging-poor-mans-twitter-client.patch
1 Index: /usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
2 ===================================================================
3 --- .orig/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
4 +++ /usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
5 @@ -1669,9 +1669,210 @@
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                 }
19         },
20         
21 +       twitterSkipChain: function (body) {
22 +               var originally_from, chainlink, result;
23 +               var modified = false;
24 +               Mojo.Log.info("twitterSkipChain(%j)", body);
25 +               while (true) {
26 +                       // skip past any RT/via chains.
27 +                       if (/^\s*rt(?:\s*@\s*|\s+)([_A-Za-z0-9]+)(?:\s*:\s*|\s+)/i.test(body)) {
28 +                               // RT@user:... (space optional before or after @ and :)
29 +                               // RT user ...
30 +                               chainlink       = RegExp.match;
31 +                               originally_from = RegExp.$1;
32 +                               body            = RegExp.rightContext;
33 +                               Mojo.Log.info("twitterSkipChain: skipping 'RT' chain link: %j", chainlink);
34 +                               modified = true;
35 +                       }
36 +                       else if (/^\s*(?:[\(\[\{]\s*)?via(?:\s*@\s*|\s+)[_A-Za-z0-9]+(?:\s*[\)\]\}])?(?:\s*:\s*|\s+)/i.test(body)) {
37 +                               // (via@user):...
38 +                               //  via user  ...
39 +                               chainlink = RegExp.match;
40 +                               body      = RegExp.rightContext;
41 +                               Mojo.Log.info("twitterSkipChain: skipping 'via' chain link: %j", chainlink);
42 +                               modified = true;
43 +                       }
44 +                       else {
45 +                               break;
46 +                       }
47 +               }
48 +               if (modified) {
49 +                       result = {
50 +                               body: body,
51 +                               originally_from: originally_from
52 +                       };
53 +               }
54 +               Mojo.Log.info("twitterSkipChain: returning %j", result);
55 +               return result;
56 +       },
57 +
58 +       twitterParseMessage: function (text) {
59 +               var from, originally_from, body, chain, result;
60 +               Mojo.Log.info("twitterParseMessage(%j)", text);
61 +               if (/^Direct from (\S+):\s*(.*)/i.test(text)) {
62 +                       from = RegExp.$1;
63 +                       body = RegExp.$2;
64 +                       result = {
65 +                               direct: true,
66 +                               from: from,
67 +                               body: body
68 +                       };
69 +               }
70 +               else if (/^(\S+):\s*(.*)/.test(text)) {
71 +                       from = RegExp.$1;
72 +                       originally_from = from;
73 +                       body = RegExp.$2;
74 +                       chain = this.twitterSkipChain(body);
75 +                       if (chain) {
76 +                               if ("originally_from" in chain) {
77 +                                       originally_from = chain.originally_from;
78 +                               }
79 +                               body = chain.body;
80 +                       }
81 +                       result = {
82 +                               direct: false, 
83 +                               from: from,
84 +                               originally_from: originally_from,
85 +                               body: body
86 +                       };
87 +               }
88 +               Mojo.Log.info("twitterParseMessage: returning %j", result);
89 +               return result;
90 +       },
91 +
92 +       twitterRetweet: function (text) {
93 +               Mojo.Log.info("twitterRetweet(%j)", text);
94 +               var tweet = this.twitterParseMessage(text);
95 +               if (tweet) {
96 +                       Mojo.Log.info("twitterRetweet: is an actionable tweet.");
97 +                       if (tweet.direct) {
98 +                               this.twitterErrorDialog("You cannot retweet a direct message.");
99 +                       }
100 +                       else {
101 +                               if (tweet.originally_from === tweet.from) {
102 +                                       this.twitterSetTextFieldValue(
103 +                                               "RT @" + tweet.originally_from + ": " + tweet.body
104 +                                       );
105 +                               }
106 +                               else {
107 +                                       this.twitterSetTextFieldValue(
108 +                                               "RT @" + tweet.originally_from +
109 +                                                       " via @" + tweet.from + ": " + tweet.body
110 +                                       );
111 +                               }
112 +                       }
113 +               }
114 +               else {
115 +                       Mojo.Log.info("twitterRetweet: is not an actionable tweet.");
116 +               }
117 +       },
118 +
119 +       twitterErrorDialog: function (error) {
120 +               this.controller.showAlertDialog({
121 +                       onChoose: function () { },
122 +                       title: $L("Error"),
123 +                       message: $L(error),
124 +                       preventCancel: false,
125 +                       choices: [{ label: $L('Dismiss'), value: 'Dismiss' }]
126 +               });
127 +       },
128 +       
129 +       twitterWarningDialog: function (warning) {
130 +               this.controller.showAlertDialog({
131 +                       onChoose: function () { },
132 +                       title: $L("Warning"),
133 +                       message: $L(warning),
134 +                       preventCancel: false,
135 +                       choices: [{ label: $L('OK'), value: 'OK' }]
136 +               });
137 +       },
138 +
139 +       twitterSetTextFieldValue: function (text) {
140 +               var self = this;
141 +               var value = this.messageTextElement.value;
142 +               if (/\S/.test(value)) {
143 +                       this.controller.showAlertDialog({
144 +                               onChoose: function (choice) {
145 +                                       if (choice) {
146 +                                               self.twitterSetTextFieldValueRaw(text);
147 +                                       }
148 +                               },
149 +                               title: "Erase existing message?",
150 +                               message: "Your current message:\n" + value,
151 +                               preventCancel: false,
152 +                               choices: [{ label: $L('Yes'), value: true },
153 +                                         { label: $L('No'),  value: false }]
154 +                       });
155 +               }
156 +               else {
157 +                       this.twitterSetTextFieldValueRaw(text);
158 +               }
159 +       },
160 +
161 +       twitterSetTextFieldValueRaw: function (text) {
162 +               this.setTextFieldValue(text);
163 +               this.moveCursorToEndOfTextField();
164 +               if (text.length > 140) {
165 +                       this.twitterWarningDialog("Your submission is longer than 140 characters. " + 
166 +                                                 "Please shorten before sending.");
167 +               }
168 +       },
169 +
170 +       twitterReply: function (text) {
171 +               Mojo.Log.info("twitterReply(%j)", text);
172 +               var tweet = this.twitterParseMessage(text);
173 +               if (tweet) {
174 +                       Mojo.Log.info("twitterReply: is an actionable tweet.");
175 +                       if (tweet.direct) {
176 +                               this.twitterSetTextFieldValue("D " + tweet.from + " ");
177 +                       }
178 +                       else {
179 +                               this.twitterSetTextFieldValue("@" + tweet.from + " ");
180 +                       }
181 +               }
182 +               else {
183 +                       Mojo.Log.info("twitterReply: is not an actionable tweet.");
184 +               }
185 +       },
186 +       
187 +       twitterLeaveUser: function (text) {
188 +               Mojo.Log.info("twitterLeaveUser(%j)", text);
189 +               var tweet = this.twitterParseMessage(text);
190 +               if (tweet) {
191 +                       Mojo.Log.info("twitterLeaveUser: is an actionable tweet.");
192 +                       if (tweet.direct) {
193 +                               this.twitterSetTextFieldValue("leave " + tweet.from);
194 +                       }
195 +                       else {
196 +                               this.twitterSetTextFieldValue("leave " + tweet.from);
197 +                       }
198 +               }
199 +               else {
200 +                       Mojo.Log.info("twitterLeaveUser: is not an actionable tweet.");
201 +               }
202 +       },
203 +
204 +       moveCursorToEndOfTextField: function () {
205 +               var widget = this.controller.get('messageTextWidget');
206 +               if (widget) {
207 +                       widget = widget.mojo;
208 +               }
209 +               var len = widget.getValue().length;
210 +               widget.setCursorPosition(len, len);
211 +       },
212 +
213         /**
214          * context menu handler for tap on MMS in chat list
215          * 
216 @@ -1794,14 +1995,31 @@
217                         
218                         var composeParams;
219                         if ((messageType == "SMS") || (messageType == "IM")) {
220 -                               this.controller.popupSubmenu({
221 -                                       onChoose: this.handleContextMenuSelectSmsIm.bind(this, event.item.textForCopying, messageId, event.index),
222 -                                       placeNear: eventTarget.target,
223 -                                       items: [
224 +                               var menuItems = [
225                                                 {label: $L('Forward'), command: 'forward-cmd'},
226                                                 {label: $L('Copy Text'), command: 'copy-cmd'},
227                                                 {label: $L('Delete'), command: 'delete-cmd'}
228 -                                       ]
229 +                               ];
230 +                               var lcDisplayName = this.chatDisplayName.toLowerCase();
231 +                               if (lcDisplayName === "twitter" ||
232 +                                   lcDisplayName === "40404") {
233 +                                       var text = event.item.textForCopying;
234 +                                       var tweet = this.twitterParseMessage(text);
235 +                                       if (tweet) {
236 +                                               if (!tweet.direct) {
237 +                                                       menuItems.push({ label: $L('Retweet'),
238 +                                                                        command: 'twitter-retweet-cmd' });
239 +                                               }
240 +                                               menuItems.push({ label: $L('Reply'),
241 +                                                                command: 'twitter-reply-cmd' });
242 +                                               menuItems.push({ label: $L('Leave User'),
243 +                                                                command: 'twitter-leave-user-cmd' });
244 +                                       }
245 +                               }
246 +                               this.controller.popupSubmenu({
247 +                                       onChoose: this.handleContextMenuSelectSmsIm.bind(this, event.item.textForCopying, messageId, event.index),
248 +                                       placeNear: eventTarget.target,
249 +                                       items: menuItems
250                                 });
251  
252                         } else if (messageType == "MMS") {