OSDN Git Service

Tableの背景色の設定が即座に反映されるように修正
[nt-manager/nt-manager.git] / src / twitter / gui / component / TweetTabbedTable.java
1 /*
2  * To change this template, choose Tools | Templates
3  * and open the template in the editor.
4  */
5
6 package twitter.gui.component;
7
8 import java.awt.Color;
9 import java.awt.Component;
10 import java.awt.Point;
11 import java.awt.event.KeyAdapter;
12 import java.awt.event.KeyEvent;
13 import java.awt.event.MouseAdapter;
14 import java.awt.event.MouseEvent;
15 import java.io.IOException;
16 import java.util.ArrayList;
17 import java.util.List;
18 import javax.swing.JMenuItem;
19 import javax.swing.JPopupMenu;
20 import javax.swing.JScrollPane;
21 import javax.swing.JTabbedPane;
22 import javax.swing.JTable;
23 import javax.swing.event.ListSelectionEvent;
24 import javax.swing.event.ListSelectionListener;
25 import javax.swing.table.TableCellRenderer;
26 import javax.swing.table.TableColumn;
27 import javax.swing.table.TableColumnModel;
28 import twitter.action.TweetGetter;
29 import twitter.action.list.ListGetterSelection;
30 import twitter.action.streaming.TweetStreamingListener;
31 import twitter.gui.action.TweetMainAction;
32 import twitter.manage.TweetManager;
33 import twitter4j.Status;
34 import twitter4j.TwitterException;
35
36 /**
37  * ツイートを表示するテーブルを扱うクラス
38  *
39  * @author nishio
40  */
41 public class TweetTabbedTable implements TweetStreamingListener {
42         // ツイートを表示するテーブル
43         private JTable table;
44         // ツイートを表示するテーブルのモデル
45         private TweetTableModel model;
46         // 未読のツイート数
47         private int uncheckedTweet;
48         // ツイートを取得する時に行うアクション
49         private TweetGetter tweetGetter;
50         // タブに表示される名前
51         private String title;
52         // タブ
53         private JTabbedPane tabbedPane;
54         // スクロールペーン
55         private JScrollPane scrollPane;
56         // ツイートを管理するクラス
57         private TweetManager tweetManager;
58         // メインアクション
59         private TweetMainAction mainAction;
60         // テーブルに追加できる要素の最大数
61         // TODO: ここを変更できるようにする
62         private int tableElementMaxSize = 500;
63         // 自動更新に使うタイマーのID
64         private String timerID;
65
66         /**
67          *
68          * @param tweetGetter
69          *            tweet取得時に行うアクション
70          * @param title
71          *             タブに表示するタイトル
72          * @param tabbedPane
73          *             テーブルを追加するタブ
74          * @param tweetManager
75          *             ツイート管理クラス
76          * @param mainAction
77          *            メインアクション
78          * @param tableElementMaxSize
79          *            テーブルに格納できる要素の最大数
80          * @param timerID
81          *            自動更新につかうタイマーのID
82          */
83         public TweetTabbedTable(TweetGetter tweetGetter, String title,
84                         JTabbedPane tabbedPane,
85                         TweetManager tweetManager, TweetMainAction mainAction,
86                         int tableElementMaxSize, String timerID) {
87                 this.tweetGetter = tweetGetter;
88                 this.title = title;
89                 this.tabbedPane = tabbedPane;
90                 this.tweetManager = tweetManager;
91                 this.mainAction = mainAction;
92                 this.tableElementMaxSize = tableElementMaxSize;
93                 this.timerID = timerID;
94
95                 table = new JTable();
96                 model = new TweetTableModel();
97                 uncheckedTweet = 0;
98                 scrollPane = new JScrollPane();
99                 tweetGetter.setUpdateListener(this);
100         }
101
102         /**
103          * Tweet情報を表示するテーブルをタブに追加
104          */
105         public void addTableToTab() {
106                 // テーブルをタブに追加
107                 getTable().setModel(model);
108                 getTable().getTableHeader().setReorderingAllowed(false);
109                 getTable().addMouseListener(new java.awt.event.MouseAdapter() {
110                         @Override
111                         public void mousePressed(java.awt.event.MouseEvent evt) {
112                                 jTableMousePressed(evt);
113                         }
114
115                         @Override
116                         public void mouseReleased(java.awt.event.MouseEvent evt) {
117                                 jTableMouseReleased(evt);
118                         }
119                 });
120
121                 // tweetを表示するテーブルを作成
122                 createTweetTable(getTable());
123
124                 // スクロールペーン追加
125                 scrollPane.setViewportView(getTable());
126                 // タブにテーブル追加
127                 tabbedPane.addTab(this.title, scrollPane);
128         }
129
130         /**
131          * Tweetを表示するテーブルを作成
132          *
133          * @param model
134          * @return
135          */
136         private void createTweetTable(final JTable table) {
137
138                 table.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
139                 table.setShowVerticalLines(false);
140                 table.setShowHorizontalLines(true);
141
142                 // Comment部分のColumnを複数行コメントが表示できるようにする
143                 TableColumnModel mdl = table.getColumnModel();
144                 TableColumn col = mdl.getColumn(1);
145                 TweetCommentRenderer commentRenderer = new TweetCommentRenderer(this.mainAction);
146                 col.setCellRenderer(commentRenderer);
147                 // INfo部分のColumnを複数行表示できるように
148                 TweetCommentRenderer infoRenderer = new TweetCommentRenderer(this.mainAction);
149                 col = mdl.getColumn(2);
150                 col.setCellRenderer(infoRenderer);
151                 col.setMaxWidth(200);
152                 col.setMinWidth(150);
153                 // ユーザImageを表示する部分
154                 col = mdl.getColumn(0);
155                 col.setCellRenderer(new UserImageRenderer());
156                 //テーブルの高さ調節
157                 col.setMinWidth(mainAction.getTableElementHeight());
158                 col.setMaxWidth(mainAction.getTableElementHeight());
159                 // 選択したセルの情報をDetailInfoへと表示
160                 // JTableを右クリックでも選択できるようにする
161                 // また,同じ行を2回クリックできるようにする
162                 table.addMouseListener(new MouseAdapter() {
163
164                         @Override
165                         public void mousePressed(MouseEvent e) {
166                                 // いったんSelectしていた情報を削除
167                                 table.clearSelection();
168                                 // if (e.getButton() == MouseEvent.BUTTON3) {
169                                 Point p = e.getPoint();
170                                 int col = table.columnAtPoint(p);
171                                 int row = table.rowAtPoint(p);
172                                 table.changeSelection(row, col, false, false);
173
174                                 // テーブルで選択した要素を詳細情報として表示
175                                 mainAction.setDetailInformationFromTable(table);
176                                 // }
177                         }
178                 });
179                 // キー受付
180                 table.addKeyListener(new KeyAdapter() {
181
182                         @Override
183                         public void keyReleased(KeyEvent ke) {
184                                 mainAction.setDetailInformationFromTable(table);
185                         }
186
187                 });
188                 // MouseEventを追加
189                 table.addMouseListener(commentRenderer);
190                 // table.addMouseMotionListener(commentRenderer);
191                 table.addMouseListener(infoRenderer);
192                 // table.addMouseMotionListener(infoRenderer);
193         }
194
195         /**
196          * テーブル情報更新
197          */
198         public void updateTweetTable() {
199                 try {
200                         // API残り回数を取得
201                         int remainingHits = tweetManager.getRateLimitStatus()
202                                         .getRemainingHits();
203                         if (remainingHits <= 0) {
204                                 return;
205                         }
206                         // ツイート情報
207                         List<Status> tweet = tweetGetter.getNewTweetData();
208
209                         // テーブル更新
210                         int newNum = updateTable(tweet);
211
212                         // 情報を取得したことをステータスバーに表示
213                         mainAction.information(this.getTitle() + "タブのツイートを" + newNum
214                                         + "件取得しました. (APIリクエスト残数は" + remainingHits + "回です)");
215
216                 } catch (TwitterException e1) {
217                         e1.printStackTrace();
218                 } catch (Exception e) {
219                         e.printStackTrace();
220                 }
221         }
222
223         /**
224          * テーブルにツイート追加
225          *
226          * @param tweet
227          * @return
228          */
229         private int updateTable(List<Status> tweet) {
230                 if( tweet == null ) {
231                         return 0;
232                 }
233                 // まだ見ていないtweet数を追加
234                 this.setUncheckedTweet(this.getUncheckedTweet() + tweet.size());
235                 //grid線を削除する
236                 this.getTable().setShowGrid(false);
237
238                 // まだチェックしていないtweetの数をタブにも表示
239                 if (this.getUncheckedTweet() > 0) {
240                         tabbedPane.setTitleAt(this.getTabSetNum(),
241                                         this.title + "(" + this.getUncheckedTweet() + ")");
242                 }
243                 // ツイートをテーブルに追加
244                 this.getModel().insertTweet(tweet);
245                 // テーブルの高さを整える
246                 int tableHeight = mainAction.getTableElementHeight();
247                 for (int i = 0; i < tweet.size(); i++) {
248                         this.getTable().setRowHeight(i, tableHeight);
249                 }
250                 /*
251                  * for (Status t : tweet) { this.getModel().insertTweet(t);
252                  * this.getTable().setRowHeight(0, getTableElementHeight()); }
253                  */
254                 // 新規した部分の背景色を変更
255                 TableCellRenderer renderer = getTable().getCellRenderer(0, 2);
256                 if (renderer instanceof TweetCommentRenderer) {
257                         if (this.getUncheckedTweet() - 1 >= 0) {
258                                 ((TweetCommentRenderer) renderer).updateNewCellRow(this.getUncheckedTweet());
259                         } else {
260                                 ((TweetCommentRenderer) renderer).updateNewCellRow(-1);
261                         }
262                 }
263                 // 古いデータを削除
264                 getModel().removeOldTweet(getTableElementMaxSize());
265                 // 時間情報リフレッシュ
266                 getModel().refreshTime();
267                 // 新しい情報
268                 int newNum = 0;
269                 if (tweet != null) {
270                         newNum = tweet.size();
271                 }
272                 // 情報間隔毎に設定を保存
273                 try {
274                         this.mainAction.saveProperties();
275                 } catch (IOException e) {
276                         // TODO 自動生成された catch ブロック
277                         e.printStackTrace();
278                 }
279
280                 return newNum;
281         }
282
283         /**
284          * マウスクリック時の動作
285          *
286          * @param evt
287          */
288         private void jTableMousePressed(java.awt.event.MouseEvent evt) {
289                 // 右クリックメニュー表示
290                 showPopup(evt);
291                 // 未読ツイート分を0にする
292                 this.setUncheckedTweet(0);
293                 this.setTitle(this.getTitle());
294         }
295
296         /**
297          * マウスリリース時の動作
298          *
299          * @param evt
300          */
301         private void jTableMouseReleased(java.awt.event.MouseEvent evt) {
302                 // 右クリックメニュー表示
303                 showPopup(evt);
304         }
305
306         /**
307          * ポップアップメニューを作成
308          *
309          * @param e
310          */
311         private void showPopup(MouseEvent e) {
312                 if (e.isPopupTrigger()) {
313                         // 右クリックのメニューを表示
314                         getRightClickPopup().show(e.getComponent(), e.getX(), e.getY());
315                 }
316         }
317
318         /**
319          * 右クリックを押した時のポップアップメニューを取得
320          *
321          * @return
322          */
323         private JPopupMenu getRightClickPopup() {
324                 // if (rightClickPopup == null) {
325                 JPopupMenu rightClickPopup = new JPopupMenu();
326
327                 JMenuItem replyMenuItem = new JMenuItem("この発言に返信(Reply)");
328                 replyMenuItem.setMnemonic('R');
329                 replyMenuItem.addActionListener(new java.awt.event.ActionListener() {
330
331                         public void actionPerformed(java.awt.event.ActionEvent e) {
332                                 // 選択したセルのステータスにreply
333                                 mainAction.actionSetReplyStatusToTweetBoxPane();
334                         }
335                 });
336
337                 JMenuItem replyAllMenuItem = new JMenuItem("この発言に返信(Reply All)");
338                 replyAllMenuItem.setMnemonic('A');
339                 replyAllMenuItem.addActionListener(new java.awt.event.ActionListener() {
340
341                         public void actionPerformed(java.awt.event.ActionEvent e) {
342                                 // 選択したセルのステータスにreply all
343                                 mainAction.actionSetReplyAllStatusToTweetBoxPane();
344                         }
345                 });
346
347                 JMenuItem retweetMenuItem = new JMenuItem("発言を公式リツイート(RT)");
348                 retweetMenuItem.setMnemonic('R');
349                 retweetMenuItem.addActionListener(new java.awt.event.ActionListener() {
350
351                         @Override
352                         public void actionPerformed(java.awt.event.ActionEvent e) {
353                                 // 選択したセルのステータスをRetweet
354                                 mainAction.actionRetweet();
355                         }
356                 });
357
358                 JMenuItem quoteMenuItem = new JMenuItem("発言を引用ツイート(QT)");
359                 quoteMenuItem.setMnemonic('Q');
360                 quoteMenuItem.addActionListener(new java.awt.event.ActionListener() {
361
362                         @Override
363                         public void actionPerformed(java.awt.event.ActionEvent e) {
364                                 // 選択したセルのステータスをQT
365                                 mainAction.actionSetQuoteStatusToTweetBoxPane();
366                         }
367                 });
368
369                 JMenuItem unofficialRetweetMenuItem = new JMenuItem(
370                                 "発言をコメント付きリツイート(非公式RT)");
371                 unofficialRetweetMenuItem.setMnemonic('T');
372                 unofficialRetweetMenuItem
373                                 .addActionListener(new java.awt.event.ActionListener() {
374
375                                         @Override
376                                         public void actionPerformed(java.awt.event.ActionEvent e) {
377                                                 // 選択したセルのステータスをコメント付Retweet
378                                                 mainAction.actionCopySelectedStatusToTweetBoxPane();
379                                         }
380                                 });
381
382                 JMenuItem directMessageMenuItem = new JMenuItem("ダイレクトメッセージを送信(D)");
383                 directMessageMenuItem.setMnemonic('D');
384                 directMessageMenuItem
385                                 .addActionListener(new java.awt.event.ActionListener() {
386
387                                         @Override
388                                         public void actionPerformed(java.awt.event.ActionEvent e) {
389                                                 // ダイレクトメッセージ送信ダイアログを表示
390                                                 mainAction.actionShowDirectMessageDialog();
391                                         }
392                                 });
393
394                 JMenuItem statusBrowserMenuItem = new JMenuItem("この発言をブラウザで開く(O)");
395                 statusBrowserMenuItem.setMnemonic('O');
396                 statusBrowserMenuItem
397                                 .addActionListener(new java.awt.event.ActionListener() {
398
399                                         @Override
400                                         public void actionPerformed(java.awt.event.ActionEvent e) {
401                                                 // 選択したセルのステータスをブラウザで開く
402                                                 mainAction.actionOpenStatusURL();
403                                         }
404                                 });
405
406                 JMenuItem userMenuItem = new JMenuItem("この人の発言を別タブで開く(U)");
407                 userMenuItem.setMnemonic('U');
408                 userMenuItem.addActionListener(new java.awt.event.ActionListener() {
409
410                         @Override
411                         public void actionPerformed(java.awt.event.ActionEvent e) {
412                                 // 指定した人の発言を開く
413                                 mainAction.actionSelectedUserTimeline();
414                         }
415                 });
416
417                 JMenuItem createFavMenuItem = new JMenuItem("この発言をお気に入りに追加(F)");
418                 createFavMenuItem.setMnemonic('F');
419                 createFavMenuItem
420                                 .addActionListener(new java.awt.event.ActionListener() {
421
422                                         @Override
423                                         public void actionPerformed(java.awt.event.ActionEvent e) {
424                                                 // 選択したセルのユーザ情報をブラウザで開く
425                                                 mainAction.actionCreateFavorite();
426                                         }
427                                 });
428
429                 JMenuItem destroyFavMenuItem = new JMenuItem("この発言をお気に入りから削除");
430                 destroyFavMenuItem
431                                 .addActionListener(new java.awt.event.ActionListener() {
432
433                                         @Override
434                                         public void actionPerformed(java.awt.event.ActionEvent e) {
435                                                 // 選択したセルのユーザ情報をブラウザで開く
436                                                 mainAction.actionDestroyFavorite();
437                                         }
438                                 });
439
440                 JMenuItem createdListMenuItem = new JMenuItem("このユーザが作成したリスト一覧");
441                 createdListMenuItem
442                                 .addActionListener(new java.awt.event.ActionListener() {
443
444                                         @Override
445                                         public void actionPerformed(java.awt.event.ActionEvent e) {
446                                                 // 選択したセルのユーザ情報をブラウザで開く
447                                                 mainAction
448                                                                 .actionShowSelectedUserList(ListGetterSelection.CREATED);
449                                         }
450                                 });
451
452                 JMenuItem subscriptionListMenuItem = new JMenuItem("このユーザが購読しているリスト一覧");
453                 subscriptionListMenuItem
454                                 .addActionListener(new java.awt.event.ActionListener() {
455
456                                         @Override
457                                         public void actionPerformed(java.awt.event.ActionEvent e) {
458                                                 // 選択したセルのユーザ情報をブラウザで開く
459                                                 mainAction
460                                                                 .actionShowSelectedUserList(ListGetterSelection.SUBSCRIPTION);
461                                         }
462                                 });
463
464                 JMenuItem membershipsListMenuItem = new JMenuItem(
465                                 "このユーザがフォローされているリスト一覧");
466                 membershipsListMenuItem
467                                 .addActionListener(new java.awt.event.ActionListener() {
468
469                                         @Override
470                                         public void actionPerformed(java.awt.event.ActionEvent e) {
471                                                 // 選択したセルのユーザ情報をブラウザで開く
472                                                 mainAction
473                                                                 .actionShowSelectedUserList(ListGetterSelection.MEMBERSHIPS);
474                                         }
475                                 });
476
477                 JMenuItem followingUserMenuItem = new JMenuItem("このユーザがフォローしているユーザ一覧");
478                 followingUserMenuItem
479                                 .addActionListener(new java.awt.event.ActionListener() {
480
481                                         @Override
482                                         public void actionPerformed(java.awt.event.ActionEvent e) {
483                                                 // 選択したセルのユーザ情報をブラウザで開く
484                                                 mainAction.actionOpenFollowing();
485                                         }
486                                 });
487
488                 JMenuItem followerUserMenuItem = new JMenuItem("このユーザがフォローされているユーザ一覧");
489                 followerUserMenuItem
490                                 .addActionListener(new java.awt.event.ActionListener() {
491
492                                         @Override
493                                         public void actionPerformed(java.awt.event.ActionEvent e) {
494                                                 // 選択したセルのユーザ情報をブラウザで開く
495                                                 mainAction.actionOpenFollower();
496                                         }
497                                 });
498
499                 // 指定した発言がRTかどうか判定
500                 int sc = table.getSelectedRowCount();
501                 if (sc == 1 && table != null) {
502                         Status st = mainAction.getTweetTableInformation(table,
503                                         table.getModel());
504
505                         JMenuItem openBrowserUserInformationMenuItem = new JMenuItem(
506                                         "この人の発言をブラウザで開く(B)");
507                         openBrowserUserInformationMenuItem.setMnemonic('B');
508                         openBrowserUserInformationMenuItem
509                                         .addActionListener(new java.awt.event.ActionListener() {
510
511                                                 @Override
512                                                 public void actionPerformed(java.awt.event.ActionEvent e) {
513                                                         // 選択したセルのユーザ情報をブラウザで開く
514                                                         mainAction.actionOpenUserURL();
515                                                 }
516                                         });
517
518                         JMenuItem openFavMenuItem = new JMenuItem("この人のお気に入りを開く");
519                         openFavMenuItem
520                                         .addActionListener(new java.awt.event.ActionListener() {
521
522                                                 @Override
523                                                 public void actionPerformed(java.awt.event.ActionEvent e) {
524                                                         // 選択したセルのユーザ情報をブラウザで開く
525                                                         mainAction.actionOpenUserFav();
526                                                 }
527                                         });
528
529                         // メニューアイテムを追加
530                         // 返信
531                         rightClickPopup.add(replyMenuItem);
532                         // 返信all
533                         rightClickPopup.add(replyAllMenuItem);
534                         // 公式RT
535                         rightClickPopup.add(retweetMenuItem);
536                         // 非公式RT
537                         rightClickPopup.add(unofficialRetweetMenuItem);
538                         // QT
539                         rightClickPopup.add(quoteMenuItem);
540                         // ダイレクトメッセージ
541                         rightClickPopup.add(directMessageMenuItem);
542                         // 発言をブラウザで開く
543                         rightClickPopup.add(statusBrowserMenuItem);
544                         // この人の発言を別タブで開く
545                         rightClickPopup.add(userMenuItem);
546                         // この人のtimelineを開く
547                         rightClickPopup.add(openBrowserUserInformationMenuItem);
548                         // この人のfavを開く
549                         rightClickPopup.add(openFavMenuItem);
550                         // この人のfollowing開く
551                         rightClickPopup.add(followingUserMenuItem);
552                         // この人のfollower開く
553                         rightClickPopup.add(followerUserMenuItem);
554                         // この人が作成したリスト
555                         rightClickPopup.add(createdListMenuItem);
556                         // この人が購読しているリスト
557                         rightClickPopup.add(subscriptionListMenuItem);
558                         // この人がフォローされているリスト一覧
559                         rightClickPopup.add(membershipsListMenuItem);
560
561                         try {
562                                 if (st.isRetweet()) {
563                                         // Retweetのときのみ表示するメニュー
564                                 }
565                                 if (st.isFavorited()) {
566                                         // お気に入りに追加されている時のみ表示するメニュー
567                                         // お気に入り追加
568                                         rightClickPopup.add(destroyFavMenuItem);
569                                 } else {
570                                         rightClickPopup.add(createFavMenuItem);
571                                 }
572                         } catch (Exception e) {
573                                 // TODO:ここの無視部分をなんとかする
574                                 // DMのときはisFavoritedができない
575                         }
576                 }
577                 // }
578                 return rightClickPopup;
579         }
580
581         /**
582          * tweetGetterを取得します。
583          * @return tweetGetter
584          */
585         public TweetGetter getTweetGetter() {
586             return tweetGetter;
587         }
588
589         /**
590          * tweetGetterを設定します。
591          * @param tweetGetter tweetGetter
592          */
593         public void setTweetGetter(TweetGetter tweetGetter) {
594             this.tweetGetter = tweetGetter;
595         }
596
597         /**
598          * @return the title
599          */
600         public String getTitle() {
601                 return title;
602         }
603
604         /**
605          * @param title
606          *            the title to set
607          */
608         public void setTitle(String title) {
609                 this.title = title;
610                 this.tabbedPane.setTitleAt(this.getTabSetNum(), title);
611         }
612
613         /**
614          * 自分自信がタブのどの場所に位置しているのかを取得
615          *
616          * @return
617          */
618         public int getTabSetNum() {
619                 int tabCount = this.tabbedPane.getTabCount();
620                 for (int i = 0; i < tabCount; i++) {
621                         Component c = this.tabbedPane.getComponentAt(i);
622                         if (c instanceof JScrollPane) {
623                                 if (c == this.scrollPane) {
624                                         return i;
625                                 }
626                         }
627                 }
628                 return 0;
629         }
630
631         /**
632          * @return the tableElementMaxSize
633          */
634         public int getTableElementMaxSize() {
635                 return tableElementMaxSize;
636         }
637
638         /**
639          * @param tableElementMaxSize
640          *            the tableElementMaxSize to set
641          */
642         public void setTableElementMaxSize(int tableElementMaxSize) {
643                 this.tableElementMaxSize = tableElementMaxSize;
644         }
645
646         /**
647          * @return the model
648          */
649         public TweetTableModel getModel() {
650                 return model;
651         }
652
653         /**
654          * @param model
655          *            the model to set
656          */
657         public void setModel(TweetTableModel model) {
658                 this.model = model;
659         }
660
661         /**
662          * @return the uncheckedTweet
663          */
664         public int getUncheckedTweet() {
665                 return uncheckedTweet;
666         }
667
668         /**
669          * @param uncheckedTweet
670          *            the uncheckedTweet to set
671          */
672         public void setUncheckedTweet(int uncheckedTweet) {
673                 this.uncheckedTweet = uncheckedTweet;
674         }
675
676         /**
677          * @return the timerID
678          */
679         public String getTimerID() {
680                 return timerID;
681         }
682
683         /**
684          * @return the table
685          */
686         public JTable getTable() {
687                 return table;
688         }
689
690         /**
691          * streaming api側からupdateされるもの
692          */
693         @Override
694         public void update(Status status) {
695                 List<Status> tweet = new ArrayList<Status>();
696                 tweet.add(status);
697                 updateTable(tweet);
698         }
699
700 }