Add editable swipeable multiple upload view

Major changes everywhere. Uses MediaDetailFragment for editing.
This commit is contained in:
YuviPanda 2013-03-20 01:14:00 +05:30
parent 534ac658a1
commit 4977e0a800
8 changed files with 172 additions and 67 deletions

View file

@ -1,13 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/uploadsFragmentContainer"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<fragment
android:name="org.wikimedia.commons.MultipleUploadListFragment"
android:id="@+id/uploadsListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout> </FrameLayout>

View file

@ -37,13 +37,13 @@
android:padding="8dp" android:padding="8dp"
> >
<TextView <EditText
android:id="@+id/mediaDetailTitle" android:id="@+id/mediaDetailTitle"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="#FFFFFFFF" android:textColor="#FFFFFFFF"
style="?android:textAppearanceMedium" style="?android:textAppearanceMedium"
android:typeface="serif" /> />
<!-- <TextView <!-- <TextView
android:id="@+id/mediaDetailDescription" android:id="@+id/mediaDetailDescription"
android:layout_width="fill_parent" android:layout_width="fill_parent"

View file

@ -39,6 +39,9 @@ public class Media implements Parcelable {
public static Pattern displayTitlePattern = Pattern.compile("(.*)(\\.\\w+)", Pattern.CASE_INSENSITIVE); public static Pattern displayTitlePattern = Pattern.compile("(.*)(\\.\\w+)", Pattern.CASE_INSENSITIVE);
public String getDisplayTitle() { public String getDisplayTitle() {
if(filename == null) {
return "";
}
// FIXME: Gross hack bercause my regex skills suck maybe or I am too lazy who knows // FIXME: Gross hack bercause my regex skills suck maybe or I am too lazy who knows
String title = filename.replaceFirst("^File:", ""); String title = filename.replaceFirst("^File:", "");
Matcher matcher = displayTitlePattern.matcher(title); Matcher matcher = displayTitlePattern.matcher(title);
@ -66,6 +69,10 @@ public class Media implements Parcelable {
return filename; return filename;
} }
public void setFilename(String filename) {
this.filename = filename;
}
public String getDescription() { public String getDescription() {
return description; return description;
} }

View file

@ -12,6 +12,7 @@ import android.os.IBinder;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.View;
import android.widget.*; import android.widget.*;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
@ -19,20 +20,49 @@ import com.nostra13.universalimageloader.core.DisplayImageOptions;
import org.wikimedia.commons.auth.AuthenticatedActivity; import org.wikimedia.commons.auth.AuthenticatedActivity;
import org.wikimedia.commons.auth.WikiAccountAuthenticator; import org.wikimedia.commons.auth.WikiAccountAuthenticator;
import org.wikimedia.commons.contributions.Contribution; import org.wikimedia.commons.contributions.Contribution;
import org.wikimedia.commons.media.MediaDetailPagerFragment;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
public class MultipleShareActivity extends AuthenticatedActivity { public class MultipleShareActivity
extends AuthenticatedActivity
implements MediaDetailPagerFragment.MediaDetailProvider,
AdapterView.OnItemClickListener {
private CommonsApplication app; private CommonsApplication app;
private ArrayList<Contribution> photosList = new ArrayList<Contribution>(); private ArrayList<Contribution> photosList = null;
private MultipleUploadListFragment uploadsList; private MultipleUploadListFragment uploadsList;
private MediaDetailPagerFragment mediaDetails;
public MultipleShareActivity() { public MultipleShareActivity() {
super(WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE); super(WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE);
} }
public Media getMediaAtPosition(int i) {
return photosList.get(i);
}
public int getTotalMediaCount() {
if(photosList == null) {
return 0;
}
return photosList.size();
}
public void notifyDatasetChanged() {
if(uploadsList != null) {
uploadsList.notifyDatasetChanged();
}
}
public void onItemClick(AdapterView<?> adapterView, View view, int index, long item) {
showDetail(index);
}
private class StartMultipleUploadTask extends AsyncTask<Void, Integer, Void> { private class StartMultipleUploadTask extends AsyncTask<Void, Integer, Void> {
ProgressDialog dialog; ProgressDialog dialog;
@ -126,8 +156,11 @@ public class MultipleShareActivity extends AuthenticatedActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_multiple_uploads); setContentView(R.layout.activity_multiple_uploads);
uploadsList = (MultipleUploadListFragment)getSupportFragmentManager().findFragmentById(R.id.uploadsListFragment);
app = (CommonsApplication)this.getApplicationContext(); app = (CommonsApplication)this.getApplicationContext();
if(savedInstanceState != null) {
photosList = savedInstanceState.getParcelableArrayList("uploadsList");
}
requestAuthToken(); requestAuthToken();
} }
@ -141,32 +174,57 @@ public class MultipleShareActivity extends AuthenticatedActivity {
} }
} }
private void showDetail(int i) {
if(mediaDetails == null ||!mediaDetails.isVisible()) {
mediaDetails = new MediaDetailPagerFragment(true);
this.getSupportFragmentManager()
.beginTransaction()
.replace(R.id.uploadsFragmentContainer, mediaDetails)
.addToBackStack(null)
.commit();
this.getSupportFragmentManager().executePendingTransactions();
}
mediaDetails.showImage(i);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList("uploadsList", photosList);
}
@Override @Override
protected void onAuthCookieAcquired(String authCookie) { protected void onAuthCookieAcquired(String authCookie) {
app.getApi().setAuthCookie(authCookie); app.getApi().setAuthCookie(authCookie);
Intent intent = getIntent(); Intent intent = getIntent();
if(intent.getAction() == Intent.ACTION_SEND_MULTIPLE) { if(intent.getAction() == Intent.ACTION_SEND_MULTIPLE) {
ArrayList<Uri> urisList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); if(photosList == null) {
for(int i=0; i < urisList.size(); i++) { photosList = new ArrayList<Contribution>();
Contribution up = new Contribution(); ArrayList<Uri> urisList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
Uri uri = urisList.get(i); for(int i=0; i < urisList.size(); i++) {
up.setLocalUri(uri); Contribution up = new Contribution();
up.setTag("mimeType", intent.getType()); Uri uri = urisList.get(i);
up.setTag("sequence", i); up.setLocalUri(uri);
photosList.add(up); up.setTag("mimeType", intent.getType());
up.setTag("sequence", i);
photosList.add(up);
}
} }
uploadsList.setData(photosList); uploadsList = new MultipleUploadListFragment();
this.getSupportFragmentManager()
.beginTransaction()
.add(R.id.uploadsFragmentContainer, uploadsList)
.commit();
this.getSupportFragmentManager().executePendingTransactions();
setTitle(getResources().getQuantityString(R.plurals.multiple_uploads_title, urisList.size(), urisList.size())); setTitle(getResources().getQuantityString(R.plurals.multiple_uploads_title, photosList.size(), photosList.size()));
Intent uploadServiceIntent = new Intent(getApplicationContext(), UploadService.class); Intent uploadServiceIntent = new Intent(getApplicationContext(), UploadService.class);
uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE);
startService(uploadServiceIntent); startService(uploadServiceIntent);
bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE);
} }
} }

