Skip to content

[GSoC] Added option to set a new avatar #3892

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,34 @@
import com.google.android.material.snackbar.Snackbar;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.bookmarks.Bookmark;
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider;
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
import fr.free.nrw.commons.utils.DownloadUtils;
import fr.free.nrw.commons.utils.ImageUtils;
import fr.free.nrw.commons.utils.NetworkUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import io.reactivex.disposables.CompositeDisposable;
import java.util.Objects;
import javax.inject.Inject;
import timber.log.Timber;

public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener {

@Inject BookmarkPicturesDao bookmarkDao;

@Inject
OkHttpJsonApiClient okHttpJsonApiClient;

@Inject
SessionManager sessionManager;

private static CompositeDisposable compositeDisposable = new CompositeDisposable();

@BindView(R.id.mediaDetailsPager) ViewPager pager;
private Boolean editable;
private boolean isFeaturedImage;
Expand Down Expand Up @@ -159,6 +171,10 @@ public boolean onOptionsItemSelected(MenuItem item) {
// Set wallpaper
setWallpaper(m);
return true;
case R.id.menu_set_as_avatar:
// Set avatar
setAvatar(m);
return true;
default:
return super.onOptionsItemSelected(item);
}
Expand All @@ -177,6 +193,20 @@ private void setWallpaper(Media media) {
ImageUtils.setWallpaperFromImageUrl(getActivity(), Uri.parse(media.getImageUrl()));
}

/**
* Set the media as user's leaderboard avatar
* @param media
*/
private void setAvatar(Media media) {
if (media.getImageUrl() == null || media.getImageUrl().isEmpty()) {
Timber.d("Media URL not present");
return;
}
ImageUtils.setAvatarFromImageUrl(getActivity(), media.getImageUrl(),
Objects.requireNonNull(sessionManager.getCurrentAccount()).name,
okHttpJsonApiClient, compositeDisposable);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (!editable) { // Disable menu options for editable views
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import fr.free.nrw.commons.profile.achievements.FeaturedImages;
import fr.free.nrw.commons.profile.achievements.FeedbackResponse;
import fr.free.nrw.commons.profile.leaderboard.LeaderboardResponse;
import fr.free.nrw.commons.profile.leaderboard.UpdateAvatarResponse;
import fr.free.nrw.commons.upload.FileUtils;
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
import fr.free.nrw.commons.utils.ConfigUtils;
Expand Down Expand Up @@ -103,6 +104,38 @@ public Observable<LeaderboardResponse> getLeaderboard(String userName, String du
});
}

@NonNull
public Single<UpdateAvatarResponse> setAvatar(String username, String avatar) {
final String urlTemplate = wikiMediaTestToolforgeUrl
+ "/update_avatar.py";
return Single.fromCallable(() -> {
String url = String.format(Locale.ENGLISH,
urlTemplate,
username,
avatar);
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
urlBuilder.addQueryParameter("user", username);
urlBuilder.addQueryParameter("avatar", avatar);
Timber.i("Url %s", urlBuilder.toString());
Request request = new Request.Builder()
.url(urlBuilder.toString())
.build();
Response response = okHttpClient.newCall(request).execute();
if (response != null && response.body() != null && response.isSuccessful()) {
String json = response.body().string();
if (json == null) {
return null;
}
try {
return gson.fromJson(json, UpdateAvatarResponse.class);
} catch (Exception e) {
return new UpdateAvatarResponse();
}
}
return null;
});
}

@NonNull
public Single<Integer> getUploadCount(String userName) {
HttpUrl.Builder urlBuilder = wikiMediaToolforgeUrl.newBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ public class LeaderboardConstants {

public static final int START_OFFSET = 0;

public static final String AVATAR_SOURCE_URL = "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0a/%s/1024px-%s.png";

public final static String LOADING = "Loading";

public final static String LOADED = "Loaded";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package fr.free.nrw.commons.profile.leaderboard;

import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.AVATAR_SOURCE_URL;

import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
Expand Down Expand Up @@ -72,9 +70,7 @@ public void onBindViewHolder(@NonNull LeaderboardListAdapter.ListViewHolder hold

rank.setText(getItem(position).getRank().toString());

avatar.setImageURI(
Uri.parse(String.format(AVATAR_SOURCE_URL, getItem(position).getAvatar(),
getItem(position).getAvatar())));
avatar.setImageURI(Uri.parse(getItem(position).getAvatar()));
username.setText(getItem(position).getUsername());
count.setText(getItem(position).getCategoryCount().toString());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package fr.free.nrw.commons.profile.leaderboard;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class UpdateAvatarResponse {

@SerializedName("status")
@Expose
private String status;

@SerializedName("message")
@Expose
private String message;

@SerializedName("user")
@Expose
private String user;

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public String getUser() {
return user;
}

public void setUser(String user) {
this.user = user;
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package fr.free.nrw.commons.profile.leaderboard;

import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.AVATAR_SOURCE_URL;

import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
Expand Down Expand Up @@ -62,8 +60,7 @@ public void onBindViewHolder(@NonNull UserDetailAdapter.DataViewHolder holder, i
leaderboardResponse.getRank()));

avatar.setImageURI(
Uri.parse(String.format(AVATAR_SOURCE_URL, leaderboardResponse.getAvatar(),
leaderboardResponse.getAvatar())));
Uri.parse(leaderboardResponse.getAvatar()));
username.setText(leaderboardResponse.getUsername());
count.setText(String.format("%s %d",
holder.getContext().getResources().getString(R.string.count_prefix),
Expand Down
76 changes: 64 additions & 12 deletions app/src/main/java/fr/free/nrw/commons/utils/ImageUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;

import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.exifinterface.media.ExifInterface;

import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
Expand All @@ -21,13 +19,15 @@
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import fr.free.nrw.commons.R;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import fr.free.nrw.commons.R;
import fr.free.nrw.commons.location.LatLng;
import timber.log.Timber;

/**
Expand Down Expand Up @@ -69,7 +69,9 @@ public class ImageUtils {
public static final int FILE_NAME_EXISTS = -4;
static final int NO_CATEGORY_SELECTED = -5;

private static ProgressDialog progressDialog;
private static ProgressDialog progressDialogWallpaper;

private static ProgressDialog progressDialogAvatar;

@IntDef(
flag = true,
Expand Down Expand Up @@ -223,28 +225,78 @@ public void onFailureImpl(DataSource dataSource) {
}, CallerThreadExecutor.getInstance());
}

/**
* Calls the set avatar api to set the image url as user's avatar
* @param context
* @param url
* @param username
* @param okHttpJsonApiClient
* @param compositeDisposable
*/
public static void setAvatarFromImageUrl(Context context, String url, String username,
OkHttpJsonApiClient okHttpJsonApiClient, CompositeDisposable compositeDisposable) {
showSettingAvatarProgressBar(context);

try {
compositeDisposable.add(okHttpJsonApiClient
.setAvatar(username, url)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
response -> {
if (response != null && response.getStatus().equals("200")) {
ViewUtil.showLongToast(context, context.getString(R.string.avatar_set_successfully));
if (progressDialogAvatar != null && progressDialogAvatar.isShowing()) {
progressDialogAvatar.dismiss();
}
}
},
t -> {
Timber.e(t, "Setting Avatar Failed");
ViewUtil.showLongToast(context, context.getString(R.string.avatar_set_unsuccessfully));
if (progressDialogAvatar != null) {
progressDialogAvatar.cancel();
}
}
));
}
catch (Exception e){
Timber.d(e+"success");
ViewUtil.showLongToast(context, context.getString(R.string.avatar_set_unsuccessfully));
if (progressDialogAvatar != null) {
progressDialogAvatar.cancel();
}
}

}

private static void setWallpaper(Context context, Bitmap bitmap) {
WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
try {
wallpaperManager.setBitmap(bitmap);
ViewUtil.showLongToast(context, context.getString(R.string.wallpaper_set_successfully));
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
if (progressDialogWallpaper != null && progressDialogWallpaper.isShowing()) {
progressDialogWallpaper.dismiss();
}
} catch (IOException e) {
Timber.e(e, "Error setting wallpaper");
ViewUtil.showLongToast(context, context.getString(R.string.wallpaper_set_unsuccessfully));
if (progressDialog != null) {
progressDialog.cancel();
if (progressDialogWallpaper != null) {
progressDialogWallpaper.cancel();
}
}
}

private static void showSettingWallpaperProgressBar(Context context) {
progressDialog = ProgressDialog.show(context, context.getString(R.string.setting_wallpaper_dialog_title),
progressDialogWallpaper = ProgressDialog.show(context, context.getString(R.string.setting_wallpaper_dialog_title),
context.getString(R.string.setting_wallpaper_dialog_message), true);
}

private static void showSettingAvatarProgressBar(Context context) {
progressDialogAvatar = ProgressDialog.show(context, context.getString(R.string.setting_avatar_dialog_title),
context.getString(R.string.setting_avatar_dialog_message), true);
}

/**
* Result variable is a result of an or operation of all possible problems. Ie. if result
* is 0001 means IMAGE_DARK
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/menu/fragment_image_detail.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,9 @@
android:id="@+id/menu_set_as_wallpaper"
android:title="@string/menu_set_wallpaper"
app:showAsAction="never" />
<item
android:id="@+id/menu_set_as_avatar"
android:title="@string/menu_set_avatar"
app:showAsAction="never" />

</menu>
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -656,4 +656,9 @@ Upload your first media by tapping on the add button.</string>
<string name="leaderboard_column_rank">Rank</string>
<string name="leaderboard_column_user">User</string>
<string name="leaderboard_column_count">Count</string>
<string name="setting_avatar_dialog_title">Set as Leaderboard Avatar</string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowercase: Set as leaderboard avatar

<string name="setting_avatar_dialog_message">Setting as Avatar, please wait</string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowercase: avatar

<string name="avatar_set_successfully">Avatar Set Successfully</string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowercase and no need to say "successfully": Avatar set

<string name="avatar_set_unsuccessfully">Error setting new avatar, please try again</string>
<string name="menu_set_avatar">Set as avatar</string>
</resources>