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"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/uploadsFragmentContainer"
android:orientation="vertical"
android:layout_width="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>

View file

@ -37,13 +37,13 @@
android:padding="8dp"
>
<TextView
<EditText
android:id="@+id/mediaDetailTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
style="?android:textAppearanceMedium"
android:typeface="serif" />
/>
<!-- <TextView
android:id="@+id/mediaDetailDescription"
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 String getDisplayTitle() {
if(filename == null) {
return "";
}
// FIXME: Gross hack bercause my regex skills suck maybe or I am too lazy who knows
String title = filename.replaceFirst("^File:", "");
Matcher matcher = displayTitlePattern.matcher(title);
@ -66,6 +69,10 @@ public class Media implements Parcelable {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getDescription() {
return description;
}

View file

@ -12,6 +12,7 @@ import android.os.IBinder;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.*;
import com.actionbarsherlock.view.Menu;
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.WikiAccountAuthenticator;
import org.wikimedia.commons.contributions.Contribution;
import org.wikimedia.commons.media.MediaDetailPagerFragment;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
public class MultipleShareActivity extends AuthenticatedActivity {
public class MultipleShareActivity
extends AuthenticatedActivity
implements MediaDetailPagerFragment.MediaDetailProvider,
AdapterView.OnItemClickListener {
private CommonsApplication app;
private ArrayList<Contribution> photosList = new ArrayList<Contribution>();
private ArrayList<Contribution> photosList = null;
private MultipleUploadListFragment uploadsList;
private MediaDetailPagerFragment mediaDetails;
public MultipleShareActivity() {
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> {
ProgressDialog dialog;
@ -126,8 +156,11 @@ public class MultipleShareActivity extends AuthenticatedActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_multiple_uploads);
uploadsList = (MultipleUploadListFragment)getSupportFragmentManager().findFragmentById(R.id.uploadsListFragment);
app = (CommonsApplication)this.getApplicationContext();
if(savedInstanceState != null) {
photosList = savedInstanceState.getParcelableArrayList("uploadsList");
}
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
protected void onAuthCookieAcquired(String authCookie) {
app.getApi().setAuthCookie(authCookie);
Intent intent = getIntent();
if(intent.getAction() == Intent.ACTION_SEND_MULTIPLE) {
ArrayList<Uri> urisList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
for(int i=0; i < urisList.size(); i++) {
Contribution up = new Contribution();
Uri uri = urisList.get(i);
up.setLocalUri(uri);
up.setTag("mimeType", intent.getType());
up.setTag("sequence", i);
photosList.add(up);
if(photosList == null) {
photosList = new ArrayList<Contribution>();
ArrayList<Uri> urisList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
for(int i=0; i < urisList.size(); i++) {
Contribution up = new Contribution();
Uri uri = urisList.get(i);
up.setLocalUri(uri);
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);
uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE);
startService(uploadServiceIntent);
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.display.FadeInBitmapDisplayer;
import org.wikimedia.commons.contributions.Contribution;
import org.wikimedia.commons.media.MediaDetailPagerFragment;
import java.util.ArrayList;
import java.util.List;
@ -29,8 +30,7 @@ public class MultipleUploadListFragment extends SherlockFragment {
private EditText baseTitle;
private Point photoSize;
private ArrayList<Contribution> photosList;
private MediaDetailPagerFragment.MediaDetailProvider detailProvider;
private DisplayImageOptions uploadDisplayOptions;
@ -43,18 +43,12 @@ public class MultipleUploadListFragment extends SherlockFragment {
private class PhotoDisplayAdapter extends BaseAdapter {
private ArrayList<Contribution> urisList;
private PhotoDisplayAdapter(ArrayList<Contribution> urisList) {
this.urisList = urisList;
}
public int getCount() {
return urisList.size();
return detailProvider.getTotalMediaCount();
}
public Object getItem(int i) {
return urisList.get(i);
return detailProvider.getMediaAtPosition(i);
}
public long getItemId(int i) {
@ -105,23 +99,31 @@ public class MultipleUploadListFragment extends SherlockFragment {
}
public void notifyDatasetChanged() {
photosAdapter.notifyDataSetChanged();
}
@Override
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);
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() {
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) {
for(Contribution up: photosList) {
public void onTextChanged(CharSequence charSequence, int i1, int i2, int i3) {
for(int i = 0; i < detailProvider.getTotalMediaCount(); i++) {
Contribution up = (Contribution) detailProvider.getMediaAtPosition(i);
Boolean isDirty = (Boolean)up.getTag("isDirty");
if(isDirty == null || !isDirty) {
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);
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();
}
public void notifyDatasetChanged() {
// Do nothing for now
}
public void onBackStackChanged() {
if(mediaDetails != null && mediaDetails.isVisible()) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

View file

@ -2,10 +2,13 @@ package org.wikimedia.commons.media;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
@ -22,17 +25,29 @@ import org.wikimedia.commons.Utils;
public class MediaDetailFragment extends SherlockFragment {
private Media media;
private boolean editable;
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();
mf.media = media;
Bundle state = new Bundle();
state.putBoolean("editable", editable);
state.putInt("index", index);
mf.setArguments(state);
return mf;
}
private ImageView image;
private TextView title;
private EditText title;
private ProgressBar loadingProgress;
private ImageView loadingFailed;
@ -40,20 +55,35 @@ public class MediaDetailFragment extends SherlockFragment {
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("media", media);
outState.putInt("index", index);
outState.putBoolean("editable", editable);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(media == null) {
media = (Media)savedInstanceState.getParcelable("media");
detailProvider = (MediaDetailPagerFragment.MediaDetailProvider)getActivity();
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);
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);
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);
ImageLoader.getInstance().displayImage(actualUrl, image, displayOptions, new ImageLoadingListener() {
public void onLoadingStarted(String s, View view) {
@ -80,6 +110,21 @@ public class MediaDetailFragment extends SherlockFragment {
});
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;
}

View file

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