11package com .codepath .apps .mysimpletweets .activities ;
22
3+ import android .content .Intent ;
4+ import android .support .v4 .app .FragmentManager ;
35import android .support .v4 .widget .SwipeRefreshLayout ;
6+ import android .support .v7 .app .ActionBar ;
47import android .support .v7 .app .ActionBarActivity ;
58import android .os .Bundle ;
69import android .util .Log ;
710import android .view .Menu ;
811import android .view .MenuItem ;
912import android .widget .ListView ;
13+ import android .widget .ProgressBar ;
14+ import android .widget .Toast ;
1015
1116import com .codepath .apps .mysimpletweets .R ;
1217import com .codepath .apps .mysimpletweets .TwitterApplication ;
1318import com .codepath .apps .mysimpletweets .TwitterClient ;
19+ import com .codepath .apps .mysimpletweets .adapters .EndlessScrollListener ;
1420import com .codepath .apps .mysimpletweets .adapters .TweetsArrayAdapter ;
21+ import com .codepath .apps .mysimpletweets .fragments .TweetFragment ;
22+ import com .codepath .apps .mysimpletweets .models .CacheManager ;
1523import com .codepath .apps .mysimpletweets .models .Tweet ;
24+ import com .codepath .apps .mysimpletweets .models .User ;
25+ import com .codepath .apps .mysimpletweets .utils .ConnectivityHelper ;
1626import com .loopj .android .http .JsonHttpResponseHandler ;
1727
1828import org .apache .http .Header ;
2131
2232import java .util .ArrayList ;
2333
24- public class TimelineActivity extends ActionBarActivity {
34+ import butterknife .ButterKnife ;
35+ import butterknife .InjectView ;
36+ import butterknife .OnClick ;
37+ import butterknife .OnItemClick ;
38+ import butterknife .OnItemSelected ;
39+
40+ public class TimelineActivity extends ActionBarActivity implements TweetFragment .TweetFragmentListener {
2541
2642 private static final String TAG = TimelineActivity .class .getName ();
2743
2844 private TwitterClient client ;
2945 private ArrayList <Tweet > tweets ;
3046 private TweetsArrayAdapter aTweets ;
31- private ListView lvTweets ;
32- private SwipeRefreshLayout swipeContainer ;
47+ @ InjectView (R .id .lvTweets ) ListView lvTweets ;
48+ @ InjectView (R .id .swipeContainer ) SwipeRefreshLayout swipeContainer ;
49+ @ InjectView (R .id .pbLoading ) ProgressBar progressBar ;
50+
51+ private long max_id ;
52+ private User currentUser ;
3353
3454 @ Override
3555 protected void onCreate (Bundle savedInstanceState ) {
3656 super .onCreate (savedInstanceState );
3757 setContentView (R .layout .activity_timeline );
38- lvTweets = (ListView ) findViewById (R .id .lvTweets );
58+ ButterKnife .inject (this );
59+ lvTweets .setOnScrollListener (new EndlessScrollListener () {
60+ @ Override
61+ public void onLoadMore (int page , int totalItemsCount ) {
62+ // Triggered only when new data needs to be appended to the list
63+ // Add whatever code is needed to append new items to your AdapterView
64+ customLoadMoreDataFromApi (page );
65+ // or customLoadMoreDataFromApi(totalItemsCount);
66+ }
67+ });
3968 tweets = new ArrayList <>();
4069 aTweets = new TweetsArrayAdapter (this , tweets );
4170 lvTweets .setAdapter (aTweets );
4271 client = TwitterApplication .getRestClient ();
72+ aTweets .addAll (CacheManager .latestTweets ());
73+ populateCurrentUser ();
74+ max_id = 0 ;
4375 populateTimeline ();
4476
45- swipeContainer = (SwipeRefreshLayout ) findViewById (R .id .swipeContainer );
4677 // Setup refresh listener which triggers new data loading
4778 swipeContainer .setOnRefreshListener (new SwipeRefreshLayout .OnRefreshListener () {
4879 @ Override
4980 public void onRefresh () {
5081 // Your code to refresh the list here.
5182 // Make sure you call swipeContainer.setRefreshing(false)
5283 // once the network request has completed successfully.
84+ max_id = 0 ;
85+ populateCurrentUser ();
5386 populateTimeline ();
5487 }
5588 });
@@ -60,13 +93,12 @@ public void onRefresh() {
6093 android .R .color .holo_red_light );
6194 }
6295
63- private void populateTimeline () {
64- client .getHomeTimeline (new JsonHttpResponseHandler () {
96+ private void populateCurrentUser () {
97+ client .getCurrentUser (new JsonHttpResponseHandler () {
6598 @ Override
66- public void onSuccess (int statusCode , Header [] headers , JSONArray json ) {
67- aTweets .clear ();
68- aTweets .addAll (Tweet .fromJSON (json ));
69- swipeContainer .setRefreshing (false );
99+ public void onSuccess (int statusCode , Header [] headers , JSONObject response ) {
100+ currentUser = User .fromJSON (response );
101+ Log .d (TAG , "user populated: " + currentUser .getScreenName ());
70102 }
71103
72104 @ Override
@@ -76,6 +108,47 @@ public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSO
76108 });
77109 }
78110
111+ // Append more data into the adapter
112+ public void customLoadMoreDataFromApi (int offset ) {
113+ // Log.d(TAG, "page = " + offset);
114+ populateTimeline ();
115+ // This method probably sends out a network request and appends new data items to your adapter.
116+ // Use the offset value and add it as a parameter to your API request to retrieve paginated data.
117+ // Deserialize API response and then construct new objects to append to the adapter
118+ }
119+
120+ private void populateTimeline () {
121+ if (!ConnectivityHelper .isNetworkAvailable (this )) {
122+ ConnectivityHelper .notifyUserAboutNoInternetConnectivity (this );
123+ } else {
124+ progressBar .setVisibility (ProgressBar .VISIBLE );
125+ client .getHomeTimeline (max_id , new JsonHttpResponseHandler () {
126+ @ Override
127+ public void onSuccess (int statusCode , Header [] headers , JSONArray json ) {
128+ if (max_id == 0 ) {
129+ aTweets .clear ();
130+ }
131+ ArrayList <Tweet > responseTweets = Tweet .fromJSON (json );
132+ // Fire and forget
133+ CacheManager .saveTweets (responseTweets );
134+ aTweets .addAll (responseTweets );
135+ Tweet lastTweet = aTweets .getItem (aTweets .getCount () - 1 );
136+ max_id = lastTweet .getUid () - 1 ;
137+ // Log.d(TAG, "max_id = " + max_id);
138+ swipeContainer .setRefreshing (false );
139+ progressBar .setVisibility (ProgressBar .INVISIBLE );
140+ }
141+
142+ @ Override
143+ public void onFailure (int statusCode , Header [] headers , Throwable throwable , JSONObject errorResponse ) {
144+ Log .e (TAG , "Failed to call API: " + throwable );
145+ progressBar .setVisibility (ProgressBar .INVISIBLE );
146+ ConnectivityHelper .notifyUserAboutAPIError (TimelineActivity .this );
147+ }
148+ });
149+ }
150+ }
151+
79152
80153 @ Override
81154 public boolean onCreateOptionsMenu (Menu menu ) {
@@ -86,16 +159,57 @@ public boolean onCreateOptionsMenu(Menu menu) {
86159
87160 @ Override
88161 public boolean onOptionsItemSelected (MenuItem item ) {
89- // Handle action bar item clicks here. The action bar will
90- // automatically handle clicks on the Home/Up button, so long
91- // as you specify a parent activity in AndroidManifest.xml.
92- int id = item .getItemId ();
93-
94- //noinspection SimplifiableIfStatement
95- if (id == R .id .action_settings ) {
96- return true ;
162+ // Handle presses on the action bar items
163+ switch (item .getItemId ()) {
164+ case R .id .miTweet :
165+ showTweetDialog ();
166+ return true ;
167+ default :
168+ return super .onOptionsItemSelected (item );
169+ }
170+ }
171+
172+ private void showTweetDialog () {
173+ FragmentManager fragmentManager = getSupportFragmentManager ();
174+ TweetFragment tweetFragment = TweetFragment .newInstance (currentUser );
175+ tweetFragment .show (fragmentManager , "fragment_tweet" );
176+ }
177+
178+ @ Override
179+ public void onTweet (String tweet ) {
180+ tweet = tweet .trim ();
181+ Log .d (TAG , "Posting tweet to Twitter: " + tweet );
182+ if (tweet .length () > 0 ){
183+ if (!ConnectivityHelper .isNetworkAvailable (this )) {
184+ ConnectivityHelper .notifyUserAboutNoInternetConnectivity (this );
185+ } else {
186+ progressBar .setVisibility (ProgressBar .VISIBLE );
187+ client .postTweet (tweet , new JsonHttpResponseHandler () {
188+ @ Override
189+ public void onSuccess (int statusCode , Header [] headers , JSONObject response ) {
190+ tweets .add (0 , Tweet .fromJSON (response ));
191+ aTweets .notifyDataSetChanged ();
192+ progressBar .setVisibility (ProgressBar .INVISIBLE );
193+ Toast .makeText (TimelineActivity .this , R .string .tweet_posted_successfully , Toast .LENGTH_SHORT ).show ();
194+ }
195+
196+ @ Override
197+ public void onFailure (int statusCode , Header [] headers , Throwable throwable , JSONObject errorResponse ) {
198+ Log .e (TAG , "Failed to call API: " + throwable );
199+ progressBar .setVisibility (ProgressBar .INVISIBLE );
200+ ConnectivityHelper .notifyUserAboutAPIError (TimelineActivity .this );
201+ }
202+ });
203+ }
97204 }
205+ }
98206
99- return super .onOptionsItemSelected (item );
207+ @ SuppressWarnings ("unused" ) // it's actually used, just injected by Butter Knife
208+ @ OnItemClick (R .id .lvTweets )
209+ void onItemSelected (int position ) {
210+ Intent i = new Intent (TimelineActivity .this , TweetDetailsActivity .class );
211+ Tweet tweet = tweets .get (position );
212+ i .putExtra (TweetDetailsActivity .EXTRA_TWEET , tweet );
213+ startActivity (i );
100214 }
101215}
0 commit comments