package org.wordpress.android.ui.posts;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import android.text.format.DateUtils;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;
import com.justsystems.hpb.pad.R;
import org.xmlrpc.android.ApiHelper;
import org.wordpress.android.WordPress;
import org.wordpress.android.models.CustomTypePost;
import org.wordpress.android.models.Post;
import org.wordpress.android.models.Postable;
import org.wordpress.android.task.LoadCustomTypePostsTask;
import org.wordpress.android.task.LoadPagesTask;
import org.wordpress.android.task.LoadPostsTask;
import org.wordpress.android.util.StringUtils;
import org.wordpress.android.util.WPAlertDialogFragment;
public class PostsListFragment extends ListFragment {
/** Called when the activity is first created. */
private int mRowID = 0;
private long mSelectedID;
private PostListAdapter mPostListAdapter;
private OnPostSelectedListener mOnPostSelectedListener;
private OnRefreshListener mOnRefreshListener;
private OnPostActionListener mOnPostActionListener;
private AbsListActivity mParentActivity;
public boolean inDrafts = false;
public List<String> imageUrl = new Vector<String>();
public String errorMsg = "";
public int totalDrafts = 0;
public boolean isPage = false, shouldSelectAfterLoad = false;
private String postType;
public int numRecords = 20;
public int offset = 0;
public ViewSwitcher switcher;
public AsyncTask<?, ?, ?> getPostsTask;
private static final int MENU_GROUP_PAGES = 2, MENU_GROUP_POSTS = 0,
MENU_GROUP_DRAFTS = 1;
private static final int MENU_ITEM_EDIT = 0, MENU_ITEM_DELETE = 1,
MENU_ITEM_PREVIEW = 2, MENU_ITEM_SHARE = 3,
MENU_ITEM_ADD_COMMENT = 4;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Intent intent = getActivity().getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
isPage = extras.getBoolean("viewPages");
this.postType = intent.getStringExtra("type_name");
}
}
@Override
public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle);
ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setBackgroundColor(getResources()
.getColor(R.color.list_row_bg));
listView.setSelector(getResources().getDrawable(
R.drawable.list_bg_selector));
createSwitcher();
mPostListAdapter = new PostListAdapter(getActivity().getBaseContext());
listView.setAdapter(mPostListAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position,
long id) {
if (position < mPostListAdapter.getCount()) {
if (v != null && !mParentActivity.isRefreshing) {
mSelectedID = v.getId();
Postable post;
if (postType != null) {
CustomPostTypePostsActivity cst = (CustomPostTypePostsActivity) getActivity();
post = new CustomTypePost(WordPress.currentBlog
.getId(), mSelectedID, cst.getPostType());
} else {
post = new Post(WordPress.currentBlog.getId(),
mSelectedID, isPage);
}
if (post.getId() >= 0) {
WordPress.setCurrentPost(post);
mOnPostSelectedListener.onPostSelected(post);
mPostListAdapter.notifyDataSetChanged();
} else {
if (!getActivity().isFinishing()) {
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
WPAlertDialogFragment alert = WPAlertDialogFragment
.newInstance(getString(R.string.post_not_found));
alert.show(ft, "alert");
}
}
}
} else {
Toast.makeText(mParentActivity,
R.string.please_wait_refresh_done,
Toast.LENGTH_SHORT).show();
}
}
});
listView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) menuInfo;
} catch (ClassCastException e) {
// Log.e(TAG, "bad menuInfo", e);
return;
}
if (mParentActivity.isRefreshing)
return;
Object[] args = { R.id.row_post_id };
try {
Method m = android.view.View.class.getMethod("getTag");
m.invoke(mSelectedID, args);
} catch (NoSuchMethodException e) {
mSelectedID = info.targetView.getId();
} catch (IllegalArgumentException e) {
mSelectedID = info.targetView.getId();
} catch (IllegalAccessException e) {
mSelectedID = info.targetView.getId();
} catch (InvocationTargetException e) {
mSelectedID = info.targetView.getId();
}
// selectedID = (String)
// info.targetView.getTag(R.id.row_post_id);
// Show comments menu option only if post allows commenting
boolean allowComments = false;
Post post = new Post(WordPress.currentBlog.getId(),
mSelectedID, isPage);
if (post.getId() >= 0) {
allowComments = post.allowComments();
}
mRowID = info.position;
if (totalDrafts > 0 && mRowID < totalDrafts) {
menu.clear();
menu.setHeaderTitle(getResources().getText(
R.string.draft_actions));
menu.add(MENU_GROUP_DRAFTS, MENU_ITEM_EDIT, 0,
getResources().getText(R.string.edit_draft));
menu.add(MENU_GROUP_DRAFTS, MENU_ITEM_DELETE, 0,
getResources().getText(R.string.delete_draft));
} else {
menu.clear();
if (isPage) {
menu.setHeaderTitle(getResources().getText(
R.string.page_actions));
menu.add(MENU_GROUP_PAGES, MENU_ITEM_EDIT, 0,
getResources().getText(R.string.edit_page));
menu.add(MENU_GROUP_PAGES, MENU_ITEM_DELETE, 0,
getResources().getText(R.string.delete_page));
menu.add(MENU_GROUP_PAGES, MENU_ITEM_PREVIEW, 0,
getResources().getText(R.string.preview_page));
menu.add(MENU_GROUP_PAGES, MENU_ITEM_SHARE, 0,
getResources().getText(R.string.share_url_page));
if (allowComments)
menu.add(MENU_GROUP_PAGES, MENU_ITEM_ADD_COMMENT,
0,
getResources()
.getText(R.string.add_comment));
} else {
menu.setHeaderTitle(getResources().getText(
R.string.post_actions));
menu.add(MENU_GROUP_POSTS, MENU_ITEM_EDIT, 0,
getResources().getText(R.string.edit_post));
menu.add(MENU_GROUP_POSTS, MENU_ITEM_DELETE, 0,
getResources().getText(R.string.delete_post));
menu.add(MENU_GROUP_POSTS, MENU_ITEM_PREVIEW, 0,
getResources().getText(R.string.preview_post));
menu.add(MENU_GROUP_POSTS, MENU_ITEM_SHARE, 0,
getResources().getText(R.string.share_url));
if (allowComments)
menu.add(MENU_GROUP_POSTS, MENU_ITEM_ADD_COMMENT,
0,
getResources()
.getText(R.string.add_comment));
}
}
}
});
}
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
// check that the containing activity implements our callback
mOnPostSelectedListener = (OnPostSelectedListener) activity;
mOnRefreshListener = (OnRefreshListener) activity;
mOnPostActionListener = (OnPostActionListener) activity;
} catch (ClassCastException e) {
activity.finish();
throw new ClassCastException(activity.toString()
+ " must implement Callback");
}
}
public void onResume() {
super.onResume();
mParentActivity = (AbsListActivity) getActivity();
}
private void createSwitcher() {
// create the ViewSwitcher in the current context
switcher = new ViewSwitcher(getActivity().getApplicationContext());
Button footer = (Button) View.inflate(getActivity()
.getApplicationContext(), R.layout.list_footer_btn, null);
footer.setText(getResources().getText(R.string.load_more)
+ " "
+ getResources().getText(
(isPage) ? R.string.tab_pages : R.string.tab_posts));
footer.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
if (!WordPress.wpDB.findLocalChanges()) {
// first view is showing, show the second progress view
switcher.showNext();
// get 20 more posts
numRecords += 20;
refreshPosts(true);
} else {
if (!getActivity().isFinishing()) {
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
WPAlertDialogFragment alert = WPAlertDialogFragment
.newInstance(
getString(R.string.remote_changes),
getString(R.string.local_changes), true);
alert.show(ft, "alert");
}
}
}
});
View progress = View.inflate(getActivity().getApplicationContext(),
R.layout.list_footer_progress, null);
switcher.addView(footer);
switcher.addView(progress);
}
public PostListAdapter getAdapter() {
return this.mPostListAdapter;
}
public void refreshPosts(final boolean loadMore) {
if (!loadMore) {
mOnRefreshListener.onRefresh(true);
numRecords = 20;
offset = 0;
}
List<Object> apiArgs = new Vector<Object>();
apiArgs.add(WordPress.currentBlog);
apiArgs.add(isPage);
apiArgs.add(numRecords);
apiArgs.add(loadMore);
if (postType != null) {
LoadCustomTypePostsTask task = new LoadCustomTypePostsTask(this,
mOnRefreshListener, loadMore, offset, postType);
task.executeOnMultiThread();
getPostsTask = task;
} else if (this.isPage) {
LoadPagesTask task = new LoadPagesTask(this, mOnRefreshListener,
loadMore);
task.executeOnMultiThread(apiArgs);
getPostsTask = task;
} else {
LoadPostsTask task = new LoadPostsTask(this, mOnRefreshListener,
loadMore);
task.executeOnMultiThread(apiArgs);
getPostsTask = task;
}
}
public Map<String, ?> createItem(String title, String caption) {
Map<String, String> item = new HashMap<String, String>();
item.put("title", title);
item.put("caption", caption);
return item;
}
public boolean loadPosts(boolean loadMore) { // loads posts from the db
this.mPostListAdapter.clear();
List<Map<String, Object>> loadedPosts;
try {
if (postType != null) {
loadedPosts = WordPress.wpDB.loadUploadedCustomTypePosts(
postType, WordPress.currentBlog.getId());
} else {
loadedPosts = WordPress.wpDB.loadUploadedPosts(
WordPress.currentBlog.getId(), isPage);
}
} catch (Exception e1) {
return false;
}
if (loadedPosts != null) {
offset = loadedPosts.size();
numRecords = loadedPosts.size();
} else {
if (mPostListAdapter != null) {
mPostListAdapter.notifyDataSetChanged();
}
}
if (loadedPosts != null) {
Date d = new Date();
for (int i = 0; i < loadedPosts.size(); i++) {
Map<String, Object> contentHash = loadedPosts.get(i);
final String mTitle = StringUtils.unescapeHTML(contentHash.get(
"title").toString());
final int mPostID = (Integer) contentHash.get("id");
final long localTime = (Long) contentHash
.get("date_created_gmt");
final String mDateCreatedFormatted = getFormattedDate(localTime);
String mStatus = null;
final Object contentStatus = contentHash.get("post_status");
if (contentStatus != null) {
String api_status = contentStatus.toString();
if (api_status.equals("publish")) {
if (localTime > d.getTime()) {
mStatus = getResources()
.getText(R.string.scheduled).toString();
} else {
mStatus = getResources()
.getText(R.string.published).toString();
}
} else if (api_status.equals("draft")) {
mStatus = getResources().getText(R.string.draft)
.toString();
} else if (api_status.equals("pending")) {
mStatus = getResources().getText(
R.string.pending_review).toString();
} else if (api_status.equals("private")) {
mStatus = getResources().getText(R.string.post_private)
.toString();
} else {
assert false;
}
}
this.mPostListAdapter.add(mPostID, mTitle,
mDateCreatedFormatted, mStatus);
}
}
// load drafts
boolean drafts = loadDrafts();
if (drafts) {
} else {
if (mPostListAdapter != null) {
mPostListAdapter.notifyDataSetChanged();
}
}
if (loadedPosts != null || drafts == true) {
ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setBackgroundColor(getResources().getColor(
R.color.list_row_bg));
listView.setDivider(getResources().getDrawable(
R.drawable.list_divider));
listView.setDividerHeight(1);
listView.removeFooterView(switcher);
int position = listView.getFirstVisiblePosition();
int y = listView.getChildCount() > 0 ? listView.getChildAt(0)
.getTop() : 0;
if (loadedPosts != null) {
if (loadedPosts.size() >= 20) {
listView.addFooterView(switcher);
listView.setAdapter(mPostListAdapter);
}
}
mPostListAdapter.notifyDataSetChanged();
// restore scrolled position
listView.setSelectionFromTop(position, y);
if (this.shouldSelectAfterLoad) {
if (mPostListAdapter.getCount() >= 1) {
final int id = (int) mPostListAdapter.getItemId(0);
Post post = new Post(WordPress.currentBlog.getId(),
Integer.valueOf(id), isPage);
if (post.getId() >= 0) {
WordPress.setCurrentPost(post);
mOnPostSelectedListener.onPostSelected(post);
FragmentManager fm = getActivity()
.getSupportFragmentManager();
ViewPostFragment f = (ViewPostFragment) fm
.findFragmentById(R.id.postDetail);
if (f != null && f.isInLayout())
getListView().setItemChecked(0, true);
}
}
shouldSelectAfterLoad = false;
}
if (loadedPosts == null) {
refreshPosts(false);
}
if (loadedPosts == null) {
refreshPosts(false);
}
return true;
} else {
if (loadedPosts == null) {
refreshPosts(false);
if (!isPage)
new ApiHelper.RefreshBlogContentTask(getActivity(),
WordPress.getCurrentBlog()).execute(false);
}
return false;
}
}
private String getFormattedDate(long localTime) {
int flags = 0;
flags |= android.text.format.DateUtils.FORMAT_SHOW_DATE;
flags |= android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
flags |= android.text.format.DateUtils.FORMAT_SHOW_YEAR;
flags |= android.text.format.DateUtils.FORMAT_SHOW_TIME;
String formattedDate = DateUtils.formatDateTime(getActivity()
.getApplicationContext(), localTime, flags);
return formattedDate;
}
class ViewWrapper {
View base;
TextView title = null;
TextView date = null;
TextView status = null;
ViewWrapper(View base) {
this.base = base;
}
TextView getTitle() {
if (title == null) {
title = (TextView) base.findViewById(R.id.title);
}
return (title);
}
TextView getDate() {
if (date == null) {
date = (TextView) base.findViewById(R.id.date);
}
return (date);
}
TextView getStatus() {
if (status == null) {
status = (TextView) base.findViewById(R.id.status);
}
return (status);
}
}
private boolean loadDrafts() { // loads drafts from the db
List<Map<String, Object>> loadedPosts;
if (getActivity() instanceof CustomPostTypePostsActivity) {
loadedPosts = WordPress.wpDB.loadCustomTypeDrafts(
WordPress.currentBlog.getId(), postType);
} else if (isPage) {
loadedPosts = WordPress.wpDB.loadDrafts(
WordPress.currentBlog.getId(), true);
} else {
loadedPosts = WordPress.wpDB.loadDrafts(
WordPress.currentBlog.getId(), false);
}
if (loadedPosts == null) {
totalDrafts = 0;
return false;
}
totalDrafts = loadedPosts.size();
for (int i = 0; i < loadedPosts.size(); i++) {
Map<String, Object> contentHash = loadedPosts.get(i);
final int mDraftID = (Integer) contentHash.get("id");
final String mDraftTitle = StringUtils.unescapeHTML(contentHash
.get("title").toString());
final String mDraftDateCreated = "";
final String mDraftStatus = getString(R.string.local_draft);
this.mPostListAdapter.addDraft(mDraftID, mDraftTitle,
mDraftDateCreated, mDraftStatus);
}
return true;
}
@Override
public boolean onContextItemSelected(MenuItem item) {
Postable post;
if (this.postType != null) {
post = new CustomTypePost(WordPress.currentBlog.getId(),
mSelectedID, postType);
} else {
post = new Post(WordPress.currentBlog.getId(), mSelectedID, isPage);
}
if (post.getId() < 0) {
if (!getActivity().isFinishing()) {
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
WPAlertDialogFragment alert = WPAlertDialogFragment
.newInstance(getString(R.string.post_not_found));
alert.show(ft, "alert");
}
return false;
}
int itemGroupID = item.getGroupId();
/* Switch on the ID of the item, to get what the user selected. */
if (itemGroupID == MENU_GROUP_POSTS || itemGroupID == MENU_GROUP_PAGES
|| itemGroupID == MENU_GROUP_DRAFTS) {
switch (item.getItemId()) {
case MENU_ITEM_EDIT:
Intent i2;
if (itemGroupID == MENU_GROUP_PAGES) { //page synced with the server
i2 = new Intent(getActivity().getApplicationContext(),
EditPostActivity.class);
i2.putExtra("postID", mSelectedID);
i2.putExtra("id", WordPress.currentBlog.getId());
i2.putExtra("isPage", true);
} else {
if (this.postType != null) {
i2 = new Intent(getActivity().getApplicationContext(),
EditCustomTypePostActivity.class);
i2.putExtra("type_name", postType);
} else {
i2 = new Intent(getActivity().getApplicationContext(),
EditPostActivity.class);
if (isPage) {
i2.putExtra("isPage", true);
}
}
i2.putExtra("postID", mSelectedID);
i2.putExtra("id", WordPress.currentBlog.getId());
if (itemGroupID == MENU_GROUP_DRAFTS) {
i2.putExtra("localDraft", true);
}
}
startActivityForResult(i2, 0);
return true;
case MENU_ITEM_DELETE:
mOnPostActionListener.onPostAction(AbsListActivity.POST_DELETE,
post);
return true;
case MENU_ITEM_PREVIEW:
Intent i = new Intent(getActivity(), PreviewPostActivity.class);
i.putExtra("isPage", itemGroupID == MENU_GROUP_PAGES ? true
: false);
i.putExtra("postID", mSelectedID);
i.putExtra("blogID", WordPress.currentBlog.getId());
startActivity(i);
return true;
case MENU_ITEM_SHARE:
mOnPostActionListener.onPostAction(AbsListActivity.POST_SHARE,
post);
return true;
case MENU_ITEM_ADD_COMMENT:
mOnPostActionListener.onPostAction(
AbsListActivity.POST_COMMENT, post);
return true;
default:
return false;
}
}
return false;
}
public interface OnPostSelectedListener {
public void onPostSelected(Postable postable);
}
public interface OnRefreshListener {
public void onRefresh(boolean start);
}
public interface OnPostActionListener {
public void onPostAction(int action, Postable post);
}
}