View file

@ -18,6 +18,7 @@ import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import org.wikimedia.commons.contributions.Contribution; import org.wikimedia.commons.contributions.Contribution;
import org.wikimedia.commons.media.MediaDetailPagerFragment;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -29,8 +30,7 @@ public class MultipleUploadListFragment extends SherlockFragment {
private EditText baseTitle; private EditText baseTitle;
private Point photoSize; private Point photoSize;
private MediaDetailPagerFragment.MediaDetailProvider detailProvider;
private ArrayList<Contribution> photosList;
private DisplayImageOptions uploadDisplayOptions; private DisplayImageOptions uploadDisplayOptions;
@ -43,18 +43,12 @@ public class MultipleUploadListFragment extends SherlockFragment {
private class PhotoDisplayAdapter extends BaseAdapter { private class PhotoDisplayAdapter extends BaseAdapter {
private ArrayList<Contribution> urisList;
private PhotoDisplayAdapter(ArrayList<Contribution> urisList) {
this.urisList = urisList;
}
public int getCount() { public int getCount() {
return urisList.size(); return detailProvider.getTotalMediaCount();
} }
public Object getItem(int i) { public Object getItem(int i) {
return urisList.get(i); return detailProvider.getMediaAtPosition(i);
} }
public long getItemId(int i) { public long getItemId(int i) {
@ -105,23 +99,31 @@ public class MultipleUploadListFragment extends SherlockFragment {
} }
public void notifyDatasetChanged() {
photosAdapter.notifyDataSetChanged();
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_multiple_uploads_list, container); View view = inflater.inflate(R.layout.fragment_multiple_uploads_list, null);
photosGrid = (GridView)view.findViewById(R.id.multipleShareBackground); photosGrid = (GridView)view.findViewById(R.id.multipleShareBackground);
baseTitle = (EditText)view.findViewById(R.id.multipleBaseTitle); baseTitle = (EditText)view.findViewById(R.id.multipleBaseTitle);
if(savedInstanceState != null) {
setData(savedInstanceState.<Contribution>getParcelableArrayList("photosData")); photosAdapter = new PhotoDisplayAdapter();
} photosGrid.setAdapter(photosAdapter);
photosGrid.setOnItemClickListener((AdapterView.OnItemClickListener)getActivity());
photoSize = calculatePicDimension(detailProvider.getTotalMediaCount());
photosGrid.setColumnWidth(photoSize.x);
baseTitle.addTextChangedListener(new TextWatcher() { baseTitle.addTextChangedListener(new TextWatcher() {
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { public void beforeTextChanged(CharSequence charSequence, int i1, int i2, int i3) {
} }
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { public void onTextChanged(CharSequence charSequence, int i1, int i2, int i3) {
for(Contribution up: photosList) { for(int i = 0; i < detailProvider.getTotalMediaCount(); i++) {
Contribution up = (Contribution) detailProvider.getMediaAtPosition(i);
Boolean isDirty = (Boolean)up.getTag("isDirty"); Boolean isDirty = (Boolean)up.getTag("isDirty");
if(isDirty == null || !isDirty) { if(isDirty == null || !isDirty) {
if(!TextUtils.isEmpty(charSequence)) { if(!TextUtils.isEmpty(charSequence)) {
@ -131,7 +133,7 @@ public class MultipleUploadListFragment extends SherlockFragment {
} }
} }
} }
photosAdapter.notifyDataSetChanged(); detailProvider.notifyDatasetChanged();
} }
@ -148,22 +150,8 @@ public class MultipleUploadListFragment extends SherlockFragment {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
uploadDisplayOptions = Utils.getGenericDisplayOptions().build(); uploadDisplayOptions = Utils.getGenericDisplayOptions().build();
detailProvider = (MediaDetailPagerFragment.MediaDetailProvider)getActivity();
} }
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList("photosData", photosList);
}
public void setData(ArrayList<Contribution> photosList) {
if(this.photosList == null) {
photosAdapter = new PhotoDisplayAdapter(photosList);
photosGrid.setAdapter(photosAdapter);
}
this.photosList = photosList;
photoSize = calculatePicDimension(photosList.size());
photosAdapter.notifyDataSetChanged();
photosGrid.setColumnWidth(photoSize.x);
}
} }

View file

@ -194,6 +194,10 @@ public class ContributionsActivity
return allContributions.getCount(); return allContributions.getCount();
} }
public void notifyDatasetChanged() {
// Do nothing for now
}
public void onBackStackChanged() { public void onBackStackChanged() {
if(mediaDetails != null && mediaDetails.isVisible()) { if(mediaDetails != null && mediaDetails.isVisible()) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);

View file

@ -2,10 +2,13 @@ package org.wikimedia.commons.media;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
@ -22,17 +25,29 @@ import org.wikimedia.commons.Utils;
public class MediaDetailFragment extends SherlockFragment { public class MediaDetailFragment extends SherlockFragment {
private Media media; private boolean editable;
private DisplayImageOptions displayOptions; private DisplayImageOptions displayOptions;
private MediaDetailPagerFragment.MediaDetailProvider detailProvider;
private int index;
public static MediaDetailFragment forMedia(Media media) { public static MediaDetailFragment forMedia(int index) {
return forMedia(index, false);
}
public static MediaDetailFragment forMedia(int index, boolean editable) {
MediaDetailFragment mf = new MediaDetailFragment(); MediaDetailFragment mf = new MediaDetailFragment();
mf.media = media;
Bundle state = new Bundle();
state.putBoolean("editable", editable);
state.putInt("index", index);
mf.setArguments(state);
return mf; return mf;
} }
private ImageView image; private ImageView image;
private TextView title; private EditText title;
private ProgressBar loadingProgress; private ProgressBar loadingProgress;
private ImageView loadingFailed; private ImageView loadingFailed;
@ -40,20 +55,35 @@ public class MediaDetailFragment extends SherlockFragment {
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putParcelable("media", media); outState.putInt("index", index);
outState.putBoolean("editable", editable);
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(media == null) { detailProvider = (MediaDetailPagerFragment.MediaDetailProvider)getActivity();
media = (Media)savedInstanceState.getParcelable("media");
if(savedInstanceState != null) {
editable = savedInstanceState.getBoolean("editable");
index = savedInstanceState.getInt("index");
} else {
editable = getArguments().getBoolean("editable");
index = getArguments().getInt("index");
} }
final Media media = detailProvider.getMediaAtPosition(index);
View view = inflater.inflate(R.layout.fragment_media_detail, container, false); View view = inflater.inflate(R.layout.fragment_media_detail, container, false);
image = (ImageView) view.findViewById(R.id.mediaDetailImage); image = (ImageView) view.findViewById(R.id.mediaDetailImage);
title = (TextView) view.findViewById(R.id.mediaDetailTitle); title = (EditText) view.findViewById(R.id.mediaDetailTitle);
loadingProgress = (ProgressBar) view.findViewById(R.id.mediaDetailImageLoading); loadingProgress = (ProgressBar) view.findViewById(R.id.mediaDetailImageLoading);
loadingFailed = (ImageView) view.findViewById(R.id.mediaDetailImageFailed); loadingFailed = (ImageView) view.findViewById(R.id.mediaDetailImageFailed);
// Enable or disable editing on the title
title.setClickable(editable);
title.setFocusable(editable);
title.setCursorVisible(editable);
title.setFocusableInTouchMode(editable);
String actualUrl = TextUtils.isEmpty(media.getImageUrl()) ? media.getLocalUri().toString() : media.getThumbnailUrl(640); String actualUrl = TextUtils.isEmpty(media.getImageUrl()) ? media.getLocalUri().toString() : media.getThumbnailUrl(640);
ImageLoader.getInstance().displayImage(actualUrl, image, displayOptions, new ImageLoadingListener() { ImageLoader.getInstance().displayImage(actualUrl, image, displayOptions, new ImageLoadingListener() {
public void onLoadingStarted(String s, View view) { public void onLoadingStarted(String s, View view) {
@ -80,6 +110,21 @@ public class MediaDetailFragment extends SherlockFragment {
}); });
title.setText(media.getDisplayTitle()); title.setText(media.getDisplayTitle());
title.addTextChangedListener(new TextWatcher() {
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
detailProvider.getMediaAtPosition(index).setFilename(title.getText().toString());
detailProvider.getMediaAtPosition(index).setTag("isDirty", true);
detailProvider.notifyDatasetChanged();
}
public void afterTextChanged(Editable editable) {
}
});
return view; return view;
} }

View file

@ -21,10 +21,12 @@ import org.wikimedia.commons.R;
public class MediaDetailPagerFragment extends SherlockFragment { public class MediaDetailPagerFragment extends SherlockFragment {
private ViewPager pager; private ViewPager pager;
private ShareActionProvider shareActionProvider; private ShareActionProvider shareActionProvider;
private final Boolean editable;
public interface MediaDetailProvider { public interface MediaDetailProvider {
public Media getMediaAtPosition(int i); public Media getMediaAtPosition(int i);
public int getTotalMediaCount(); public int getTotalMediaCount();
public void notifyDatasetChanged();
} }
private class MediaDetailAdapter extends FragmentStatePagerAdapter { private class MediaDetailAdapter extends FragmentStatePagerAdapter {
@ -34,8 +36,7 @@ public class MediaDetailPagerFragment extends SherlockFragment {
@Override @Override
public Fragment getItem(int i) { public Fragment getItem(int i) {
Media m = ((MediaDetailProvider)getActivity()).getMediaAtPosition(i); return MediaDetailFragment.forMedia(i, editable);
return MediaDetailFragment.forMedia((m));
} }
@Override @Override
@ -44,6 +45,14 @@ public class MediaDetailPagerFragment extends SherlockFragment {
} }
} }
public MediaDetailPagerFragment() {
this(false);
}
public MediaDetailPagerFragment(Boolean editable) {
this.editable = editable;
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_media_detail_pager, container, false); View view = inflater.inflate(R.layout.fragment_media_detail_pager, container, false);
@ -105,6 +114,5 @@ public class MediaDetailPagerFragment extends SherlockFragment {
public void showImage(int i) { public void showImage(int i) {
pager.setCurrentItem(i); pager.setCurrentItem(i);
} }
} }