mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-30 14:23:55 +01:00
Merge "commons" into the project root directory
This commit is contained in:
parent
d42db0612e
commit
b4231bbfdc
324 changed files with 22 additions and 23 deletions
|
|
@ -0,0 +1,57 @@
|
|||
package fr.free.nrw.commons.media;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.util.Log;
|
||||
import org.mediawiki.api.ApiResult;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CategoryImagesLoader extends AsyncTaskLoader<List<Media>>{
|
||||
private final CommonsApplication app;
|
||||
private final String category;
|
||||
|
||||
public CategoryImagesLoader(Context context, String category) {
|
||||
super(context);
|
||||
this.app = (CommonsApplication) context.getApplicationContext();
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
super.onStartLoading();
|
||||
super.forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Media> loadInBackground() {
|
||||
ArrayList<Media> mediaList = new ArrayList<Media>();
|
||||
ApiResult result;
|
||||
try {
|
||||
result = app.getApi().action("query")
|
||||
.param("list", "categorymembers")
|
||||
.param("cmtitle", "Category:" + category)
|
||||
.param("cmprop", "title|timestamp")
|
||||
.param("cmtype", "file")
|
||||
.param("cmsort", "timestamp")
|
||||
.param("cmdir", "descending")
|
||||
.param("cmlimit", 50)
|
||||
.get();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Log.d("Commons", Utils.getStringFromDOM(result.getDocument()));
|
||||
|
||||
List<ApiResult> members = result.getNodes("/api/query/categorymembers/cm");
|
||||
for(ApiResult member : members) {
|
||||
mediaList.add(new Media(member.getString("@title")));
|
||||
}
|
||||
return mediaList;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,367 @@
|
|||
package fr.free.nrw.commons.media;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.database.DataSetObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.volley.toolbox.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.License;
|
||||
import fr.free.nrw.commons.LicenseList;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.MediaDataExtractor;
|
||||
import fr.free.nrw.commons.MediaWikiImageView;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
|
||||
public class MediaDetailFragment extends Fragment {
|
||||
|
||||
private boolean editable;
|
||||
private DisplayImageOptions displayOptions;
|
||||
private fr.free.nrw.commons.media.MediaDetailPagerFragment.MediaDetailProvider detailProvider;
|
||||
private int index;
|
||||
|
||||
public static MediaDetailFragment forMedia(int index) {
|
||||
return forMedia(index, false);
|
||||
}
|
||||
|
||||
public static MediaDetailFragment forMedia(int index, boolean editable) {
|
||||
MediaDetailFragment mf = new MediaDetailFragment();
|
||||
|
||||
Bundle state = new Bundle();
|
||||
state.putBoolean("editable", editable);
|
||||
state.putInt("index", index);
|
||||
state.putInt("listIndex", 0);
|
||||
state.putInt("listTop", 0);
|
||||
|
||||
mf.setArguments(state);
|
||||
|
||||
return mf;
|
||||
}
|
||||
|
||||
private ImageView image;
|
||||
//private EditText title;
|
||||
private ProgressBar loadingProgress;
|
||||
private ImageView loadingFailed;
|
||||
private fr.free.nrw.commons.media.MediaDetailSpacer spacer;
|
||||
private int initialListTop = 0;
|
||||
|
||||
private TextView title;
|
||||
private TextView desc;
|
||||
private TextView license;
|
||||
private LinearLayout categoryContainer;
|
||||
private ScrollView scrollView;
|
||||
private ArrayList<String> categoryNames;
|
||||
private boolean categoriesLoaded = false;
|
||||
private boolean categoriesPresent = false;
|
||||
private ViewTreeObserver.OnGlobalLayoutListener layoutListener; // for layout stuff, only used once!
|
||||
private ViewTreeObserver.OnScrollChangedListener scrollListener;
|
||||
DataSetObserver dataObserver;
|
||||
private AsyncTask<Void,Void,Boolean> detailFetchTask;
|
||||
private LicenseList licenseList;
|
||||
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt("index", index);
|
||||
outState.putBoolean("editable", editable);
|
||||
|
||||
getScrollPosition();
|
||||
outState.putInt("listTop", initialListTop);
|
||||
}
|
||||
|
||||
private void getScrollPosition() {
|
||||
initialListTop = scrollView.getScrollY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
detailProvider = (fr.free.nrw.commons.media.MediaDetailPagerFragment.MediaDetailProvider)getActivity();
|
||||
|
||||
if(savedInstanceState != null) {
|
||||
editable = savedInstanceState.getBoolean("editable");
|
||||
index = savedInstanceState.getInt("index");
|
||||
initialListTop = savedInstanceState.getInt("listTop");
|
||||
} else {
|
||||
editable = getArguments().getBoolean("editable");
|
||||
index = getArguments().getInt("index");
|
||||
initialListTop = 0;
|
||||
}
|
||||
categoryNames = new ArrayList<String>();
|
||||
categoryNames.add(getString(R.string.detail_panel_cats_loading));
|
||||
|
||||
final View view = inflater.inflate(R.layout.fragment_media_detail, container, false);
|
||||
|
||||
image = (ImageView) view.findViewById(R.id.mediaDetailImage);
|
||||
loadingProgress = (ProgressBar) view.findViewById(R.id.mediaDetailImageLoading);
|
||||
loadingFailed = (ImageView) view.findViewById(R.id.mediaDetailImageFailed);
|
||||
scrollView = (ScrollView) view.findViewById(R.id.mediaDetailScrollView);
|
||||
|
||||
// Detail consists of a list view with main pane in header view, plus category list.
|
||||
spacer = (fr.free.nrw.commons.media.MediaDetailSpacer) view.findViewById(R.id.mediaDetailSpacer);
|
||||
title = (TextView) view.findViewById(R.id.mediaDetailTitle);
|
||||
desc = (TextView) view.findViewById(R.id.mediaDetailDesc);
|
||||
license = (TextView) view.findViewById(R.id.mediaDetailLicense);
|
||||
categoryContainer = (LinearLayout) view.findViewById(R.id.mediaDetailCategoryContainer);
|
||||
|
||||
licenseList = new LicenseList(getActivity());
|
||||
|
||||
Media media = detailProvider.getMediaAtPosition(index);
|
||||
if (media == null) {
|
||||
// Ask the detail provider to ping us when we're ready
|
||||
Log.d("Commons", "MediaDetailFragment not yet ready to display details; registering observer");
|
||||
dataObserver = new DataSetObserver() {
|
||||
public void onChanged() {
|
||||
Log.d("Commons", "MediaDetailFragment ready to display delayed details!");
|
||||
detailProvider.unregisterDataSetObserver(dataObserver);
|
||||
dataObserver = null;
|
||||
displayMediaDetails(detailProvider.getMediaAtPosition(index));
|
||||
}
|
||||
};
|
||||
detailProvider.registerDataSetObserver(dataObserver);
|
||||
} else {
|
||||
Log.d("Commons", "MediaDetailFragment ready to display details");
|
||||
displayMediaDetails(media);
|
||||
}
|
||||
|
||||
// Progressively darken the image in the background when we scroll detail pane up
|
||||
scrollListener = new ViewTreeObserver.OnScrollChangedListener() {
|
||||
public void onScrollChanged() {
|
||||
updateTheDarkness();
|
||||
}
|
||||
};
|
||||
view.getViewTreeObserver().addOnScrollChangedListener(scrollListener);
|
||||
|
||||
// Layout layoutListener to size the spacer item relative to the available space.
|
||||
// There may be a .... better way to do this.
|
||||
layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
private int currentHeight = -1;
|
||||
|
||||
public void onGlobalLayout() {
|
||||
int viewHeight = view.getHeight();
|
||||
//int textHeight = title.getLineHeight();
|
||||
int paddingDp = 112;
|
||||
float paddingPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, paddingDp, getResources().getDisplayMetrics());
|
||||
int newHeight = viewHeight - Math.round(paddingPx);
|
||||
|
||||
if (newHeight != currentHeight) {
|
||||
currentHeight = newHeight;
|
||||
ViewGroup.LayoutParams params = spacer.getLayoutParams();
|
||||
params.height = newHeight;
|
||||
spacer.setLayoutParams(params);
|
||||
|
||||
scrollView.scrollTo(0, initialListTop);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
view.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
|
||||
return view;
|
||||
}
|
||||
|
||||
private void displayMediaDetails(final Media media) {
|
||||
String actualUrl = (media.getLocalUri() != null && !TextUtils.isEmpty(media.getLocalUri().toString())) ? media.getLocalUri().toString() : media.getThumbnailUrl(640);
|
||||
if(actualUrl.startsWith("http")) {
|
||||
ImageLoader loader = ((CommonsApplication)getActivity().getApplicationContext()).getImageLoader();
|
||||
MediaWikiImageView mwImage = (MediaWikiImageView)image;
|
||||
mwImage.setLoadingView(loadingProgress); //FIXME: Set this as an attribute
|
||||
mwImage.setMedia(media, loader);
|
||||
|
||||
Log.d("Volley", actualUrl);
|
||||
// FIXME: For transparent images
|
||||
|
||||
// Load image metadata: desc, license, categories
|
||||
// FIXME: keep the spinner going while we load data
|
||||
// FIXME: cache this data
|
||||
detailFetchTask = new AsyncTask<Void, Void, Boolean>() {
|
||||
private MediaDataExtractor extractor;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
extractor = new MediaDataExtractor(media.getFilename(), licenseList);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
try {
|
||||
extractor.fetch();
|
||||
return Boolean.TRUE;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean success) {
|
||||
detailFetchTask = null;
|
||||
|
||||
if (success.booleanValue()) {
|
||||
extractor.fill(media);
|
||||
|
||||
// Fill some fields
|
||||
desc.setText(prettyDescription(media));
|
||||
license.setText(prettyLicense(media));
|
||||
|
||||
categoryNames.removeAll(categoryNames);
|
||||
categoryNames.addAll(media.getCategories());
|
||||
|
||||
categoriesLoaded = true;
|
||||
categoriesPresent = (categoryNames.size() > 0);
|
||||
if (!categoriesPresent) {
|
||||
// Stick in a filler element.
|
||||
categoryNames.add(getString(R.string.detail_panel_cats_none));
|
||||
}
|
||||
rebuildCatList();
|
||||
} else {
|
||||
Log.d("Commons", "Failed to load photo details.");
|
||||
}
|
||||
}
|
||||
};
|
||||
Utils.executeAsyncTask(detailFetchTask);
|
||||
} else {
|
||||
com.nostra13.universalimageloader.core.ImageLoader.getInstance().displayImage(actualUrl, image, displayOptions, new ImageLoadingListener() {
|
||||
public void onLoadingStarted(String s, View view) {
|
||||
loadingProgress.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void onLoadingFailed(String s, View view, FailReason failReason) {
|
||||
loadingProgress.setVisibility(View.GONE);
|
||||
loadingFailed.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void onLoadingComplete(String s, View view, Bitmap bitmap) {
|
||||
loadingProgress.setVisibility(View.GONE);
|
||||
loadingFailed.setVisibility(View.GONE);
|
||||
image.setVisibility(View.VISIBLE);
|
||||
if(bitmap.hasAlpha()) {
|
||||
image.setBackgroundResource(android.R.color.white);
|
||||
}
|
||||
}
|
||||
|
||||
public void onLoadingCancelled(String s, View view) {
|
||||
throw new RuntimeException("Image loading cancelled. But why?");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
title.setText(media.getDisplayTitle());
|
||||
desc.setText(""); // fill in from network...
|
||||
license.setText(""); // fill in from network...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
displayOptions = Utils.getGenericDisplayOptions().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
if (detailFetchTask != null) {
|
||||
detailFetchTask.cancel(true);
|
||||
detailFetchTask = null;
|
||||
}
|
||||
if (layoutListener != null) {
|
||||
getView().getViewTreeObserver().removeGlobalOnLayoutListener(layoutListener); // old Android was on crack. CRACK IS WHACK
|
||||
layoutListener = null;
|
||||
}
|
||||
if (scrollListener != null) {
|
||||
getView().getViewTreeObserver().removeOnScrollChangedListener(scrollListener);
|
||||
scrollListener = null;
|
||||
}
|
||||
if (dataObserver != null) {
|
||||
detailProvider.unregisterDataSetObserver(dataObserver);
|
||||
dataObserver = null;
|
||||
}
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
private void rebuildCatList() {
|
||||
// @fixme add the category items
|
||||
for (String cat : categoryNames) {
|
||||
View catLabel = buildCatLabel(cat);
|
||||
categoryContainer.addView(catLabel);
|
||||
}
|
||||
}
|
||||
|
||||
private View buildCatLabel(String cat) {
|
||||
final String catName = cat;
|
||||
final View item = getLayoutInflater(null).inflate(R.layout.detail_category_item, null, false);
|
||||
final TextView textView = (TextView)item.findViewById(R.id.mediaDetailCategoryItemText);
|
||||
|
||||
textView.setText(cat);
|
||||
if (categoriesLoaded && categoriesPresent) {
|
||||
textView.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
String selectedCategoryTitle = "Category:" + catName;
|
||||
Intent viewIntent = new Intent();
|
||||
viewIntent.setAction(Intent.ACTION_VIEW);
|
||||
viewIntent.setData(Utils.uriForWikiPage(selectedCategoryTitle));
|
||||
startActivity(viewIntent);
|
||||
}
|
||||
});
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
private void updateTheDarkness() {
|
||||
// You must face the darkness alone
|
||||
int scrollY = scrollView.getScrollY();
|
||||
int scrollMax = getView().getHeight();
|
||||
float scrollPercentage = (float)scrollY / (float)scrollMax;
|
||||
final float transparencyMax = 0.75f;
|
||||
if (scrollPercentage > transparencyMax) {
|
||||
scrollPercentage = transparencyMax;
|
||||
}
|
||||
image.setAlpha(1.0f - scrollPercentage);
|
||||
}
|
||||
|
||||
private String prettyDescription(Media media) {
|
||||
// @todo use UI language when multilingual descs are available
|
||||
String desc = media.getDescription("en").trim();
|
||||
if (desc.equals("")) {
|
||||
return getString(R.string.detail_description_empty);
|
||||
} else {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
private String prettyLicense(Media media) {
|
||||
String licenseKey = media.getLicense();
|
||||
Log.d("Commons", "Media license is: " + licenseKey);
|
||||
if (licenseKey == null || licenseKey.equals("")) {
|
||||
return getString(R.string.detail_license_empty);
|
||||
}
|
||||
License licenseObj = licenseList.get(licenseKey);
|
||||
if (licenseObj == null) {
|
||||
return licenseKey;
|
||||
} else {
|
||||
return licenseObj.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
package fr.free.nrw.commons.media;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.DownloadManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.Cursor;
|
||||
import android.database.DataSetObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.EventLog;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||
|
||||
public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPageChangeListener {
|
||||
private ViewPager pager;
|
||||
private Boolean editable;
|
||||
private CommonsApplication app;
|
||||
|
||||
public void onPageScrolled(int i, float v, int i2) {
|
||||
getActivity().supportInvalidateOptionsMenu();
|
||||
}
|
||||
|
||||
public void onPageSelected(int i) {
|
||||
}
|
||||
|
||||
public void onPageScrollStateChanged(int i) {
|
||||
|
||||
}
|
||||
|
||||
public interface MediaDetailProvider {
|
||||
public Media getMediaAtPosition(int i);
|
||||
public int getTotalMediaCount();
|
||||
public void notifyDatasetChanged();
|
||||
public void registerDataSetObserver(DataSetObserver observer);
|
||||
public void unregisterDataSetObserver(DataSetObserver observer);
|
||||
}
|
||||
private class MediaDetailAdapter extends FragmentStatePagerAdapter {
|
||||
|
||||
public MediaDetailAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int i) {
|
||||
if(i == 0) {
|
||||
// See bug https://code.google.com/p/android/issues/detail?id=27526
|
||||
pager.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
getActivity().supportInvalidateOptionsMenu();
|
||||
}
|
||||
}, 5);
|
||||
}
|
||||
return fr.free.nrw.commons.media.MediaDetailFragment.forMedia(i, editable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return ((MediaDetailProvider)getActivity()).getTotalMediaCount();
|
||||
}
|
||||
}
|
||||
|
||||
public MediaDetailPagerFragment() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
@SuppressLint("ValidFragment")
|
||||
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);
|
||||
pager = (ViewPager) view.findViewById(R.id.mediaDetailsPager);
|
||||
pager.setOnPageChangeListener(this);
|
||||
if(savedInstanceState != null) {
|
||||
final int pageNumber = savedInstanceState.getInt("current-page");
|
||||
// Adapter doesn't seem to be loading immediately.
|
||||
// Dear God, please forgive us for our sins
|
||||
view.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
pager.setAdapter(new MediaDetailAdapter(getChildFragmentManager()));
|
||||
pager.setCurrentItem(pageNumber, false);
|
||||
getActivity().supportInvalidateOptionsMenu();
|
||||
}
|
||||
}, 100);
|
||||
} else {
|
||||
pager.setAdapter(new MediaDetailAdapter(getChildFragmentManager()));
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt("current-page", pager.getCurrentItem());
|
||||
outState.putBoolean("editable", editable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if(savedInstanceState != null) {
|
||||
editable = savedInstanceState.getBoolean("editable");
|
||||
}
|
||||
app = (CommonsApplication)getActivity().getApplicationContext();
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
MediaDetailProvider provider = (MediaDetailProvider)getActivity();
|
||||
Media m = provider.getMediaAtPosition(pager.getCurrentItem());
|
||||
switch(item.getItemId()) {
|
||||
case R.id.menu_share_current_image:
|
||||
EventLog.schema(CommonsApplication.EVENT_SHARE_ATTEMPT)
|
||||
.param("username", app.getCurrentAccount().name)
|
||||
.param("filename", m.getFilename())
|
||||
.log();
|
||||
Intent shareIntent = new Intent();
|
||||
shareIntent.setAction(Intent.ACTION_SEND);
|
||||
shareIntent.setType("text/plain");
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, m.getDisplayTitle() + " " + m.getDescriptionUrl());
|
||||
startActivity(shareIntent);
|
||||
return true;
|
||||
case R.id.menu_browser_current_image:
|
||||
Intent viewIntent = new Intent();
|
||||
viewIntent.setAction(Intent.ACTION_VIEW);
|
||||
viewIntent.setData(Uri.parse(m.getDescriptionUrl()));
|
||||
startActivity(viewIntent);
|
||||
return true;
|
||||
case R.id.menu_download_current_image:
|
||||
downloadMedia(m);
|
||||
return true;
|
||||
case R.id.menu_retry_current_image:
|
||||
// Is this... sane? :)
|
||||
((ContributionsActivity)getActivity()).retryUpload(pager.getCurrentItem());
|
||||
getActivity().getSupportFragmentManager().popBackStack();
|
||||
return true;
|
||||
case R.id.menu_cancel_current_image:
|
||||
// todo: delete image
|
||||
((ContributionsActivity)getActivity()).deleteUpload(pager.getCurrentItem());
|
||||
getActivity().getSupportFragmentManager().popBackStack();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the media file downloading to the local SD card/storage.
|
||||
* The file can then be opened in Gallery or other apps.
|
||||
*
|
||||
* @param m
|
||||
*/
|
||||
private void downloadMedia(Media m) {
|
||||
String imageUrl = m.getImageUrl(),
|
||||
fileName = m.getFilename();
|
||||
// Strip 'File:' from beginning of filename, we really shouldn't store it
|
||||
fileName = fileName.replaceFirst("^File:", "");
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
// Gingerbread DownloadManager has no HTTPS support...
|
||||
// Download file over HTTP, there'll be no credentials
|
||||
// sent so it should be safe-ish.
|
||||
imageUrl = imageUrl.replaceFirst("^https://", "http://");
|
||||
}
|
||||
Uri imageUri = Uri.parse(imageUrl);
|
||||
|
||||
DownloadManager.Request req = new DownloadManager.Request(imageUri);
|
||||
req.setDescription(getString(R.string.app_name));
|
||||
req.setTitle(m.getDisplayTitle());
|
||||
req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
// Modern Android updates the gallery automatically. Yay!
|
||||
req.allowScanningByMediaScanner();
|
||||
|
||||
// On HC/ICS/JB we can leave the download notification up when complete.
|
||||
// This allows folks to open the file directly in gallery viewer.
|
||||
// But for some reason it fails on Honeycomb (Google TV). Sigh.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||
}
|
||||
}
|
||||
|
||||
final DownloadManager manager = (DownloadManager)getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
final long downloadId = manager.enqueue(req);
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
|
||||
// For Gingerbread compatibility...
|
||||
BroadcastReceiver onComplete = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// Check if the download has completed...
|
||||
Cursor c = manager.query(new DownloadManager.Query()
|
||||
.setFilterById(downloadId)
|
||||
.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL | DownloadManager.STATUS_FAILED)
|
||||
);
|
||||
if (c.moveToFirst()) {
|
||||
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
|
||||
Log.d("Commons", "Download completed with status " + status);
|
||||
if (status == DownloadManager.STATUS_SUCCESSFUL) {
|
||||
// Force Gallery to index the new file
|
||||
Uri mediaUri = Uri.parse("file://" + Environment.getExternalStorageDirectory());
|
||||
getActivity().sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, mediaUri));
|
||||
|
||||
// todo: show a persistent notification?
|
||||
}
|
||||
} else {
|
||||
Log.d("Commons", "Couldn't get download status for some reason");
|
||||
}
|
||||
getActivity().unregisterReceiver(this);
|
||||
}
|
||||
};
|
||||
getActivity().registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
if(!editable) { // Disable menu options for editable views
|
||||
menu.clear(); // see http://stackoverflow.com/a/8495697/17865
|
||||
inflater.inflate(R.menu.fragment_image_detail, menu);
|
||||
if(pager != null) {
|
||||
MediaDetailProvider provider = (MediaDetailProvider)getActivity();
|
||||
Media m = provider.getMediaAtPosition(pager.getCurrentItem());
|
||||
if(m != null) {
|
||||
// Enable default set of actions, then re-enable different set of actions only if it is a failed contrib
|
||||
menu.findItem(R.id.menu_retry_current_image).setEnabled(false).setVisible(false);
|
||||
menu.findItem(R.id.menu_cancel_current_image).setEnabled(false).setVisible(false);
|
||||
menu.findItem(R.id.menu_browser_current_image).setEnabled(true).setVisible(true);
|
||||
menu.findItem(R.id.menu_share_current_image).setEnabled(true).setVisible(true);
|
||||
menu.findItem(R.id.menu_download_current_image).setEnabled(true).setVisible(true);
|
||||
|
||||
if(m instanceof Contribution) {
|
||||
Contribution c = (Contribution)m;
|
||||
switch(c.getState()) {
|
||||
case Contribution.STATE_FAILED:
|
||||
menu.findItem(R.id.menu_retry_current_image).setEnabled(true).setVisible(true);
|
||||
menu.findItem(R.id.menu_cancel_current_image).setEnabled(true).setVisible(true);
|
||||
menu.findItem(R.id.menu_browser_current_image).setEnabled(false).setVisible(false);
|
||||
menu.findItem(R.id.menu_share_current_image).setEnabled(false).setVisible(false);
|
||||
menu.findItem(R.id.menu_download_current_image).setEnabled(false).setVisible(false);
|
||||
break;
|
||||
case Contribution.STATE_IN_PROGRESS:
|
||||
case Contribution.STATE_QUEUED:
|
||||
menu.findItem(R.id.menu_retry_current_image).setEnabled(false).setVisible(false);
|
||||
menu.findItem(R.id.menu_cancel_current_image).setEnabled(false).setVisible(false);
|
||||
menu.findItem(R.id.menu_browser_current_image).setEnabled(false).setVisible(false);
|
||||
menu.findItem(R.id.menu_share_current_image).setEnabled(false).setVisible(false);
|
||||
menu.findItem(R.id.menu_download_current_image).setEnabled(false).setVisible(false);
|
||||
break;
|
||||
case Contribution.STATE_COMPLETED:
|
||||
// Default set of menu items works fine. Treat same as regular media object
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showImage(int i) {
|
||||
pager.setCurrentItem(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package fr.free.nrw.commons.media;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
public class MediaDetailSpacer extends View {
|
||||
public MediaDetailSpacer(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public MediaDetailSpacer(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public MediaDetailSpacer(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue