Yuvipanda has uploaded a new change for review.
https://gerrit.wikimedia.org/r/119800
Change subject: [WIP] Add User Contributions page
......................................................................
[WIP] Add User Contributions page
Activated by tapping on user name when logged in.
- Need to find alternate location for logout
Change-Id: I34cb52277dd1929b64f0f19fc74bdd83cd10418f
---
A wikipedia-it/src/main/java/org/wikipedia/test/FetchUserContribsTaskTest.java
M wikipedia/AndroidManifest.xml
M wikipedia/res/layout/fragment_navdrawer.xml
A wikipedia/res/layout/group_load_more.xml
A wikipedia/res/layout/item_usercontribs_entry.xml
M wikipedia/res/values/strings.xml
M wikipedia/src/main/java/org/wikipedia/NavDrawerFragment.java
M wikipedia/src/main/java/org/wikipedia/PageTitle.java
A wikipedia/src/main/java/org/wikipedia/pagehistory/PageHistoryItem.java
A
wikipedia/src/main/java/org/wikipedia/pagehistory/usercontributions/FetchUserContribsTask.java
A
wikipedia/src/main/java/org/wikipedia/pagehistory/usercontributions/UserContribsActivity.java
11 files changed, 427 insertions(+), 1 deletion(-)
git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia
refs/changes/00/119800/1
diff --git
a/wikipedia-it/src/main/java/org/wikipedia/test/FetchUserContribsTaskTest.java
b/wikipedia-it/src/main/java/org/wikipedia/test/FetchUserContribsTaskTest.java
new file mode 100644
index 0000000..ebb9050
--- /dev/null
+++
b/wikipedia-it/src/main/java/org/wikipedia/test/FetchUserContribsTaskTest.java
@@ -0,0 +1,36 @@
+package org.wikipedia.test;
+
+import android.content.*;
+import android.test.*;
+import org.wikipedia.*;
+import org.wikipedia.pagehistory.usercontributions.*;
+
+import java.util.concurrent.*;
+
+public class FetchUserContribsTaskTest extends
ActivityUnitTestCase<TestDummyActivity> {
+ private static final int TASK_COMPLETION_TIMEOUT = 20000;
+
+ public FetchUserContribsTaskTest() {
+ super(TestDummyActivity.class);
+ }
+
+ public void testUserContributionsFetch() throws Throwable {
+ final CountDownLatch completionLatch = new CountDownLatch(1);
+ startActivity(new Intent(), null, null);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ new
FetchUserContribsTask(getInstrumentation().getTargetContext(), new
Site("test.wikipedia.org"), "yuvipanda", 10, null) {
+ @Override
+ public void
onFinish(FetchUserContribsTask.UserContributionsList result) {
+ assertNotNull(result);
+ assertNotNull(result.getQueryContinue());
+ assertFalse(result.getContribs().size() < 10);
+ completionLatch.countDown();
+ }
+ }.execute();
+ }
+ });
+ assertTrue(completionLatch.await(TASK_COMPLETION_TIMEOUT,
TimeUnit.MILLISECONDS));
+ }
+}
diff --git a/wikipedia/AndroidManifest.xml b/wikipedia/AndroidManifest.xml
index a3c8abf..f57f1b6 100644
--- a/wikipedia/AndroidManifest.xml
+++ b/wikipedia/AndroidManifest.xml
@@ -68,6 +68,7 @@
android:label="@string/create_account_activity_title"
android:windowSoftInputMode="stateVisible|adjustResize"
/>
+ <activity
android:name=".pagehistory.usercontributions.UserContribsActivity"
android:label="My contributions"/>
<provider
android:authorities="org.wikipedia.history"
diff --git a/wikipedia/res/layout/fragment_navdrawer.xml
b/wikipedia/res/layout/fragment_navdrawer.xml
index 15f9d67..97996a0 100644
--- a/wikipedia/res/layout/fragment_navdrawer.xml
+++ b/wikipedia/res/layout/fragment_navdrawer.xml
@@ -78,6 +78,7 @@
android:layout_gravity="center_vertical"
android:text="@string/nav_item_tap_to_logout"
style="?android:textAppearanceSmallInverse"
+ android:visibility="gone"
/>
</LinearLayout>
</LinearLayout>
diff --git a/wikipedia/res/layout/group_load_more.xml
b/wikipedia/res/layout/group_load_more.xml
new file mode 100644
index 0000000..debf472
--- /dev/null
+++ b/wikipedia/res/layout/group_load_more.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="8dp"
+ android:background="?android:selectableItemBackground"
+ android:id="@+id/load_more_container"
+ >
+ <org.wikipedia.styledviews.StyledTextView
+ android:id="@+id/load_more_text"
+ android:layout_width="wrap_content"
+ android:layout_height="32dp"
+ android:layout_gravity="center"
+ android:gravity="center"
+ style="?android:textAppearanceMedium"
+ android:text="@string/user_contribs_more_action"
+ />
+
+ <ProgressBar
+ android:id="@+id/load_more_progress"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_gravity="center"
+ android:indeterminate="true"
+ style="?android:progressBarStyleSmall"
+ android:visibility="gone"
+ />
+
+</FrameLayout>
diff --git a/wikipedia/res/layout/item_usercontribs_entry.xml
b/wikipedia/res/layout/item_usercontribs_entry.xml
new file mode 100644
index 0000000..5919376
--- /dev/null
+++ b/wikipedia/res/layout/item_usercontribs_entry.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ >
+ <org.wikipedia.styledviews.StyledTextView
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:id="@+id/user_contrib_item_page_name"
+ style="?android:textAppearanceMedium"
+ android:textStyle="bold"
+ />
+
+ <org.wikipedia.styledviews.StyledTextView
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:id="@+id/user_contrib_item_edit_summary"
+ style="?android:textAppearanceSmall"
+ />
+
+ <org.wikipedia.styledviews.StyledTextView
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:id="@+id/user_contrib_item_time_ago"
+ style="?android:textAppearanceSmall"
+ />
+</LinearLayout>
\ No newline at end of file
diff --git a/wikipedia/res/values/strings.xml b/wikipedia/res/values/strings.xml
index 1e7c468..725a27a 100644
--- a/wikipedia/res/values/strings.xml
+++ b/wikipedia/res/values/strings.xml
@@ -120,4 +120,5 @@
<string name="nav_item_login_benefits">If you Log in, your edits will be
associated with your username and your IP address will not be publicly
visible.</string>
<string name="nav_item_tap_to_logout">Tap to log out</string>
<string name="create_account_account_created_toast">Account
created!</string>
+ <string name="user_contribs_more_action">Load more</string>
</resources>
diff --git a/wikipedia/src/main/java/org/wikipedia/NavDrawerFragment.java
b/wikipedia/src/main/java/org/wikipedia/NavDrawerFragment.java
index 98057e8..f63dae4 100644
--- a/wikipedia/src/main/java/org/wikipedia/NavDrawerFragment.java
+++ b/wikipedia/src/main/java/org/wikipedia/NavDrawerFragment.java
@@ -9,6 +9,7 @@
import android.widget.*;
import org.wikipedia.history.*;
import org.wikipedia.login.*;
+import org.wikipedia.pagehistory.usercontributions.*;
import org.wikipedia.random.*;
import org.wikipedia.savedpages.*;
import org.wikipedia.settings.*;
@@ -119,7 +120,10 @@
randomHandler.doVistRandomArticle();
break;
case R.id.nav_item_username:
- doLogout();
+ intent.setClass(this.getActivity(),
UserContribsActivity.class);
+ startActivity(intent);
+
+// doLogout();
break;
case R.id.nav_item_send_feedback:
// Will be stripped out in prod builds
diff --git a/wikipedia/src/main/java/org/wikipedia/PageTitle.java
b/wikipedia/src/main/java/org/wikipedia/PageTitle.java
index 9d94d31..84b4c3e 100644
--- a/wikipedia/src/main/java/org/wikipedia/PageTitle.java
+++ b/wikipedia/src/main/java/org/wikipedia/PageTitle.java
@@ -1,10 +1,12 @@
package org.wikipedia;
import android.os.*;
+import android.text.*;
import org.json.*;
import java.io.*;
import java.net.*;
+import java.util.*;
/**
* Immutable value object representing the text of a page.
@@ -29,6 +31,33 @@
this(namespace, text, null, site);
}
+ public PageTitle(final String text, final Site site) {
+ // FIXME: Does not handle mainspace articles with a colon in the title
well at all
+ String parts[];
+ if (text.indexOf("#") != -1) {
+ try {
+ this.fragment = URLDecoder.decode(text.split("#")[1], "utf-8");
+ parts = text.split("#")[0].split(":");
+ } catch (UnsupportedEncodingException e) {
+ // STUPID STUPID JAVA
+ throw new RuntimeException(e);
+ }
+ } else {
+ this.fragment = null;
+ parts = text.split(":");
+ }
+
+ if (parts.length > 1) {
+ this.namespace = parts[0];
+ this.text = TextUtils.join(":", Arrays.copyOfRange(parts, 1,
parts.length));
+ } else {
+ this.namespace = null;
+ this.text = parts[0];
+ }
+
+ this.site = site;
+ }
+
public String getNamespace() {
return namespace;
}
diff --git
a/wikipedia/src/main/java/org/wikipedia/pagehistory/PageHistoryItem.java
b/wikipedia/src/main/java/org/wikipedia/pagehistory/PageHistoryItem.java
new file mode 100644
index 0000000..bb3b5ce
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikipedia/pagehistory/PageHistoryItem.java
@@ -0,0 +1,75 @@
+package org.wikipedia.pagehistory;
+
+import android.os.*;
+import org.wikipedia.*;
+
+import java.util.*;
+
+public class PageHistoryItem implements Parcelable {
+ private final String username;
+ private final Date timestamp;
+ private final String summary;
+ private final int sizeDiff;
+ private final PageTitle title;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public String getSummary() {
+ return summary;
+ }
+
+ public int getSizeDiff() {
+ return sizeDiff;
+ }
+
+ public PageTitle getTitle() {
+ return title;
+ }
+
+ public PageHistoryItem(String username, Date timestamp, String summary,
int sizeDiff, PageTitle title) {
+ this.username = username;
+ this.timestamp = timestamp;
+ this.summary = summary;
+ this.sizeDiff = sizeDiff;
+ this.title = title;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeString(username);
+ parcel.writeSerializable(timestamp);
+ parcel.writeString(summary);
+ parcel.writeInt(sizeDiff);
+ parcel.writeParcelable(title, flags);
+ }
+
+ private PageHistoryItem(Parcel in) {
+ this.username = in.readString();
+ this.timestamp = (Date) in.readSerializable();
+ this.summary = in.readString();
+ this.sizeDiff = in.readInt();
+ this.title = in.readParcelable(PageTitle.class.getClassLoader());
+ }
+
+ public static final Parcelable.Creator<PageHistoryItem> CREATOR
+ = new Parcelable.Creator<PageHistoryItem>() {
+ public PageHistoryItem createFromParcel(Parcel in) {
+ return new PageHistoryItem(in);
+ }
+
+ public PageHistoryItem[] newArray(int size) {
+ return new PageHistoryItem[size];
+ }
+ };
+}
diff --git
a/wikipedia/src/main/java/org/wikipedia/pagehistory/usercontributions/FetchUserContribsTask.java
b/wikipedia/src/main/java/org/wikipedia/pagehistory/usercontributions/FetchUserContribsTask.java
new file mode 100644
index 0000000..631e929
--- /dev/null
+++
b/wikipedia/src/main/java/org/wikipedia/pagehistory/usercontributions/FetchUserContribsTask.java
@@ -0,0 +1,84 @@
+package org.wikipedia.pagehistory.usercontributions;
+
+import android.content.*;
+import org.json.*;
+import org.mediawiki.api.json.*;
+import org.wikipedia.*;
+import org.wikipedia.pagehistory.*;
+
+import java.util.*;
+
+public class FetchUserContribsTask extends
ApiTask<FetchUserContribsTask.UserContributionsList> {
+ private final WikipediaApp app;
+ private final Site site;
+ private final String username;
+ private final int numberToFetch;
+ private final String queryContinue;
+
+ public FetchUserContribsTask(Context context, Site site, String username,
int numberToFetch, String queryContinue) {
+ super(
+ 1,
+
((WikipediaApp)context.getApplicationContext()).getAPIForSite(site)
+ );
+ app = (WikipediaApp)context.getApplicationContext();
+ this.site = site;
+ this.username = username;
+ this.numberToFetch = numberToFetch;
+ this.queryContinue = queryContinue;
+ }
+
+ @Override
+ public RequestBuilder buildRequest(Api api) {
+ RequestBuilder builder = api.action("query")
+ .param("list", "usercontribs")
+ .param("uclimit", String.valueOf(numberToFetch))
+ .param("ucuser", username)
+ .param("ucprop", "title|timestamp|comment|sizediff");
+ if (queryContinue != null) {
+ builder.param("ucstart", queryContinue);
+ }
+ return builder;
+ }
+
+ @Override
+ public UserContributionsList processResult(ApiResult result) throws
Throwable {
+ String continueString = null;
+ if (result.asObject().has("query-continue")) {
+ continueString =
result.asObject().optJSONObject("query-continue").optJSONObject("usercontribs").optString("ucstart");
+ }
+ JSONArray contribsJSON =
result.asObject().optJSONObject("query").optJSONArray("usercontribs");
+
+ ArrayList<PageHistoryItem> contribs = new
ArrayList<PageHistoryItem>(contribsJSON.length());
+
+ for (int i = 0; i < contribsJSON.length(); i++) {
+ JSONObject contribJSON = contribsJSON.optJSONObject(i);
+ contribs.add(new PageHistoryItem(
+ contribJSON.optString("user"),
+ Utils.parseMWDate(contribJSON.optString("timestamp")),
+ contribJSON.optString("comment"),
+ contribJSON.optInt("sizeDiff"),
+ new PageTitle(contribJSON.optString("title"), site)
+ ));
+ }
+
+ return new UserContributionsList(contribs, continueString);
+ }
+
+ public static class UserContributionsList {
+ private final ArrayList<PageHistoryItem> contribs;
+ private final String queryContinue;
+
+ public UserContributionsList(ArrayList<PageHistoryItem> contribs,
String queryContinue) {
+ this.contribs = contribs;
+ this.queryContinue = queryContinue;
+ }
+
+ public ArrayList<PageHistoryItem> getContribs() {
+ return contribs;
+ }
+
+ public String getQueryContinue() {
+ return queryContinue;
+ }
+ }
+}
diff --git
a/wikipedia/src/main/java/org/wikipedia/pagehistory/usercontributions/UserContribsActivity.java
b/wikipedia/src/main/java/org/wikipedia/pagehistory/usercontributions/UserContribsActivity.java
new file mode 100644
index 0000000..5c5ea26
--- /dev/null
+++
b/wikipedia/src/main/java/org/wikipedia/pagehistory/usercontributions/UserContribsActivity.java
@@ -0,0 +1,137 @@
+package org.wikipedia.pagehistory.usercontributions;
+
+import android.os.*;
+import android.support.v7.app.*;
+import android.text.*;
+import android.view.*;
+import android.widget.*;
+import org.wikipedia.*;
+import org.wikipedia.pagehistory.*;
+
+import java.util.*;
+
+public class UserContribsActivity extends ActionBarActivity {
+ private ListView userContribsList;
+ private View moreContainer;
+ private TextView moreText;
+ private ProgressBar moreProgress;
+
+ private String lastContinue = null;
+ private ArrayList<PageHistoryItem> contribs = new
ArrayList<PageHistoryItem>();
+
+ private UserContribsAdapter adapter;
+
+ private WikipediaApp app;
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_user_contribs);
+
+ app = (WikipediaApp)getApplicationContext();
+
+ userContribsList = (ListView)findViewById(R.id.user_contribs_list);
+ moreContainer = getLayoutInflater().inflate(R.layout.group_load_more,
null, false);
+ moreText = (TextView) moreContainer.findViewById(R.id.load_more_text);
+ moreProgress = (ProgressBar)
moreContainer.findViewById(R.id.load_more_progress);
+
+ moreContainer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ fetchMore();
+ }
+ });
+
+ adapter = new UserContribsAdapter();
+ userContribsList.setAdapter(adapter);
+
+ userContribsList.addFooterView(moreContainer);
+
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+ fetchMore();
+ }
+
+ private boolean isFetching = false;
+ private void fetchMore() {
+ if (isFetching) {
+ return;
+ }
+ new FetchUserContribsTask(this, app.getPrimarySite(),
app.getUserInfoStorage().getUser().getUsername(), 24, lastContinue) {
+ @Override
+ public void onBeforeExecute() {
+ isFetching = true;
+ moreProgress.setVisibility(View.VISIBLE);
+ moreText.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onFinish(UserContributionsList result) {
+ lastContinue = result.getQueryContinue();
+ contribs.addAll(result.getContribs());
+ adapter.notifyDataSetChanged();
+ isFetching = false;
+
+ moreProgress.setVisibility(View.GONE);
+ moreText.setVisibility(View.VISIBLE);
+
+ if (lastContinue == null) {
+ // We got no continue back, so that means we have loaded
all the things!
+ moreContainer.setVisibility(View.GONE);
+ }
+ }
+ }.execute();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ }
+
+ return false;
+ }
+
+ private class UserContribsAdapter extends BaseAdapter{
+
+ @Override
+ public int getCount() {
+ return contribs.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return contribs.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @Override
+ public View getView(int pos, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView =
getLayoutInflater().inflate(R.layout.item_usercontribs_entry, parent, false);
+ }
+
+ TextView titleText = (TextView)
convertView.findViewById(R.id.user_contrib_item_page_name);
+ TextView summaryText = (TextView)
convertView.findViewById(R.id.user_contrib_item_edit_summary);
+ TextView timeAgoText = (TextView)
convertView.findViewById(R.id.user_contrib_item_time_ago);
+
+ PageHistoryItem item = (PageHistoryItem) getItem(pos);
+ titleText.setText(item.getTitle().getDisplayText());
+ summaryText.setText(Html.fromHtml(item.getSummary()));
+ timeAgoText.setText(Utils.formatDateRelative(item.getTimestamp()));
+
+ if (summaryText.getText().length() == 0) {
+ summaryText.setVisibility(View.GONE);
+ } else {
+ summaryText.setVisibility(View.VISIBLE);
+ }
+
+ return convertView;
+ }
+ }
+}
\ No newline at end of file
--
To view, visit https://gerrit.wikimedia.org/r/119800
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I34cb52277dd1929b64f0f19fc74bdd83cd10418f
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Yuvipanda <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits