Commits

smorik committed 6b5a4f6

-New activity to update issue's title, content, status, and priority.

  • Participants
  • Parent commits 66d7c0d

Comments (0)

Files changed (10)

AndroidManifest.xml

 		<activity android:name="NewIssueActivity"></activity>
 		<activity android:name="IssueActivity"></activity>
 		<activity android:name="NewIssueCommentActivity"></activity>
+		<activity android:name="UpdateIssueActivity"></activity>
     </application>
 </manifest>

res/drawable-hdpi/pen_32x32.png

Added
New image

res/layout/new_issue.xml

             android:orientation="vertical" >
 
             <!-- Repository name -->
+
             <TextView
                 android:id="@+id/repository_description"
                 android:layout_width="match_parent"
             </TextView>
 
             <!-- Issue title -->
+
             <EditText
                 android:id="@+id/new_issue_title"
                 android:layout_width="match_parent"
             </EditText>
 
             <!-- Issue Content -->
+
             <TextView
                 android:id="@+id/TextView02"
                 android:layout_width="match_parent"
                 android:lines="3" >
             </EditText>
 
+            <!-- Issue status -->
+
+            <TextView
+                android:id="@+id/StatusLabel"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_margin="5dip"
+                android:text="@string/status" />
+
+            <Spinner
+                android:id="@+id/new_issue_status"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:entries="@array/issue_status_options" />
+
             <!-- Issue type -->
+
             <TextView
                 android:id="@+id/TextView01"
                 android:layout_width="match_parent"
             </Spinner>
 
             <!-- Issue priority -->
+
             <TextView
                 android:id="@+id/PriorityLabel"
                 android:layout_width="match_parent"

res/menu/menu_manage_issue.xml

+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/menu_update"
+        android:icon="@drawable/pen_32x32"
+        android:showAsAction="always"
+        android:title="@string/update_issue">
+    </item>
+    
+    <item
+        android:id="@+id/menu_add"
+        android:icon="@drawable/plus_alt_32x32"
+        android:showAsAction="always"
+        android:title="@string/add">
+    </item>
+
+</menu>

res/menu/menu_simple_add.xml

 <?xml version="1.0" encoding="utf-8"?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
-    <item android:id="@+id/menu_add" android:title="@string/add" android:showAsAction="always" android:icon="@drawable/plus_alt_32x32"></item>
     
+    <item
+        android:id="@+id/menu_add"
+        android:icon="@drawable/plus_alt_32x32"
+        android:showAsAction="always"
+        android:title="@string/add">
+    </item>
 
 </menu>

res/values/strings.xml

     <string name="refresh">Refresh</string>
     <string name="clear_cache">Clear cache</string>
     <string name="new_issue">Create new issue</string>
+    <string name="update_issue">Update issue</string>
     <string name="title">Title</string>
     <string name="content">Content</string>
     <string name="type">Type</string>
     <string name="submit_new_issue">Submit new issue</string>
     <string name="hint">"Note: You don't need to login to use the search function!"</string>
     <string name="issue_filter_prompt">Filter issues</string>
+    <string name="status">Status</string>
     <string-array name="status_of_issue">
         <item>Show all issues</item>
         <item>new &amp; open</item>
         <item>duplicate</item>
         <item>wontfix</item>
     </string-array>
+    <string-array name="issue_status_options">
+        <item>new</item>
+        <item>open</item>
+        <item>resolved</item>
+        <item>on hold</item>
+        <item>invalid</item>
+        <item>duplicate</item>
+        <item>wontfix</item>
+    </string-array>
     <string name="menu_source">Source</string>
     <string name="submit_comment">Submit</string>
     <string name="new_comment_hint">Leave a comment</string>

src/com/saibotd/bitbeaker/IssueActivity.java

 	private ListView listView;//issue's content and comments
 	ActionMode mMode;
 	static final int NEW_ISSUE_COMMENT = 0;
+	static final int UPDATE_ISSUE = 1;
 
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 	
 	public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getSupportMenuInflater();
-        inflater.inflate(R.menu.menu_simple_add, menu);
+        inflater.inflate(R.menu.menu_manage_issue, menu);
         return true;
     }
     
     @Override
    	public boolean onOptionsItemSelected(MenuItem item) {
    	    switch (item.getItemId()) {
-   		    case R.id.menu_add:
+   	    
+   	    case R.id.menu_update: {
+   	    	Intent intent = new Intent(this, UpdateIssueActivity.class);
+   	    	intent.putExtras(getIntent().getExtras());
+   	    	startActivityForResult(intent, UPDATE_ISSUE);
+   	    	return true;
+   	    }
+   	    
+   		    case R.id.menu_add: {
    		    	Intent intent = new Intent(this, NewIssueCommentActivity.class);
    				intent.putExtras(getIntent().getExtras()); // Just passing the current bundle instead of creating a new one!
    				startActivityForResult(intent, NEW_ISSUE_COMMENT);
    		        return true;
+   		    }
    		    default:
    		        return super.onOptionsItemSelected(item);
    	    }

src/com/saibotd/bitbeaker/MyActivity.java

 		return result;
 	}
 
