From e0cae93c3cecebc09f9764536d6bae924ee0de0a Mon Sep 17 00:00:00 2001 From: YuviPanda Date: Thu, 19 Sep 2013 18:19:17 -0700 Subject: [PATCH] Display contributions from other people to the campaign Attempts to be as minimally invasive as possible Change-Id: I1c9d7080d046199d5277385da625c180a8bacbfa --- .../java/org/wikimedia/commons/Media.java | 3 + .../java/org/wikimedia/commons/Utils.java | 1 + .../wikimedia/commons/campaigns/Campaign.java | 4 +- .../commons/campaigns/CampaignActivity.java | 14 ++++- .../contributions/ContributionsActivity.java | 62 +++++++++++++------ .../ContributionsListAdapter.java | 15 ++--- .../ContributionsListFragment.java | 24 ++++--- .../contributions/MediaListAdapter.java | 47 ++++++++++++++ .../commons/media/CategoryImagesLoader.java | 57 +++++++++++++++++ .../commons/media/MediaDetailFragment.java | 2 +- .../commons/upload/UploadController.java | 13 ++-- 11 files changed, 194 insertions(+), 48 deletions(-) create mode 100644 commons/src/main/java/org/wikimedia/commons/contributions/MediaListAdapter.java create mode 100644 commons/src/main/java/org/wikimedia/commons/media/CategoryImagesLoader.java diff --git a/commons/src/main/java/org/wikimedia/commons/Media.java b/commons/src/main/java/org/wikimedia/commons/Media.java index ae3e5b024..cacf1ff3e 100644 --- a/commons/src/main/java/org/wikimedia/commons/Media.java +++ b/commons/src/main/java/org/wikimedia/commons/Media.java @@ -144,6 +144,9 @@ public class Media implements Parcelable { protected String creator; + public Media(String filename) { + this.filename = filename; + } public Media(Uri localUri, String imageUrl, String filename, String description, long dataLength, Date dateCreated, Date dateUploaded, String creator) { this.localUri = localUri; diff --git a/commons/src/main/java/org/wikimedia/commons/Utils.java b/commons/src/main/java/org/wikimedia/commons/Utils.java index 0a9915a30..d8013fd0d 100644 --- a/commons/src/main/java/org/wikimedia/commons/Utils.java +++ b/commons/src/main/java/org/wikimedia/commons/Utils.java @@ -1,6 +1,7 @@ package org.wikimedia.commons; import android.os.*; +import android.util.Log; import com.nostra13.universalimageloader.core.*; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; diff --git a/commons/src/main/java/org/wikimedia/commons/campaigns/Campaign.java b/commons/src/main/java/org/wikimedia/commons/campaigns/Campaign.java index f7c24bcbe..61b796eab 100644 --- a/commons/src/main/java/org/wikimedia/commons/campaigns/Campaign.java +++ b/commons/src/main/java/org/wikimedia/commons/campaigns/Campaign.java @@ -7,9 +7,11 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.io.Serializable; import java.util.ArrayList; -public class Campaign { +// FIXME: Implement Parcelable +public class Campaign implements Serializable { private boolean enabled; private String autoAddWikitext; diff --git a/commons/src/main/java/org/wikimedia/commons/campaigns/CampaignActivity.java b/commons/src/main/java/org/wikimedia/commons/campaigns/CampaignActivity.java index 7b8489867..2fafcb40e 100644 --- a/commons/src/main/java/org/wikimedia/commons/campaigns/CampaignActivity.java +++ b/commons/src/main/java/org/wikimedia/commons/campaigns/CampaignActivity.java @@ -1,14 +1,18 @@ package org.wikimedia.commons.campaigns; import android.app.Activity; +import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; +import android.view.View; +import android.widget.AdapterView; import android.widget.ListView; import com.actionbarsherlock.app.SherlockFragmentActivity; import org.wikimedia.commons.R; +import org.wikimedia.commons.contributions.ContributionsActivity; public class CampaignActivity extends SherlockFragmentActivity @@ -16,12 +20,20 @@ public class CampaignActivity private ListView campaignsListView; private CampaignsListAdapter campaignsListAdapter; - private Cursor allCampaigns; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_campaigns); campaignsListView = (ListView) findViewById(R.id.campaignsList); + + campaignsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + Campaign c = Campaign.fromCursor((Cursor) adapterView.getItemAtPosition(i)); + Intent intent = new Intent(CampaignActivity.this, ContributionsActivity.class); + intent.putExtra("campaign", c); + startActivity(intent); + } + }); getSupportLoaderManager().initLoader(0, null, this); } diff --git a/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsActivity.java b/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsActivity.java index 0a9574960..a1951fa9c 100644 --- a/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsActivity.java +++ b/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsActivity.java @@ -8,6 +8,7 @@ import android.support.v4.content.Loader; import android.content.*; import android.database.Cursor; import android.os.Bundle; +import android.support.v4.widget.CursorAdapter; import android.util.Log; import android.view.View; import android.widget.AdapterView; @@ -16,12 +17,15 @@ import com.actionbarsherlock.view.MenuItem; import org.wikimedia.commons.*; import org.wikimedia.commons.auth.*; +import org.wikimedia.commons.campaigns.Campaign; import org.wikimedia.commons.media.*; import org.wikimedia.commons.upload.UploadService; +import java.util.ArrayList; + public class ContributionsActivity extends AuthenticatedActivity - implements LoaderManager.LoaderCallbacks, + implements LoaderManager.LoaderCallbacks, AdapterView.OnItemClickListener, MediaDetailPagerFragment.MediaDetailProvider, FragmentManager.OnBackStackChangedListener { @@ -31,6 +35,8 @@ public class ContributionsActivity private ContributionsListFragment contributionsList; private MediaDetailPagerFragment mediaDetails; + private Campaign campaign; + public ContributionsActivity() { super(WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE); } @@ -101,6 +107,10 @@ public class ContributionsActivity setTitle(R.string.title_activity_contributions); setContentView(R.layout.activity_contributions); + if(getIntent().hasExtra("campaign")) { + this.campaign = (Campaign) getIntent().getSerializableExtra("campaign"); + } + contributionsList = (ContributionsListFragment)getSupportFragmentManager().findFragmentById(R.id.contributionsListFragment); getSupportFragmentManager().addOnBackStackChangedListener(this); @@ -180,13 +190,7 @@ public class ContributionsActivity public void onItemClick(AdapterView adapterView, View view, int position, long item) { - Cursor cursor = (Cursor)adapterView.getItemAtPosition(position); - Contribution c = Contribution.fromCursor(cursor); - - Log.d("Commons", "Clicking for " + c.toContentValues()); showDetail(position); - - Log.d("Commons", "You clicked on:" + c.toContentValues().toString()); } @Override @@ -194,31 +198,51 @@ public class ContributionsActivity return super.onCreateOptionsMenu(menu); } - public Loader onCreateLoader(int i, Bundle bundle) { - return new CursorLoader(this, ContributionsContentProvider.BASE_URI, Contribution.Table.ALL_FIELDS, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT); + public Loader onCreateLoader(int i, Bundle bundle) { + if(campaign == null) { + return new CursorLoader(this, ContributionsContentProvider.BASE_URI, Contribution.Table.ALL_FIELDS, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT); + } else { + return new CategoryImagesLoader(this, campaign.getTrackingCategory()); + } } - public void onLoadFinished(Loader cursorLoader, Cursor cursor) { - allContributions = cursor; - contributionsList.setCursor(cursor); + public void onLoadFinished(Loader cursorLoader, Object result) { + if(campaign == null) { + Cursor cursor = (Cursor) result; + if(contributionsList.getAdapter() == null) { + contributionsList.setAdapter(new ContributionsListAdapter(this, cursor, 0)); + } else { + ((CursorAdapter)contributionsList.getAdapter()).swapCursor(cursor); + } - getSupportActionBar().setSubtitle(getResources().getQuantityString(R.plurals.contributions_subtitle, cursor.getCount(), cursor.getCount())); + getSupportActionBar().setSubtitle(getResources().getQuantityString(R.plurals.contributions_subtitle, cursor.getCount(), cursor.getCount())); + } else { + contributionsList.setAdapter(new MediaListAdapter(this, (ArrayList) result)); + } } - public void onLoaderReset(Loader cursorLoader) { - contributionsList.setCursor(null); + public void onLoaderReset(Loader cursorLoader) { + if(campaign == null) { + ((CursorAdapter) contributionsList.getAdapter()).swapCursor(null); + } else { + //((MediaListAdapter) contributionsList.getAdapter()). + // DO SOMETHING! + } } public Media getMediaAtPosition(int i) { - allContributions.moveToPosition(i); - return Contribution.fromCursor(allContributions); + if(campaign == null) { + return Contribution.fromCursor((Cursor) contributionsList.getAdapter().getItem(i)); + } else { + return (Media) contributionsList.getAdapter().getItem(i); + } } public int getTotalMediaCount() { - if(allContributions == null) { + if(contributionsList.getAdapter() == null) { return 0; } - return allContributions.getCount(); + return contributionsList.getAdapter().getCount(); } public void notifyDatasetChanged() { diff --git a/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsListAdapter.java b/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsListAdapter.java index 295f2566d..3ce0c4c03 100644 --- a/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsListAdapter.java +++ b/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsListAdapter.java @@ -1,5 +1,6 @@ package org.wikimedia.commons.contributions; +import android.app.Activity; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; @@ -19,16 +20,16 @@ import org.wikimedia.commons.Utils; class ContributionsListAdapter extends CursorAdapter { private DisplayImageOptions contributionDisplayOptions = Utils.getGenericDisplayOptions().build();; - private SherlockFragment fragment; + private Activity activity; - public ContributionsListAdapter(SherlockFragment fragment, Cursor c, int flags) { - super(fragment.getActivity(), c, flags); - this.fragment = fragment; + public ContributionsListAdapter(Activity activity, Cursor c, int flags) { + super(activity, c, flags); + this.activity = activity; } @Override public View newView(Context context, Cursor cursor, ViewGroup viewGroup) { - View parent = fragment.getActivity().getLayoutInflater().inflate(R.layout.layout_contribution, viewGroup, false); + View parent = activity.getLayoutInflater().inflate(R.layout.layout_contribution, viewGroup, false); parent.setTag(new ContributionViewHolder(parent)); return parent; } @@ -38,12 +39,12 @@ class ContributionsListAdapter extends CursorAdapter { final ContributionViewHolder views = (ContributionViewHolder)view.getTag(); Contribution contribution = Contribution.fromCursor(cursor); - String actualUrl = TextUtils.isEmpty(contribution.getImageUrl()) ? contribution.getLocalUri().toString() : contribution.getThumbnailUrl(320); + String actualUrl = (contribution.getLocalUri() != null && TextUtils.isEmpty(contribution.getLocalUri().toString())) ? contribution.getLocalUri().toString() : contribution.getThumbnailUrl(640); if(views.url == null || !views.url.equals(actualUrl)) { if(actualUrl.startsWith("http")) { MediaWikiImageView mwImageView = (MediaWikiImageView)views.imageView; - mwImageView.setMedia(contribution, ((CommonsApplication) fragment.getActivity().getApplicationContext()).getImageLoader()); + mwImageView.setMedia(contribution, ((CommonsApplication) activity.getApplicationContext()).getImageLoader()); // FIXME: For transparent images } else { com.nostra13.universalimageloader.core.ImageLoader.getInstance().displayImage(actualUrl, views.imageView, contributionDisplayOptions, new SimpleImageLoadingListener() { diff --git a/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsListFragment.java b/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsListFragment.java index 065f790d9..0be5eaddb 100644 --- a/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsListFragment.java +++ b/commons/src/main/java/org/wikimedia/commons/contributions/ContributionsListFragment.java @@ -16,8 +16,6 @@ import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; -import com.nostra13.universalimageloader.core.DisplayImageOptions; - import org.wikimedia.commons.*; import org.wikimedia.commons.R; @@ -28,10 +26,6 @@ public class ContributionsListFragment extends SherlockFragment { private TextView waitingMessage; private TextView emptyMessage; - private ContributionsListAdapter contributionsAdapter; - - private Cursor allContributions; - private ContributionController controller; @Override @@ -39,13 +33,12 @@ public class ContributionsListFragment extends SherlockFragment { return inflater.inflate(R.layout.fragment_contributions, container, false); } - public void setCursor(Cursor cursor) { - if(allContributions == null) { - contributionsAdapter = new ContributionsListAdapter(this, cursor, 0); - contributionsList.setAdapter(contributionsAdapter); - } - allContributions = cursor; - contributionsAdapter.swapCursor(cursor); + public ListAdapter getAdapter() { + return contributionsList.getAdapter(); + } + + public void setAdapter(ListAdapter adapter) { + this.contributionsList.setAdapter(adapter); } @Override @@ -111,6 +104,11 @@ public class ContributionsListFragment extends SherlockFragment { setHasOptionsMenu(true); } + @Override + public void onDestroy() { + super.onDestroy(); + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); diff --git a/commons/src/main/java/org/wikimedia/commons/contributions/MediaListAdapter.java b/commons/src/main/java/org/wikimedia/commons/contributions/MediaListAdapter.java new file mode 100644 index 000000000..33f846043 --- /dev/null +++ b/commons/src/main/java/org/wikimedia/commons/contributions/MediaListAdapter.java @@ -0,0 +1,47 @@ +package org.wikimedia.commons.contributions; + +import android.app.Activity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import com.android.volley.toolbox.ImageLoader; +import org.wikimedia.commons.CommonsApplication; +import org.wikimedia.commons.Media; +import org.wikimedia.commons.R; + +import java.util.ArrayList; + +public class MediaListAdapter extends BaseAdapter { + private ArrayList mediaList; + private Activity activity; + + public MediaListAdapter(Activity activity, ArrayList mediaList) { + this.mediaList = mediaList; + this.activity = activity; + } + + public int getCount() { + return mediaList.size(); + } + + public Object getItem(int i) { + return mediaList.get(i); + } + + public long getItemId(int i) { + return i; + } + + public View getView(int i, View view, ViewGroup viewGroup) { + if(view == null) { + view = activity.getLayoutInflater().inflate(R.layout.layout_contribution, null, false); + view.setTag(new ContributionViewHolder(view)); + } + + Media m = (Media) getItem(i); + ContributionViewHolder holder = (ContributionViewHolder) view.getTag(); + holder.imageView.setMedia(m, ((CommonsApplication)activity.getApplicationContext()).getImageLoader()); + holder.titleView.setText(m.getDisplayTitle()); + return view; + } +} diff --git a/commons/src/main/java/org/wikimedia/commons/media/CategoryImagesLoader.java b/commons/src/main/java/org/wikimedia/commons/media/CategoryImagesLoader.java new file mode 100644 index 000000000..02e517f35 --- /dev/null +++ b/commons/src/main/java/org/wikimedia/commons/media/CategoryImagesLoader.java @@ -0,0 +1,57 @@ +package org.wikimedia.commons.media; + +import android.content.Context; +import android.support.v4.content.AsyncTaskLoader; +import android.util.Log; +import org.mediawiki.api.ApiResult; +import org.wikimedia.commons.CommonsApplication; +import org.wikimedia.commons.Media; +import org.wikimedia.commons.Utils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class CategoryImagesLoader extends AsyncTaskLoader>{ + private final CommonsApplication app; + private final String category; + + public CategoryImagesLoader(Context context, String category) { + super(context); + this.app = (CommonsApplication) context.getApplicationContext(); + this.category = category; + } + + @Override + protected void onStartLoading() { + super.onStartLoading(); + super.forceLoad(); + } + + @Override + public List loadInBackground() { + ArrayList mediaList = new ArrayList(); + ApiResult result; + try { + result = app.getApi().action("query") + .param("list", "categorymembers") + .param("cmtitle", "Category:" + category) + .param("cmprop", "title|timestamp") + .param("cmtype", "file") + .param("cmsort", "timestamp") + .param("cmdir", "descending") + .param("cmlimit", 50) + .get(); + } catch (IOException e) { + throw new RuntimeException(e); + } + + Log.d("Commons", Utils.getStringFromDOM(result.getDocument())); + + List members = result.getNodes("/api/query/categorymembers/cm"); + for(ApiResult member : members) { + mediaList.add(new Media(member.getString("@title"))); + } + return mediaList; + } +} diff --git a/commons/src/main/java/org/wikimedia/commons/media/MediaDetailFragment.java b/commons/src/main/java/org/wikimedia/commons/media/MediaDetailFragment.java index 39343d825..d4971d4a8 100644 --- a/commons/src/main/java/org/wikimedia/commons/media/MediaDetailFragment.java +++ b/commons/src/main/java/org/wikimedia/commons/media/MediaDetailFragment.java @@ -80,7 +80,7 @@ public class MediaDetailFragment extends SherlockFragment { title.setBackgroundDrawable(null); } - String actualUrl = TextUtils.isEmpty(media.getImageUrl()) ? media.getLocalUri().toString() : media.getThumbnailUrl(640); + String actualUrl = (media.getLocalUri() != null && TextUtils.isEmpty(media.getLocalUri().toString())) ? media.getLocalUri().toString() : media.getThumbnailUrl(640); if(actualUrl.startsWith("http")) { ImageLoader loader = ((CommonsApplication)getActivity().getApplicationContext()).getImageLoader(); MediaWikiImageView mwImage = (MediaWikiImageView)image; diff --git a/commons/src/main/java/org/wikimedia/commons/upload/UploadController.java b/commons/src/main/java/org/wikimedia/commons/upload/UploadController.java index 00c9a41e5..3a86db3fd 100644 --- a/commons/src/main/java/org/wikimedia/commons/upload/UploadController.java +++ b/commons/src/main/java/org/wikimedia/commons/upload/UploadController.java @@ -27,6 +27,7 @@ public class UploadController { private UploadService uploadService; private final Activity activity; + private Campaign campaign; final CommonsApplication app; public interface ContributionUploadProgress { @@ -35,7 +36,12 @@ public class UploadController { public UploadController(Activity activity) { this.activity = activity; - app = (CommonsApplication)activity.getApplicationContext(); + app = (CommonsApplication)activity.getApplicationContext(); + } + + public UploadController(Activity activity, Campaign campaign) { + this(activity); + this.campaign = campaign; } private boolean isUploadServiceConnected; @@ -64,12 +70,7 @@ public class UploadController { } } - /* The JavaScript is Leaking!*/ public void startUpload(String rawTitle, Uri mediaUri, String description, String mimeType, String source, ContributionUploadProgress onComplete) { - startUpload(rawTitle, mediaUri, description, mimeType, source, null, onComplete); - } - - public void startUpload(String rawTitle, Uri mediaUri, String description, String mimeType, String source, Campaign campaign, ContributionUploadProgress onComplete) { Contribution contribution; String title = rawTitle;