package com.gh4a.fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.Loader;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.gh4a.BackgroundTask;
import com.gh4a.BrowseFilter;
import com.gh4a.Gh4Application;
import com.gh4a.R;
import com.gh4a.activities.RepositoryActivity;
import com.gh4a.adapter.NotificationAdapter;
import com.gh4a.adapter.RootAdapter;
import com.gh4a.loader.LoaderCallbacks;
import com.gh4a.loader.LoaderResult;
import com.gh4a.loader.NotificationHolder;
import com.gh4a.loader.NotificationListLoadResult;
import com.gh4a.loader.NotificationListLoader;
import com.gh4a.utils.ApiHelpers;
import com.gh4a.utils.IntentUtils;
import org.eclipse.egit.github.core.Notification;
import org.eclipse.egit.github.core.NotificationSubject;
import org.eclipse.egit.github.core.Repository;
import org.eclipse.egit.github.core.service.NotificationService;
import java.io.IOException;
import java.util.Date;
public class NotificationListFragment extends LoadingListFragmentBase implements
RootAdapter.OnItemClickListener<NotificationHolder>,NotificationAdapter.OnNotificationActionCallback {
public static NotificationListFragment newInstance() {
return new NotificationListFragment();
}
private final LoaderCallbacks<NotificationListLoadResult> mNotificationsCallback =
new LoaderCallbacks<NotificationListLoadResult>(this) {
@Override
protected Loader<LoaderResult<NotificationListLoadResult>> onCreateLoader() {
return new NotificationListLoader(getContext());
}
@Override
protected void onResultReady(NotificationListLoadResult result) {
mNotificationsLoadTime = result.loadTime;
mAdapter.clear();
mAdapter.addAll(result.notifications);
setContentShown(true);
mAdapter.notifyDataSetChanged();
updateEmptyState();
updateMenuItemVisibility();
}
};
private NotificationAdapter mAdapter;
private Date mNotificationsLoadTime;
private MenuItem mMarkAllAsReadMenuItem;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setContentShown(false);
getLoaderManager().initLoader(0, null, mNotificationsCallback);
}
@Override
protected int getEmptyTextResId() {
return R.string.no_notifications_found;
}
@Override
public void onRefresh() {
if (mAdapter != null) {
mAdapter.clear();
}
hideContentAndRestartLoaders(0);
updateMenuItemVisibility();
}
@Override
protected void onRecyclerViewInflated(RecyclerView view, LayoutInflater inflater) {
super.onRecyclerViewInflated(view, inflater);
mAdapter = new NotificationAdapter(getActivity(), this);
mAdapter.setOnItemClickListener(this);
view.setAdapter(mAdapter);
updateEmptyState();
}
@Override
protected boolean hasDividers() {
return false;
}
@Override
protected boolean hasCards() {
return true;
}
@Override
public void onItemClick(NotificationHolder item) {
final Intent intent;
if (item.notification == null) {
intent = RepositoryActivity.makeIntent(getActivity(), item.repository);
} else {
new MarkReadTask(null, item.notification).schedule();
NotificationSubject subject = item.notification.getSubject();
Uri uri = ApiHelpers.normalizeUri(Uri.parse(subject.getUrl()));
intent = BrowseFilter.makeRedirectionIntent(getActivity(), uri,
new IntentUtils.InitialCommentMarker(item.notification.getLastReadAt()));
}
startActivity(intent);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.notification_list_menu, menu);
mMarkAllAsReadMenuItem = menu.findItem(R.id.mark_all_as_read);
updateMenuItemVisibility();
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.mark_all_as_read:
new AlertDialog.Builder(getActivity())
.setMessage(R.string.mark_all_as_read_question)
.setPositiveButton(R.string.mark_all_as_read,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new MarkReadTask(null, null).schedule();
}
})
.setNegativeButton(R.string.cancel, null)
.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void markAsRead(NotificationHolder notificationHolder) {
if (notificationHolder.notification == null) {
final Repository repository = notificationHolder.repository;
String login = ApiHelpers.getUserLogin(getActivity(), repository.getOwner());
String title = getString(R.string.mark_repository_as_read_question,
login + "/" + repository.getName());
new AlertDialog.Builder(getActivity())
.setMessage(title)
.setPositiveButton(R.string.mark_as_read,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new MarkReadTask(repository, null).schedule();
}
})
.setNegativeButton(R.string.cancel, null)
.show();
} else {
new MarkReadTask(null, notificationHolder.notification).schedule();
}
}
@Override
public void unsubscribe(NotificationHolder notificationHolder) {
new UnsubscribeTask(notificationHolder.notification).schedule();
}
private void updateMenuItemVisibility() {
if (mMarkAllAsReadMenuItem == null) {
return;
}
mMarkAllAsReadMenuItem.setVisible(isContentShown() && mAdapter.getCount() > 0);
}
private class MarkReadTask extends BackgroundTask<Void> {
@Nullable
private final Repository mRepository;
@Nullable
private final Notification mNotification;
public MarkReadTask(@Nullable Repository repository, @Nullable Notification notification) {
super(getActivity());
mRepository = repository;
mNotification = notification;
}
@Override
protected Void run() throws IOException {
NotificationService notificationService = (NotificationService)
Gh4Application.get().getService(Gh4Application.NOTIFICATION_SERVICE);
if (mNotification != null) {
notificationService.markThreadAsRead(mNotification.getId());
} else if (mRepository != null) {
notificationService.markNotificationsAsRead(mRepository, mNotificationsLoadTime);
} else {
notificationService.markNotificationsAsRead(mNotificationsLoadTime);
}
return null;
}
@Override
protected void onSuccess(Void result) {
mAdapter.markAsRead(mRepository, mNotification);
}
}
private class UnsubscribeTask extends BackgroundTask<Void> {
private final Notification mNotification;
public UnsubscribeTask(Notification notification) {
super(getActivity());
mNotification = notification;
}
@Override
protected Void run() throws IOException {
NotificationService notificationService = (NotificationService)
Gh4Application.get().getService(Gh4Application.NOTIFICATION_SERVICE);
notificationService.setThreadSubscription(mNotification.getId(), false, true);
return null;
}
@Override
protected void onSuccess(Void result) {
mAdapter.markAsRead(null, mNotification);
}
}
}