Brion VIBBER has submitted this change and it was merged.

Change subject: Add User Contributions page
......................................................................


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
A wikipedia/res/layout/activity_user_contribs.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-qq/strings.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
13 files changed, 452 insertions(+), 1 deletion(-)

Approvals:
  Brion VIBBER: Verified; Looks good to me, approved



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..6f78e5d 100644
--- a/wikipedia/AndroidManifest.xml
+++ b/wikipedia/AndroidManifest.xml
@@ -68,6 +68,8 @@
                   android:label="@string/create_account_activity_title"
                   android:windowSoftInputMode="stateVisible|adjustResize"
                 />
+        <activity 
android:name=".pagehistory.usercontributions.UserContribsActivity"
+                  android:label="@string/activity_my_contributions_title"/>
 
         <provider
             android:authorities="org.wikipedia.history"
diff --git a/wikipedia/res/layout/activity_user_contribs.xml 
b/wikipedia/res/layout/activity_user_contribs.xml
new file mode 100644
index 0000000..fe9d28a
--- /dev/null
+++ b/wikipedia/res/layout/activity_user_contribs.xml
@@ -0,0 +1,11 @@
+<?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">
+    <ListView android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:id="@+id/user_contribs_list"
+              />
+</LinearLayout>
\ No newline at end of file
diff --git a/wikipedia/res/layout/fragment_navdrawer.xml 
b/wikipedia/res/layout/fragment_navdrawer.xml
index 22f1f6b..99b4ab1 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-qq/strings.xml 
b/wikipedia/res/values-qq/strings.xml
index 9c8cb4d..73aef6e 100644
--- a/wikipedia/res/values-qq/strings.xml
+++ b/wikipedia/res/values-qq/strings.xml
@@ -64,4 +64,6 @@
   <string name="zero_settings_devmode_summary">Prerelease explanation text 
explaining that Wikipedia Zero Devmode on means that Wikipedia Zero detection 
will be turned on</string>
   <string name="random_progress">Message shown in progress popup dialog while 
waiting for a random article to be fetched</string>
   <string name="create_account_account_created_toast">Message shown in a small 
toast when account creation is successful.</string>
+  <string name="user_contribs_more_action">Text shown as a button at the end 
of lists that let the user load more items.</string>
+  <string name="activity_my_contributions_title">Title for screen showing list 
of edits by current user.</string>
 </resources>
diff --git a/wikipedia/res/values/strings.xml b/wikipedia/res/values/strings.xml
index 1e7c468..d8ba0db 100644
--- a/wikipedia/res/values/strings.xml
+++ b/wikipedia/res/values/strings.xml
@@ -120,4 +120,6 @@
     <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>
+    <string name="activity_my_contributions_title">My Contributions</string>
 </resources>
diff --git a/wikipedia/src/main/java/org/wikipedia/NavDrawerFragment.java 
b/wikipedia/src/main/java/org/wikipedia/NavDrawerFragment.java
index b00b405..1abd875 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.*;
@@ -132,7 +133,8 @@
                 randomHandler.doVistRandomArticle();
                 break;
             case R.id.nav_item_username:
-                doLogout();
+                intent.setClass(this.getActivity(), 
UserContribsActivity.class);
+                startActivity(intent);
                 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..c8bad3b
--- /dev/null
+++ 
b/wikipedia/src/main/java/org/wikipedia/pagehistory/usercontributions/UserContribsActivity.java
@@ -0,0 +1,149 @@
+package org.wikipedia.pagehistory.usercontributions;
+
+import android.os.*;
+import android.support.v7.app.*;
+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);
+
+        if (savedInstanceState != null) {
+            lastContinue = savedInstanceState.getString("lastContinue");
+            contribs = savedInstanceState.getParcelableArrayList("contribs");
+            adapter.notifyDataSetChanged();
+        } else {
+            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;
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putString("lastContinue", lastContinue);
+        outState.putParcelableArrayList("contribs", contribs);
+    }
+
+    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(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: merged
Gerrit-Change-Id: I34cb52277dd1929b64f0f19fc74bdd83cd10418f
Gerrit-PatchSet: 8
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Yuvipanda <yuvipa...@gmail.com>
Gerrit-Reviewer: Brion VIBBER <br...@wikimedia.org>
Gerrit-Reviewer: Siebrand <siebr...@kitano.nl>
Gerrit-Reviewer: Yuvipanda <yuvipa...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to