-	private static String convertStreamToString(InputStream is) {
+	protected static String convertStreamToString(InputStream is) {
 
 		String line = null;
 		try {

src/com/saibotd/bitbeaker/NewIssueActivity.java

 					.toString();
 			String priority = ((Spinner) findViewById(R.id.new_issue_priority)).getSelectedItem()
 					.toString();
+			String status = ((Spinner)findViewById(R.id.new_issue_status)).getSelectedItem().toString();
 			AsyncLoader asyncLoader = new AsyncLoader();
 			asyncLoader.execute("https://api.bitbucket.org/1.0/repositories/" 
 					+ owner + "/" + slug
 					+ encode(title) 
 					+ "&content=" 
 					+ encode(content)
-					+ "&kind=" + encode(type) 
-					+ "&priority=" + encode(priority)
+					+ "&kind=" + type
+					+ "&priority=" + priority
+					+ "&status=" + status
 					);
 		default:
 			return super.onOptionsItemSelected(item);

src/com/saibotd/bitbeaker/UpdateIssueActivity.java

+package com.saibotd.bitbeaker;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+
+import javax.net.ssl.HttpsURLConnection;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Base64;
+import android.util.Log;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.Toast;
+
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+
+public class UpdateIssueActivity extends MyActivity {
+
+	private static final boolean DEBUG = true;
+	
+	private static final String TAG = "UpdateIssueActivity";
+	
+	private String slug;
+	private String owner;
+	
+	private int issue_id;
+	private String issue_title;
+
+	// Issue widgets.
+	private EditText titleEditor, contentEditor;
+	private Spinner typeSpinner, prioritySpinner, statusSpinner;
+
+	private String initialTitle = "", initialContent = "", initialType = "", initialPriority = "",
+			initialStatus = "";
+
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+
+		super.onCreate(savedInstanceState);
+
+		setSupportProgressBarIndeterminateVisibility(false);
+
+		Bundle b = getIntent().getExtras();
+
+		slug = b.getString("slug");
+		owner = b.getString("owner");
+
+		issue_id = b.getInt("id");
+		issue_title = b.getString("title");
+
+		// Set layout and actionbar title.
+		setContentView(R.layout.new_issue);
+		setTitle(slug);
+		getSupportActionBar().setSubtitle("Update issue");
+
+		// Load issue data.
+		AsyncLoader asyncLoader = new AsyncLoader();
+		asyncLoader.execute("https://api.bitbucket.org/1.0/repositories/" + owner + "/" + slug
+				+ "/issues/" + issue_id);
+
+		if (DEBUG) {
+			Log.d(TAG, "intent extras: " + b.toString());
+		}
+
+	}
+
+	public boolean onCreateOptionsMenu(Menu menu) {
+		MenuInflater inflater = getSupportMenuInflater();
+		inflater.inflate(R.menu.menu_simple_submit, menu);
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item) {
+
+		switch (item.getItemId()) {
+
+		case R.id.menu_submit: {
+
+			// Submit updated issue to bitbucket.
+			UpdateLoader updateloader = new UpdateLoader();
+			String content = contentEditor.getText().toString();
+			content = encode(content);
+			String updateURI = "https://api.bitbucket.org/1.0/repositories/" 
+				+ owner     + "/" 
+				+ slug      + "/"
+				+ "issues/" 
+				+ issue_id  + "/";
+				String postParams = "";
+				
+			// Only add parameters that have changed.
+			if (!initialTitle.equals(titleEditor.getText().toString())) {
+
+				if (0 < postParams.length()) {
+					postParams += "&title=";
+				} else {
+					postParams = "title=";
+				}
+				postParams += encode(titleEditor.getText().toString());
+
+			}
+
+			if (!initialContent.equals(contentEditor.getText().toString())) {
+
+				if (0 < postParams.length()) {
+					postParams += "&content=";
+				} else {
+					postParams = "content=";
+				}
+				postParams += encode(contentEditor.getText().toString());
+			}
+
+			if (!initialType.equalsIgnoreCase(typeSpinner.getSelectedItem().toString())) {
+
+				if (0 < postParams.length()) {
+					postParams += "&kind=";
+				} else {
+					postParams = "kind=";
+				}
+				postParams += typeSpinner.getSelectedItem();
+
+			}
+			
+			if (!initialPriority.equalsIgnoreCase(prioritySpinner.getSelectedItem().toString())) {
+
+				if (0 < postParams.length()) {
+					postParams += "&priority=";
+				} else {
+					postParams = "priority=";
+				}
+				postParams += prioritySpinner.getSelectedItem().toString();
+
+			}
+			
+			if (!initialStatus.equalsIgnoreCase(statusSpinner.getSelectedItem().toString())) {
+
+				if (0 < postParams.length()) {
+					postParams += "&status=";
+				} else {
+					postParams = "status=";
+				}
+				postParams += statusSpinner.getSelectedItem().toString();
+
+			}
+			
+			bitbeaker.delKV(updateURI);
+			updateloader.execute(updateURI, postParams);
+			return true;
+
+		}
+		default:
+			return super.onOptionsItemSelected(item);
+		}
+
+	}
+
+	private class UpdateLoader extends AsyncLoader {
+
+		private String errorMSG = "There was a problem retrieving and/or processing data from Bitbucket.org. Checking your data connectivity and trying again might help.";
+		
+		@Override
+		protected String doInBackground(String... params) {
+			String postParams = null;
+			if(params.length >= 2) postParams = params[1];
+			if(params.length == 3) errorMSG = params[2];
+			return getAuthHTTPS(params[0], postParams);
+		}
+		
+		@Override
+		protected void onPostExecute(String result) {
+			setSupportProgressBarIndeterminateVisibility(false);
+			done();
+		}
+
+	}
+	
+	@Override
+	protected String getAuthHTTPS(String webAdress, String postParams) {
+		Log.d("FETCH", webAdress);
+		String cache = bitbeaker.getKV(webAdress);
+		if (cache != null)
+			return cache;
+		URL url;
+		InputStream in = null;
+		try {
+			url = new URL(webAdress);
+			HttpsURLConnection urlConnection = (HttpsURLConnection) url
+					.openConnection();
+			urlConnection.setUseCaches(true);
+			if (!bitbeaker.getUsername().equals("")) {
+				String loginString = bitbeaker.getUsername() + ":"
+						+ bitbeaker.getPassword();
+				urlConnection.setRequestProperty(
+						"Authorization",
+						"Basic "
+								+ Base64.encodeToString(loginString.getBytes(),
+										Base64.DEFAULT).trim());
+				Log.d("AUTH", "True");
+			}
+			if (postParams != null) {
+				urlConnection.setDoOutput(true);
+				urlConnection.setRequestMethod("PUT");
+				OutputStreamWriter out = new OutputStreamWriter(
+						urlConnection.getOutputStream());
+				out.write(postParams);
+				Log.d("PUT", postParams);
+				out.close();
+			}
+			in = new BufferedInputStream(urlConnection.getInputStream());
+		} catch (Exception e) {
+			e.printStackTrace();
+			return "Fail";
+		}
+		String result = convertStreamToString(in);
+		if (!result.trim().equals("") && result.length() < 100000)
+			bitbeaker.setKV(webAdress, result);
+		return result;
+	}
+	
+	private void done() {
+		Toast.makeText(this, "Updated issue submitted!", Toast.LENGTH_LONG).show();
+		setResult(Activity.RESULT_OK, getIntent());
+		finish();
+	}
+
+	protected void AsyncLoaderDone(String result) {
+		super.AsyncLoaderDone(result);
+
+		// Initialize issue widgets.
+		try {
+
+			JSONObject issueJson = new JSONObject(result);
+
+			titleEditor = (EditText) findViewById(R.id.new_issue_title);
+			titleEditor.setText(issue_title);
+
+			// Issue content.
+			initialContent = issueJson.getString("content");
+			contentEditor = (EditText) findViewById(R.id.new_issue_content);
+			contentEditor.setText(initialContent);
+
+			// Issue type.
+			initialType = issueJson.getJSONObject("metadata").getString("kind");
+			typeSpinner = (Spinner) findViewById(R.id.new_issue_type);
+			String[] typeOptions = getResources().getStringArray(R.array.type_of_issue);
+			int type_index = 0;
+			for (String type : typeOptions) {
+				if (type.equalsIgnoreCase(initialType)) {
+					break;
+				}
+				++type_index;
+			}
+			typeSpinner.setSelection(type_index);
+
+			// Issue priority.
+			initialPriority = issueJson.getString("priority");
+			prioritySpinner = (Spinner) findViewById(R.id.new_issue_priority);
+			String[] priorityOptions = getResources().getStringArray(R.array.priority_of_issue);
+			int priority_index = 0;
+			for (String priority : priorityOptions) {
+				if (priority.equalsIgnoreCase(initialPriority)) {
+					break;
+				}
+				++priority_index;
+			}
+			prioritySpinner.setSelection(priority_index);
+			
+			// Issue status.
+			initialStatus = issueJson.getString("status");
+			statusSpinner = (Spinner) findViewById(R.id.new_issue_status);
+			String[] statusOptions = getResources().getStringArray(R.array.issue_status_options);
+			int status_index = 0;
+			for (String status : statusOptions) {
+				if (status.equalsIgnoreCase(initialStatus)) {
+					break;
+				}
+				++status_index;
+			}
+			statusSpinner.setSelection(status_index);
+
+		} catch (JSONException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+}