package de.bsd.zwitscher;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Html;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import de.bsd.zwitscher.account.Account;
import de.bsd.zwitscher.account.AccountHolder;
import de.bsd.zwitscher.helper.NetworkHelper;
import de.bsd.zwitscher.helper.PicHelper;
import twitter4j.User;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Show details about a user and allow to (un)follow
* the user or add it to a list.
*
* @author Heiko W. Rupp
*/
public class UserDetailActivity extends Activity {
Bundle bundle;
TwitterHelper twitterHelper;
ProgressBar pg;
User theUser;
boolean weAreFollowing = false;
Button followButton ;
private long userId;
private Account account;
private MenuItem weAreFollowingMenuItem;
private String userName;
List<String> userListNames ;
boolean listsLoaded = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_detail);
followButton = (Button) findViewById(R.id.userDetail_follow_button);
if (followButton!=null)
followButton.setEnabled(false);
account = AccountHolder.getInstance(this).getAccount();
twitterHelper = new TwitterHelper(this, account);
bundle = getIntent().getExtras();
if (bundle!=null) {
userName = bundle.getString("userName");
userId = bundle.getLong("userId");
TextView userNameView = (TextView) findViewById(R.id.UserName);
userNameView.setText(userName);
}
// If the user is in the DB, show the saved state while reloading its data
if (userId!=0) {
theUser = twitterHelper.getUserById(userId,true);
if (theUser!=null)
fillDetails(theUser,false);
reload();
}
else {
reload();
}
// We don't need to show the "<-- touch" comment any more
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putBoolean("newUser",false).commit();
}
public void onResume() {
super.onResume();
userName = bundle.getString("userName");
}
private void reload() {
if (userId!=0)
new UserDetailDownloadTask(this).execute(userId);
else {
new UserDetailDownloadTask(this).execute(this.userName);
}
}
/**
* Fill data of the passed user in the form fields.
* @param user User object to display
* @param weAreFollowing True if we are following that user
*/
private void fillDetails(User user, boolean weAreFollowing) {
if (user == null) {
return;
}
TextView userNameView = (TextView) findViewById(R.id.UserName);
String uName = "<b>" + user.getName() + "</b>" + " (" + user.getScreenName() + ")";
userNameView.setText(Html.fromHtml(uName));
userId = user.getId();
View usersTweetsButton = findViewById(R.id.view_users_tweets_button);
if (usersTweetsButton!=null)
usersTweetsButton.setEnabled(true);
View viewOnWebButton = findViewById(R.id.view_user_on_web_button);
if (viewOnWebButton!=null)
viewOnWebButton.setEnabled(true);
String colorString = user.getProfileBackgroundColor();
if (colorString==null || colorString.equals("")) {
colorString = "#EFEFEF";
}
if (!colorString.startsWith("#")) // identi.ca sends the # , but twitter does not
colorString = "#" + colorString;
getWindow().setTitleColor(Color.parseColor(colorString));
String textColorString = user.getProfileTextColor();
int textColor = 0x555555;
if (textColorString!= null) {
if ( textColorString.equals(""))
textColorString = colorString;
if (!textColorString.startsWith("#"))
textColorString = "#" + textColorString;
textColor = Color.parseColor(textColorString);
}
userNameView.setTextColor(textColor);
TableLayout tl = (TableLayout) findViewById(R.id.user_table_layout);
for (int i = 0 ; i < tl.getChildCount(); i++) {
TableRow row = (TableRow) tl.getChildAt(i);
for (int j = 0 ; j < row.getChildCount(); j++) {
TextView tv = (TextView) row.getChildAt(j);
tv.setTextColor(textColor);
}
}
String backgroundColorString = user.getProfileSidebarFillColor();
if (!backgroundColorString.equals("")) {
if (!backgroundColorString.startsWith("#"))
backgroundColorString = "#" + backgroundColorString;
int backgroundColor = Color.parseColor(backgroundColorString);
tl.setBackgroundColor(backgroundColor);
userNameView.setBackgroundColor(backgroundColor);
}
PicHelper picHelper = new PicHelper();
Bitmap bitmap;
bitmap = picHelper.getBitMapForUserFromFile(user);
if (bitmap!=null) {
ImageView iv = (ImageView) findViewById(R.id.UserPictureImageView);
iv.setImageBitmap(bitmap);
}
TextView locationView = (TextView) findViewById(R.id.userDetail_location);
locationView.setText(user.getLocation());
TextView bioView = (TextView) findViewById(R.id.userDetail_bio);
bioView.setText(user.getDescription());
TextView webView = (TextView) findViewById(R.id.userDetail_web);
if (user.getURL()!=null) {
webView.setText(user.getURL());
String plc = user.getProfileBackgroundColor();
if (!plc.equals("")) {
if (!plc.startsWith("#"))
plc = "#" + plc;
webView.setTextColor(Color.parseColor(plc));
}
}
TextView tweetView = (TextView) findViewById(R.id.userDetail_tweetCount);
tweetView.setText("" + user.getStatusesCount());
TextView followersView = (TextView) findViewById(R.id.userDetail_followerCount);
followersView.setText("" + user.getFollowersCount());
TextView followingView = (TextView) findViewById(R.id.userDetail_followingCount);
followingView.setText("" + user.getFriendsCount());
TextView listedView = (TextView) findViewById(R.id.userDetail_listedCount);
listedView.setText("" + user.getListedCount());
if (followButton!=null) {
followButton.setEnabled(true);
setFollowingButton(weAreFollowing);
}
ImageButton addToListButton = (ImageButton) findViewById(R.id.userDetail_addListButton);
if (addToListButton!=null)
addToListButton.setEnabled(true);
}
/**
* Set the appropriate text on the follow button
* @param weAreFollowing Are we following that user (show 'unfollow' message in this case).
*/
private void setFollowingButton(boolean weAreFollowing) {
if (weAreFollowing)
followButton.setText(R.string.unfollow_user);
else
followButton.setText(R.string.follow_user);
}
/**
* Called from the back button to finish the activity
* @param v View object touched
*/
@SuppressWarnings("unused")
public void done(View v) {
finish();
}
/**
* Allow sending a direct message to the user.
* Called from the direct button.
* TODO check if he follows us and thus sending is possible at all.
* @param v View object touched
*/
@SuppressWarnings("unused")
public void directMessage(View v) {
Intent i = new Intent(this, NewTweetActivity.class);
i.putExtra("user",theUser);
i.putExtra("op", getString(R.string.direct));
startActivity(i);
}
/**
* Called from the followUser button
* @param v View object touched
*/
@SuppressWarnings("unused")
public void followUser(View v) {
UpdateRequest request = new UpdateRequest(UpdateType.FOLLOW_UNFOLLOW);
request.userId = theUser.getId();
request.someBool = !weAreFollowing;
UpdateStatusService.sendUpdate(this,account,request);
}
/**
* Start a browser to view user on server
* Triggered from a button
* @param v View object touched
*/
@SuppressWarnings("unused")
public void viewOnWeb(View v) {
Intent i = new Intent(Intent.ACTION_VIEW);
String u = "http://twitter.com/#!/" + theUser.getScreenName();
i.setData(Uri.parse(u));
startActivity(i);
}
/**
* View users's recent tweets
* Triggered from a button
* @param v View object touched
*/
@SuppressWarnings("unused")
public void showUserTweets(View v) {
Intent intent = new Intent().setClass(this, TweetListActivity.class);
intent.putExtra("userId",userId);
startActivity(intent);
}
/**
* Add the user to a list
* Called from the addToList button
* @param v View object touched
*/
@SuppressWarnings("unused")
public void addToList(View v) {
TweetDB tdb = TweetDB.getInstance(this);
List<String> data = new ArrayList<String>();
Set<Map.Entry<String,Integer>> userListsEntries;
int i = 0;
userListsEntries = tdb.getOwnedLists(account).entrySet();
boolean[] checked = new boolean[userListsEntries.size()];
for (Map.Entry<String,Integer> userList : userListsEntries) {
data.add(userList.getKey());
boolean found = false;
for (String listName : userListNames) {
if (listName.equals(userList.getKey())) {
found = true;
}
}
checked[i] = found;
i++;
}
Intent intent = new Intent(this,MultiSelectListActivity.class);
intent.putStringArrayListExtra("data", (ArrayList<String>) data);
// put enabled items separately
intent.putExtra("checked", checked);
intent.putExtra("mode","multiple");
startActivityForResult(intent, 1);
}
/**
* Callback that is called after the user has selected a list. We need to go thhrough
* the result and check if an item was added or removed and then fire the respective
* task with the server.
* @param requestCode selection code of the original event
* @param resultCode result (ok, not ok)
* @param data Data from the called Intent
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==1 && resultCode==RESULT_OK) {
long[] checkedOnes = data.getLongArrayExtra("data");
TweetDB tdb = TweetDB.getInstance(getApplicationContext());
Set<Map.Entry<String,Integer>> userListsEntries;
userListsEntries = tdb.getOwnedLists(account).entrySet();
int i = 0;
for (Map.Entry<String,Integer> userList : userListsEntries) {
String listName = userList.getKey();
if (userListNames.contains(listName)) { // the stored lists contains the above userList
if (!isChecked(checkedOnes,i)) {
// not checked -> user wants to remove the list
UpdateRequest request = new UpdateRequest(UpdateType.REMOVE_FROM_LIST);
request.id = userList.getValue();
request.userId=theUser.getId();
UpdateStatusService.sendUpdate(this,account,request);
}
} else {
if (isChecked(checkedOnes,i)) {
UpdateRequest request = new UpdateRequest(UpdateType.ADD_TO_LIST);
request.id=userList.getValue();
request.userId=theUser.getId();
UpdateStatusService.sendUpdate(this,account,request);
}
}
i++;
}
}
}
private boolean isChecked(long[] checkedOnes, int pos) {
for (long tmp : checkedOnes) {
if (tmp==pos)
return true;
}
return false;
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.user_detail_menu,menu);
weAreFollowingMenuItem = menu.findItem(R.id.follow);
if (weAreFollowing)
weAreFollowingMenuItem.setTitle(R.string.unfollow_user);
else
weAreFollowingMenuItem.setTitle(R.string.follow_user);
ActionBar actionBar = this.getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
MenuItem pgItem = menu.findItem(R.id.ProgressBar);
pg = (ProgressBar) pgItem.getActionView();
pg.setVisibility(ProgressBar.INVISIBLE);
MenuItem listsItem = menu.findItem(R.id.addToList);
listsItem.setEnabled(listsLoaded);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
case R.id.follow:
followUser(null);
break;
case R.id.addToList:
addToList(null);
break;
case R.id.direct:
directMessage(null);
break;
case R.id.viewOnWeb:
viewOnWeb(null);
break;
case R.id.usersTweets:
showUserTweets(null);
break;
case R.id.refresh:
reload();
break;
default:
Log.e("UserDetailActivity", "Unknown menu item: " + item.toString());
}
return super.onOptionsItemSelected(item);
}
/**
* Async task to download the userdata from server (or db) and
* trigger its display.
*/
private class UserDetailDownloadTask extends AsyncTask<Object,Void, Object[]> {
private Context context;
private UserDetailDownloadTask(Context context) {
this.context = context;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if (weAreFollowingMenuItem!=null) {
weAreFollowingMenuItem.setEnabled(false);
}
if (pg!=null) {
pg.setVisibility(ProgressBar.VISIBLE);
}
getActionBar().setTitle(R.string.get_user_detail);
}
@Override
protected Object[] doInBackground(Object... params) {
Long userId;
User user;
if (params[0] instanceof Long) {
userId = (Long) params[0];
user = twitterHelper.getUserById(userId, false);
}
else if (params[0] instanceof String) {
String name= (String) params[0];
user = twitterHelper.getUserByScreenName(name, false);
if (user==null)
return new Object[]{};
userId = user.getId();
} else {
// Should not happen
return new Object[]{};
}
boolean downloadImages = new NetworkHelper(context).mayDownloadImages();
Drawable background = null;
if (downloadImages) {
String profileBackgroundImageUrl = user.getProfileBackgroundImageURL();
if (!"".equals(profileBackgroundImageUrl)) {
try {
URL url = new URL(profileBackgroundImageUrl);
InputStream is = url.openStream();
background = Drawable.createFromStream(is,"lala");
} catch (IOException e) {
e.printStackTrace();
} catch (OutOfMemoryError oome) {
oome.printStackTrace();
}
}
PicHelper picHelper = new PicHelper(); // TODO optimize
picHelper.fetchUserPic(user);
}
userListNames = twitterHelper.getListMembershipFromServer(user.getScreenName());
Boolean isFriend = twitterHelper.areWeFollowing(userId);
weAreFollowing = isFriend;
Object[] res = new Object[3];
res[0] = user;
res[1] = isFriend;
res[2] = background;
return res;
}
@Override
protected void onPostExecute(Object[] params) {
super.onPostExecute(params);
if (params==null || params.length==0 || params[0]==null) {
Toast.makeText(context,R.string.failed_to_load_user_info,Toast.LENGTH_LONG).show();
return;
}
User user = (User) params[0];
Boolean isFriend = (Boolean) params[1];
theUser = user;
fillDetails(user, isFriend);
View followButton = findViewById(R.id.userDetail_follow_button);
if (followButton!=null)
followButton.setEnabled(true);
if (weAreFollowingMenuItem!=null) {
if (isFriend)
weAreFollowingMenuItem.setTitle(R.string.unfollow_user);
else
weAreFollowingMenuItem.setTitle(R.string.follow_user);
weAreFollowingMenuItem.setEnabled(true);
}
if (pg!=null)
pg.setVisibility(ProgressBar.INVISIBLE);
getActionBar().setTitle(R.string.app_name);
Drawable background = (Drawable) params[2];
if (background!=null)
getWindow().setBackgroundDrawable(background);
listsLoaded = true;
invalidateOptionsMenu();
}
}
}