mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-29 22:03:55 +01:00
Merge pull request #1089 from maskaravivek/notifications
Integrated Notifications API
This commit is contained in:
commit
3697eb5b2d
26 changed files with 669 additions and 8 deletions
|
|
@ -8,6 +8,7 @@ import fr.free.nrw.commons.auth.LoginActivity;
|
|||
import fr.free.nrw.commons.auth.SignupActivity;
|
||||
import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||
import fr.free.nrw.commons.nearby.NearbyActivity;
|
||||
import fr.free.nrw.commons.notification.NotificationActivity;
|
||||
import fr.free.nrw.commons.settings.SettingsActivity;
|
||||
import fr.free.nrw.commons.upload.MultipleShareActivity;
|
||||
import fr.free.nrw.commons.upload.ShareActivity;
|
||||
|
|
@ -43,4 +44,6 @@ public abstract class ActivityBuilderModule {
|
|||
@ContributesAndroidInjector
|
||||
abstract NearbyActivity bindNearbyActivity();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract NotificationActivity bindNotificationActivity();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ import android.support.v4.util.LruCache;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.auth.AccountUtil;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.caching.CacheController;
|
||||
|
|
@ -31,7 +31,9 @@ import static fr.free.nrw.commons.modifications.ModificationsContentProvider.MOD
|
|||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class CommonsApplicationModule {
|
||||
public static final String CATEGORY_AUTHORITY = "fr.free.nrw.commons.categories.contentprovider";
|
||||
public static final long OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024;
|
||||
|
||||
private CommonsApplication application;
|
||||
private Context applicationContext;
|
||||
|
||||
public CommonsApplicationModule(Context applicationContext) {
|
||||
|
|
@ -100,8 +102,8 @@ public class CommonsApplicationModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
public MediaWikiApi provideMediaWikiApi() {
|
||||
return new ApacheHttpClientMediaWikiApi(BuildConfig.WIKIMEDIA_API_HOST);
|
||||
public MediaWikiApi provideMediaWikiApi(Context context) {
|
||||
return new ApacheHttpClientMediaWikiApi(context, BuildConfig.WIKIMEDIA_API_HOST);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
@ -133,4 +135,4 @@ public class CommonsApplicationModule {
|
|||
public LruCache<String, String> provideLruCache() {
|
||||
return new LruCache<>(1024);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package fr.free.nrw.commons.mwapi;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
|
@ -21,6 +22,8 @@ import org.apache.http.params.CoreProtocolPNames;
|
|||
import org.apache.http.util.EntityUtils;
|
||||
import org.mediawiki.api.ApiResult;
|
||||
import org.mediawiki.api.MWApi;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
|
@ -36,11 +39,17 @@ import java.util.concurrent.Callable;
|
|||
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.PageTitle;
|
||||
import fr.free.nrw.commons.notification.Notification;
|
||||
import in.yuvi.http.fluent.Http;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static fr.free.nrw.commons.notification.NotificationType.UNKNOWN;
|
||||
import static fr.free.nrw.commons.notification.NotificationUtils.getNotificationFromApiResult;
|
||||
import static fr.free.nrw.commons.notification.NotificationUtils.getNotificationType;
|
||||
import static fr.free.nrw.commons.notification.NotificationUtils.isCommonsNotification;
|
||||
|
||||
/**
|
||||
* @author Addshore
|
||||
*/
|
||||
|
|
@ -50,8 +59,10 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
|||
private static final String THUMB_SIZE = "640";
|
||||
private AbstractHttpClient httpClient;
|
||||
private MWApi api;
|
||||
private Context context;
|
||||
|
||||
public ApacheHttpClientMediaWikiApi(String apiURL) {
|
||||
public ApacheHttpClientMediaWikiApi(Context context, String apiURL) {
|
||||
this.context = context;
|
||||
BasicHttpParams params = new BasicHttpParams();
|
||||
SchemeRegistry schemeRegistry = new SchemeRegistry();
|
||||
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
|
||||
|
|
@ -353,6 +364,42 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
|||
.getString("/api/query/pages/page/revisions/rev");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public List<Notification> getNotifications() {
|
||||
ApiResult notificationNode = null;
|
||||
try {
|
||||
notificationNode = api.action("query")
|
||||
.param("notprop", "list")
|
||||
.param("format", "xml")
|
||||
.param("meta", "notifications")
|
||||
.param("notfilter", "!read")
|
||||
.get()
|
||||
.getNode("/api/query/notifications/list");
|
||||
} catch (IOException e) {
|
||||
Timber.e("Failed to obtain searchCategories", e);
|
||||
}
|
||||
|
||||
if (notificationNode == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<Notification> notifications = new ArrayList<>();
|
||||
|
||||
NodeList childNodes = notificationNode.getDocument().getChildNodes();
|
||||
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (isCommonsNotification(node)
|
||||
&& !getNotificationType(node).equals(UNKNOWN)) {
|
||||
notifications.add(getNotificationFromApiResult(context, node));
|
||||
}
|
||||
}
|
||||
|
||||
return notifications;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean existingFile(String fileSha1) throws IOException {
|
||||
return api.action("query")
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ import android.support.annotation.Nullable;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import fr.free.nrw.commons.notification.Notification;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
|
||||
|
|
@ -43,6 +45,9 @@ public interface MediaWikiApi {
|
|||
@NonNull
|
||||
Observable<String> allCategories(String filter, int searchCatsLimit);
|
||||
|
||||
@NonNull
|
||||
List<Notification> getNotifications() throws IOException;
|
||||
|
||||
@NonNull
|
||||
Observable<String> searchTitles(String title, int searchCatsLimit);
|
||||
|
||||
|
|
@ -51,6 +56,8 @@ public interface MediaWikiApi {
|
|||
|
||||
boolean existingFile(String fileSha1) throws IOException;
|
||||
|
||||
|
||||
|
||||
@NonNull
|
||||
LogEventResult logEvents(String user, String lastModified, String queryContinue, int limit) throws IOException;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
public class MarkReadResponse {
|
||||
@SuppressWarnings("unused") @Nullable
|
||||
private String result;
|
||||
|
||||
public String result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class QueryMarkReadResponse {
|
||||
@SuppressWarnings("unused") @Nullable private MarkReadResponse echomarkread;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
/**
|
||||
* Created by root on 18.12.2017.
|
||||
*/
|
||||
|
||||
public class Notification {
|
||||
public NotificationType notificationType;
|
||||
public String notificationText;
|
||||
public String date;
|
||||
public String description;
|
||||
public String link;
|
||||
|
||||
public Notification(NotificationType notificationType, String notificationText, String date, String description, String link) {
|
||||
this.notificationType = notificationType;
|
||||
this.notificationText = notificationText;
|
||||
this.date = date;
|
||||
this.description = description;
|
||||
this.link = link;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Created by root on 18.12.2017.
|
||||
*/
|
||||
|
||||
public class NotificationActivity extends NavigationBaseActivity {
|
||||
NotificationAdapterFactory notificationAdapterFactory;
|
||||
|
||||
@BindView(R.id.listView) RecyclerView recyclerView;
|
||||
|
||||
@Inject NotificationController controller;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_notification);
|
||||
ButterKnife.bind(this);
|
||||
initListView();
|
||||
initDrawer();
|
||||
}
|
||||
|
||||
private void initListView() {
|
||||
recyclerView = findViewById(R.id.listView);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
addNotifications();
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void addNotifications() {
|
||||
Timber.d("Add notifications");
|
||||
|
||||
Observable.fromCallable(() -> controller.getNotifications())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(notificationList -> {
|
||||
Timber.d("Number of notifications is %d", notificationList.size());
|
||||
setAdapter(notificationList);
|
||||
}, throwable -> {
|
||||
Timber.e(throwable, "Error occurred while loading notifications");
|
||||
});
|
||||
}
|
||||
|
||||
private void handleUrl(String url) {
|
||||
if (url == null || url.equals("")) {
|
||||
return;
|
||||
}
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
||||
}
|
||||
|
||||
private void setAdapter(List<Notification> notificationList) {
|
||||
notificationAdapterFactory = new NotificationAdapterFactory(notification -> {
|
||||
Timber.d("Notification clicked %s", notification.link);
|
||||
handleUrl(notification.link);
|
||||
});
|
||||
RVRendererAdapter<Notification> adapter = notificationAdapterFactory.create(notificationList);
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
public static void startYourself(Context context) {
|
||||
Intent intent = new Intent(context, NotificationActivity.class);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.pedrogomez.renderers.ListAdapteeCollection;
|
||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
||||
import com.pedrogomez.renderers.RendererBuilder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by root on 19.12.2017.
|
||||
*/
|
||||
|
||||
class NotificationAdapterFactory {
|
||||
private NotificationRenderer.NotificationClicked listener;
|
||||
|
||||
NotificationAdapterFactory(@NonNull NotificationRenderer.NotificationClicked listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public RVRendererAdapter<Notification> create(List<Notification> notifications) {
|
||||
RendererBuilder<Notification> builder = new RendererBuilder<Notification>()
|
||||
.bind(Notification.class, new NotificationRenderer(listener));
|
||||
ListAdapteeCollection<Notification> collection = new ListAdapteeCollection<>(
|
||||
notifications != null ? notifications : Collections.<Notification>emptyList());
|
||||
return new RVRendererAdapter<>(builder, collection);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
|
||||
/**
|
||||
* Created by root on 19.12.2017.
|
||||
*/
|
||||
@Singleton
|
||||
public class NotificationController {
|
||||
|
||||
private MediaWikiApi mediaWikiApi;
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Inject
|
||||
public NotificationController(MediaWikiApi mediaWikiApi, SessionManager sessionManager) {
|
||||
this.mediaWikiApi = mediaWikiApi;
|
||||
this.sessionManager = sessionManager;
|
||||
}
|
||||
|
||||
public List<Notification> getNotifications() throws IOException {
|
||||
if (mediaWikiApi.validateLogin()) {
|
||||
return mediaWikiApi.getNotifications();
|
||||
} else {
|
||||
Boolean authTokenValidated = sessionManager.revalidateAuthToken();
|
||||
if (authTokenValidated != null && authTokenValidated) {
|
||||
return mediaWikiApi.getNotifications();
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.pedrogomez.renderers.Renderer;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.utils.DateUtils;
|
||||
|
||||
/**
|
||||
* Created by root on 19.12.2017.
|
||||
*/
|
||||
|
||||
public class NotificationRenderer extends Renderer<Notification> {
|
||||
@BindView(R.id.title) TextView title;
|
||||
@BindView(R.id.description) TextView description;
|
||||
@BindView(R.id.time) TextView time;
|
||||
@BindView(R.id.icon) ImageView icon;
|
||||
private NotificationClicked listener;
|
||||
|
||||
|
||||
NotificationRenderer(NotificationClicked listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpView(View view) { }
|
||||
|
||||
@Override
|
||||
protected void hookListeners(View rootView) {
|
||||
rootView.setOnClickListener(v -> listener.notificationClicked(getContent()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View inflate(LayoutInflater layoutInflater, ViewGroup viewGroup) {
|
||||
View inflatedView = layoutInflater.inflate(R.layout.item_notification, viewGroup, false);
|
||||
ButterKnife.bind(this, inflatedView);
|
||||
return inflatedView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
Notification notification = getContent();
|
||||
title.setText(notification.notificationText);
|
||||
time.setText(notification.date);
|
||||
description.setText(notification.description);
|
||||
switch (notification.notificationType) {
|
||||
case THANK_YOU_EDIT:
|
||||
icon.setImageResource(R.drawable.ic_edit_black_24dp);
|
||||
break;
|
||||
default:
|
||||
icon.setImageResource(R.drawable.round_icon_unknown);
|
||||
}
|
||||
}
|
||||
|
||||
public interface NotificationClicked{
|
||||
void notificationClicked(Notification notification);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
public enum NotificationType {
|
||||
THANK_YOU_EDIT("thank-you-edit"),
|
||||
EDIT_USER_TALK("edit-user-talk"),
|
||||
MENTION("mention"),
|
||||
WELCOME("welcome"),
|
||||
UNKNOWN("unknown");
|
||||
private String type;
|
||||
|
||||
NotificationType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static NotificationType handledValueOf(String name) {
|
||||
for (NotificationType e : values()) {
|
||||
if (e.getType().equals(name)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
public class NotificationUtils {
|
||||
|
||||
private static final String COMMONS_WIKI = "commonswiki";
|
||||
|
||||
public static boolean isCommonsNotification(Node document) {
|
||||
if (document == null || !document.hasAttributes()) {
|
||||
return false;
|
||||
}
|
||||
Element element = (Element) document;
|
||||
return COMMONS_WIKI.equals(element.getAttribute("wiki"));
|
||||
}
|
||||
|
||||
public static NotificationType getNotificationType(Node document) {
|
||||
Element element = (Element) document;
|
||||
String type = element.getAttribute("type");
|
||||
return NotificationType.handledValueOf(type);
|
||||
}
|
||||
|
||||
public static Notification getNotificationFromApiResult(Context context, Node document) {
|
||||
NotificationType type = getNotificationType(document);
|
||||
|
||||
String notificationText = "";
|
||||
String link = getNotificationLink(document);
|
||||
String description = getNotificationDescription(document);
|
||||
switch (type) {
|
||||
case THANK_YOU_EDIT:
|
||||
notificationText = context.getString(R.string.notifications_thank_you_edit);
|
||||
break;
|
||||
case EDIT_USER_TALK:
|
||||
notificationText = getUserTalkMessage(context, document);
|
||||
break;
|
||||
case MENTION:
|
||||
notificationText = getMentionMessage(context, document);
|
||||
break;
|
||||
case WELCOME:
|
||||
notificationText = getWelcomeMessage(context, document);
|
||||
break;
|
||||
}
|
||||
return new Notification(type, notificationText, getTimestamp(document), description, link);
|
||||
}
|
||||
|
||||
public static String getMentionMessage(Context context, Node document) {
|
||||
String format = context.getString(R.string.notifications_mention);
|
||||
return String.format(format, getAgent(document), getNotificationDescription(document));
|
||||
}
|
||||
|
||||
public static String getUserTalkMessage(Context context, Node document) {
|
||||
String format = context.getString(R.string.notifications_talk_page_message);
|
||||
return String.format(format, getAgent(document));
|
||||
}
|
||||
|
||||
public static String getWelcomeMessage(Context context, Node document) {
|
||||
String welcomeMessageFormat = context.getString(R.string.notifications_welcome);
|
||||
return String.format(welcomeMessageFormat, getAgent(document));
|
||||
}
|
||||
|
||||
private static String getAgent(Node document) {
|
||||
Element agentElement = (Element) getNode(document, "agent");
|
||||
if (agentElement != null) {
|
||||
return agentElement.getAttribute("name");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String getTimestamp(Node document) {
|
||||
Element timestampElement = (Element) getNode(document, "timestamp");
|
||||
if (timestampElement != null) {
|
||||
return timestampElement.getAttribute("date");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String getNotificationLink(Node document) {
|
||||
String format = "%s%s";
|
||||
Element titleElement = (Element) getNode(document, "title");
|
||||
if (titleElement != null) {
|
||||
String fullName = titleElement.getAttribute("full");
|
||||
return String.format(format, BuildConfig.HOME_URL, fullName);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String getNotificationDescription(Node document) {
|
||||
Element titleElement = (Element) getNode(document, "title");
|
||||
if (titleElement != null) {
|
||||
return titleElement.getAttribute("text");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Node getNode(Node node, String nodeName) {
|
||||
NodeList childNodes = node.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node nodeItem = childNodes.item(i);
|
||||
Element item = (Element) nodeItem;
|
||||
if (item.getTagName().equals(nodeName)) {
|
||||
return nodeItem;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ import fr.free.nrw.commons.auth.AccountUtil;
|
|||
import fr.free.nrw.commons.auth.LoginActivity;
|
||||
import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||
import fr.free.nrw.commons.nearby.NearbyActivity;
|
||||
import fr.free.nrw.commons.notification.NotificationActivity;
|
||||
import fr.free.nrw.commons.settings.SettingsActivity;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
|
@ -143,6 +144,10 @@ public abstract class NavigationBaseActivity extends BaseActivity
|
|||
.setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel())
|
||||
.show();
|
||||
return true;
|
||||
case R.id.action_notifications:
|
||||
drawerLayout.closeDrawer(navigationView);
|
||||
NotificationActivity.startYourself(this);
|
||||
return true;
|
||||
default:
|
||||
Timber.e("Unknown option [%s] selected from the navigation menu", itemId);
|
||||
return false;
|
||||
|
|
|
|||
36
app/src/main/java/fr/free/nrw/commons/utils/DateUtils.java
Normal file
36
app/src/main/java/fr/free/nrw/commons/utils/DateUtils.java
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package fr.free.nrw.commons.utils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateUtils {
|
||||
public static String getTimeAgo(Date currDate, Date itemDate) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(currDate);
|
||||
int yearNow = c.get(Calendar.YEAR);
|
||||
int monthNow = c.get(Calendar.MONTH);
|
||||
int dayNow = c.get(Calendar.DAY_OF_MONTH);
|
||||
int hourNow = c.get(Calendar.HOUR_OF_DAY);
|
||||
int minuteNow = c.get(Calendar.MINUTE);
|
||||
c.setTime(itemDate);
|
||||
int videoYear = c.get(Calendar.YEAR);
|
||||
int videoMonth = c.get(Calendar.MONTH);
|
||||
int videoDays = c.get(Calendar.DAY_OF_MONTH);
|
||||
int videoHour = c.get(Calendar.HOUR_OF_DAY);
|
||||
int videoMinute = c.get(Calendar.MINUTE);
|
||||
|
||||
if (yearNow != videoYear) {
|
||||
return (String.valueOf(yearNow - videoYear) + "-" + "years");
|
||||
} else if (monthNow != videoMonth) {
|
||||
return (String.valueOf(monthNow - videoMonth) + "-" + "months");
|
||||
} else if (dayNow != videoDays) {
|
||||
return (String.valueOf(dayNow - videoDays) + "-" + "days");
|
||||
} else if (hourNow != videoHour) {
|
||||
return (String.valueOf(hourNow - videoHour) + "-" + "hours");
|
||||
} else if (minuteNow != videoMinute) {
|
||||
return (String.valueOf(minuteNow - videoMinute) + "-" + "minutes");
|
||||
} else {
|
||||
return "0-seconds";
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue