Android Open Source - ghwatch Main Activity






From Project

Back to project page ghwatch.

License

The source code is released under:

Apache License

If you think the Android project ghwatch listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2014 contributors as indicated by the @authors tag.
 * //from  w  w  w. j a va 2 s .co m
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.daskiworks.ghwatch;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;

import com.daskiworks.ghwatch.LoginDialogFragment.LoginDialogListener;
import com.daskiworks.ghwatch.backend.GHConstants;
import com.daskiworks.ghwatch.backend.UnreadNotificationsService;
import com.daskiworks.ghwatch.backend.ViewDataReloadStrategy;
import com.daskiworks.ghwatch.image.ImageLoader;
import com.daskiworks.ghwatch.model.BaseViewData;
import com.daskiworks.ghwatch.model.LoadingStatus;
import com.daskiworks.ghwatch.model.NotifCount;
import com.daskiworks.ghwatch.model.Notification;
import com.daskiworks.ghwatch.model.NotificationStreamViewData;
import com.daskiworks.ghwatch.model.StringViewData;

/**
 * Activity used to show list of Notifications.
 * 
 * @author Vlastimil Elias <vlastimil.elias@worldonline.cz>
 * 
 */
public class MainActivity extends ActivityBase implements LoginDialogListener, OnRefreshListener {

  private static final String STATE_FILTER_REPOSITORY = "STATE_FILTER_REPOSITORY";

  public static String INTENT_ACTION_DISMISS_ALL = "ACTION_MARK_ALL_READ";
  public static String INTENT_ACTION_SHOW = "ACTION_SHOW";

  private static final String TAG = MainActivity.class.getSimpleName();

  // common fields
  private DataLoaderTask dataLoader;

  // view components
  private ListView notificationsListView;
  private NotificationListAdapter notificationsListAdapter;

  private ListView repositoriesListView;
  private NotificationRepositoriesListAdapter repositoriesListAdapter;

  // backend services
  private ImageLoader imageLoader;
  private UnreadNotificationsService unreadNotificationsService;

  // filters
  private String filterByRepository = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (savedInstanceState != null) {
      filterByRepository = savedInstanceState.getString(STATE_FILTER_REPOSITORY);
    }

    setContentView(R.layout.activity_main);

    imageLoader = ImageLoader.getInstance(getApplicationContext());
    unreadNotificationsService = new UnreadNotificationsService(getBaseContext());

    initNavigationDrawer(NAV_DRAWER_ITEM_UNREAD_NOTIF);

    repositoriesListView = (ListView) findViewById(R.id.repositories_list);
    repositoriesListView.setOnItemClickListener(new RepositoriesListItemClickListener());

    // initialization of main content
    notificationsListView = (ListView) findViewById(R.id.list);
    notificationsListView.setVerticalFadingEdgeEnabled(true);
    SwipeDismissListViewTouchListener touchListener = new SwipeDismissListViewTouchListener(notificationsListView, new NotificationsListSwipeDismissListener());
    notificationsListView.setOnTouchListener(touchListener);
    // Setting this scroll listener is required to ensure that during ListView scrolling,
    // we don't look for swipes.
    notificationsListView.setOnScrollListener(touchListener.makeScrollListener());

    initSwipeLayout(this);
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putCharSequence(STATE_FILTER_REPOSITORY, filterByRepository);
  }

  @Override
  protected void onResume() {
    super.onResume();
    if (!checkUserLoggedIn()) {
      finish();
      return;
    }
    ActivityTracker.sendView(this, TAG);

    Intent intent = getIntent();
    Log.d(TAG, "Intent who runs us : " + getIntent());
    if (intent != null && INTENT_ACTION_DISMISS_ALL.equals(intent.getAction())) {
      showMarkAllNotificationsAsReadDialog();
      intent.setAction(null);
    } else {
      if (SupportAppDevelopmentDialogFragment.isAutoShowScheduled(this)) {
        showSupportAppDevelopmentDialog();
      }
    }
    refreshList(ViewDataReloadStrategy.IF_TIMED_OUT, false);
    unreadNotificationsService.markAndroidWidgetsAsRead();
    unreadNotificationsService.markAndroidNotificationsRead();
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_activity_actions, menu);
    MenuItem mi = menu.findItem(R.id.action_notifCheck);
    if (mi != null) {
      mi.setVisible(GHConstants.DEBUG);
    }
    return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onPrepareOptionsMenu(Menu menu) {
    menu.findItem(R.id.action_all_read).setVisible(notificationsListAdapter != null && !notificationsListAdapter.isEmpty());
    return super.onPrepareOptionsMenu(menu);
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    if (dataLoader != null)
      dataLoader.cancel(true);
    notifyDataSetChanged();
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (super.onOptionsItemSelected(item)) {
      return true;
    }

    switch (item.getItemId()) {
    case R.id.action_all_read:
      showMarkAllNotificationsAsReadDialog();
      return true;
    case R.id.action_notifCheck:
      Toast.makeText(MainActivity.this, "New notification check started with empty store", Toast.LENGTH_SHORT).show();
      unreadNotificationsService.flushPersistentStore();
      unreadNotificationsService.newNotificationCheck();
      return true;
    default:
      return false;
    }
  }

  /**
   * Called when "Swipe to refresh" is finished.
   */
  @Override
  public void onRefresh() {
    ActivityTracker.sendEvent(this, ActivityTracker.CAT_UI, "unread_notifications_refresh", "", 0L);
    refreshList(ViewDataReloadStrategy.ALWAYS, false);
  }

  public void refreshList(ViewDataReloadStrategy reloadStrateg, boolean supressErrorMessages) {
    if (dataLoader == null)
      (dataLoader = new DataLoaderTask(reloadStrateg, supressErrorMessages)).execute();
  }

  private final class NotificationsListSwipeDismissListener implements SwipeDismissListViewTouchListener.DismissCallbacks {
    @Override
    public boolean canDismiss(int position) {
      return true;
    }

    @Override
    public void onDismiss(ListView listView, int[] reverseSortedPositions) {
      for (int position : reverseSortedPositions) {
        Notification tr = (Notification) notificationsListAdapter.getItem(position);
        if (tr != null) {
          new MarkNotificationAsReadTask().execute(tr.getId());
          ActivityTracker.sendEvent(MainActivity.this, ActivityTracker.CAT_UI, "notification_mark_read_swipe", "", 0L);
          notificationsListAdapter.removeNotificationByPosition(position);
        }
      }
      notifyDataSetChanged();
    }
  }

  private final class NotificationsListItemClickListener implements OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      Notification notification = (Notification) notificationsListAdapter.getItem(position);
      if (notification != null) {
        new ShowNotificationTask().execute(notification);
        ActivityTracker.sendEvent(MainActivity.this, ActivityTracker.CAT_UI, "notification_show", "", 0L);
      }
    }
  }

  private final class NotificationsListItemMenuClickListener implements NotificationListAdapter.OnItemMenuClickedListener {
    @Override
    public boolean onMenuItemClick(Notification notification, MenuItem item) {
      switch (item.getItemId()) {
      case R.id.action_view:
        new ShowNotificationTask().execute(notification);
        ActivityTracker.sendEvent(MainActivity.this, ActivityTracker.CAT_UI, "notification_show_menu", "", 0L);
      case R.id.action_mark_read:
        new MarkNotificationAsReadTask().execute(notification.getId());
        notificationsListAdapter.removeNotificationById(notification.getId());
        ActivityTracker.sendEvent(MainActivity.this, ActivityTracker.CAT_UI, "notification_mark_read_menu", "", 0L);
        notifyDataSetChanged();
        return true;
      case R.id.action_mute_thread:
        new MuteNotificationThreadTask().execute(notification.getId());
        notificationsListAdapter.removeNotificationById(notification.getId());
        ActivityTracker.sendEvent(MainActivity.this, ActivityTracker.CAT_UI, "notification_mute_thread", "", 0L);
        notifyDataSetChanged();
        return true;
      default:
        return false;
      }
    }
  }

  private final class RepositoriesListItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      if (repositoriesListView != null) {
        NotifCount nc = (NotifCount) repositoriesListAdapter.getItem(position);
        if (nc != null) {
          if (filterByRepository != null && filterByRepository.equals(nc.title)) {
            filterByRepository = null;
            repositoriesListView.setItemChecked(position, false);
          } else {
            filterByRepository = nc.title;
          }
          if (notificationsListAdapter != null) {
            notificationsListAdapter.setFilterByRepository(filterByRepository);
          }
          ActivityTracker.sendEvent(MainActivity.this, ActivityTracker.CAT_UI, "notification_filter_by_repository", filterByRepository != null ? "SET"
              : "RESET", 0L);
        }
      }
      navigationDrawerClose();

    }
  }

  private final class DataLoaderTask extends AsyncTask<String, String, NotificationStreamViewData> {

    ViewDataReloadStrategy reloadStrategy = null;
    boolean supressErrorMessages = false;

    DataLoaderTask(ViewDataReloadStrategy reloadStrategy, boolean supressErrorMessages) {
      this.reloadStrategy = reloadStrategy;
      this.supressErrorMessages = supressErrorMessages;
    }

    @Override
    protected void onPreExecute() {
      super.onPreExecute();
    }

    @Override
    protected NotificationStreamViewData doInBackground(String... args) {
      return unreadNotificationsService.getNotificationStreamForView(reloadStrategy);
    }

    @Override
    protected void onPostExecute(final NotificationStreamViewData viewData) {
      try {
        if (isCancelled() || viewData == null)
          return;
        if (viewData.loadingStatus != LoadingStatus.OK) {
          if (!supressErrorMessages)
            showServerCommunicationErrorAllertDialog(viewData.loadingStatus, viewData.notificationStream != null);
        }
        if (viewData.notificationStream != null) {

          if (notificationsListAdapter != null) {
            notificationsListAdapter.setNotificationStream(viewData.notificationStream);
            notificationsListAdapter.notifyDataSetChanged();
          } else {
            notificationsListAdapter = new NotificationListAdapter(MainActivity.this, viewData.notificationStream, imageLoader);
            notificationsListView.setAdapter(notificationsListAdapter);
            notificationsListAdapter.setOnItemMenuClickedListener(new NotificationsListItemMenuClickListener());
            notificationsListView.setOnItemClickListener(new NotificationsListItemClickListener());
          }

          if (repositoriesListAdapter != null) {
            repositoriesListAdapter.setNotificationStream(viewData.notificationStream);
            repositoriesListAdapter.notifyDataSetChanged();
          } else {
            repositoriesListAdapter = new NotificationRepositoriesListAdapter(MainActivity.this, viewData.notificationStream);
            repositoriesListView.setAdapter(repositoriesListAdapter);
          }
          if (!repositoriesListAdapter.setSelectionForFilter(repositoriesListView, filterByRepository)) {
            // repo no more in data so reset filter
            filterByRepository = null;
          }
          if (notificationsListAdapter != null) {
            notificationsListAdapter.setFilterByRepository(filterByRepository);
          }

          if (viewData.notificationStream.size() == 0) {
            swipeLayout2.setVisibility(View.VISIBLE);
            swipeLayout.setVisibility(View.GONE);
          } else {
            swipeLayout2.setVisibility(View.GONE);
            swipeLayout.setVisibility(View.VISIBLE);
          }
        }
      } finally {
        dataLoader = null;
        swipeLayout.setRefreshing(false);
        swipeLayout2.setRefreshing(false);
        hideInitialProgressBar();
        invalidateOptionsMenu();
      }
    }
  }

  private final class ShowNotificationTask extends AsyncTask<Notification, String, StringViewData> {

    ProgressDialog progress;

    @Override
    protected void onPreExecute() {
      progress = ProgressDialog.show(MainActivity.this, null, getString(R.string.progress_get_view_url_title), true, true, new OnCancelListener() {

        @Override
        public void onCancel(DialogInterface dialog) {
          ShowNotificationTask.this.cancel(true);
        }
      });
    }

    @Override
    protected StringViewData doInBackground(Notification... params) {
      return unreadNotificationsService.getGithubDataHtmlUrl(params[0].getViewBaseUrl());
    }

    @Override
    protected void onPostExecute(StringViewData result) {
      if (isCancelled() || result == null) {
        progress.dismiss();
        return;
      }
      if (result.loadingStatus != LoadingStatus.OK) {
        progress.dismiss();
        showServerCommunicationErrorAllertDialog(result.loadingStatus, false);
      } else if (result.data != null) {
        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(result.data));
        startActivity(browserIntent);
        progress.dismiss();
      }
    }
  }

  private final class MarkNotificationAsReadTask extends AsyncTask<Long, String, BaseViewData> {

    @Override
    protected BaseViewData doInBackground(Long... params) {

      return unreadNotificationsService.markNotificationAsRead(params[0]);
    }

    @Override
    protected void onPostExecute(final BaseViewData viewData) {
      if (isCancelled() || viewData == null)
        return;
      if (viewData.loadingStatus != LoadingStatus.OK) {
        showServerCommunicationErrorAllertDialog(viewData.loadingStatus, false);
        refreshList(ViewDataReloadStrategy.NEVER, true);
      } else {
        // Toast.makeText(MainActivity.this, R.string.message_notification_marked_read, Toast.LENGTH_SHORT).show();
      }
    }
  }

  private final class MuteNotificationThreadTask extends AsyncTask<Long, String, BaseViewData> {

    @Override
    protected BaseViewData doInBackground(Long... params) {

      return unreadNotificationsService.muteNotificationThread(params[0]);
    }

    @Override
    protected void onPostExecute(final BaseViewData viewData) {
      if (isCancelled() || viewData == null)
        return;
      if (viewData.loadingStatus != LoadingStatus.OK) {
        showServerCommunicationErrorAllertDialog(viewData.loadingStatus, false);
        refreshList(ViewDataReloadStrategy.NEVER, true);
      } else {
        Toast.makeText(MainActivity.this, R.string.message_notification_thread_muted, Toast.LENGTH_SHORT).show();
      }
    }
  }

  private final class MarkAllNotificationsAsReadTask extends AsyncTask<Object, String, BaseViewData> {

    @Override
    protected void onPreExecute() {
      swipeLayout.setRefreshing(true);
    }

    @Override
    protected BaseViewData doInBackground(Object... params) {
      return unreadNotificationsService.markAllNotificationsAsRead(filterByRepository);
    }

    @Override
    protected void onPostExecute(final BaseViewData viewData) {
      boolean supressErrorMessage = false;
      ViewDataReloadStrategy reloadStrategy = ViewDataReloadStrategy.ALWAYS;
      try {
        if (isCancelled() || viewData == null)
          return;
        if (viewData.loadingStatus != LoadingStatus.OK) {
          showServerCommunicationErrorAllertDialog(viewData.loadingStatus, false);
          supressErrorMessage = true;
          reloadStrategy = ViewDataReloadStrategy.NEVER;
        } else {
          supressErrorMessage = false;
          reloadStrategy = ViewDataReloadStrategy.ALWAYS;
          // Toast.makeText(MainActivity.this, R.string.message_notifications_all_marked_read, Toast.LENGTH_SHORT).show();
        }
      } finally {
        refreshList(reloadStrategy, supressErrorMessage);
      }
    }
  }

  private void showServerCommunicationErrorAllertDialog(LoadingStatus loadingStatus, boolean showStaledDataWarning) {
    StringBuilder sb = new StringBuilder();
    sb.append(getString(loadingStatus.getResId()));
    if (showStaledDataWarning) {
      sb.append("\n").append(getString(R.string.message_staled_data));
    }
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(sb).setCancelable(true).setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int id) {
      }
    });

    builder.create().show();
  }

  private void showMarkAllNotificationsAsReadDialog() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(R.string.message_confirm_notifications_all_mark_read_title);
    if (filterByRepository == null) {
      builder.setMessage(R.string.message_confirm_notifications_all_mark_read);
    } else {
      builder.setMessage(R.string.message_confirm_notifications_all_mark_read_repo);
    }
    builder.setCancelable(true);
    builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int id) {
        ActivityTracker.sendEvent(MainActivity.this, ActivityTracker.CAT_UI, "notifications_mark_read_all", "", 0L);
        new MarkAllNotificationsAsReadTask().execute();
      }
    });
    builder.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int id) {
      }
    });
    builder.create().show();
  }

  @Override
  public void afterLoginSuccess(LoginDialogFragment dialog) {
    refreshList(ViewDataReloadStrategy.ALWAYS, false);
  }

  protected void notifyDataSetChanged() {
    if (notificationsListAdapter != null)
      notificationsListAdapter.notifyDataSetChanged();
    if (repositoriesListAdapter != null) {
      repositoriesListAdapter.notifyDataSetChanged();
    }
  }
}




Java Source Code List

com.daskiworks.ghwatch.AboutDialogFragment.java
com.daskiworks.ghwatch.ActivityBase.java
com.daskiworks.ghwatch.ActivityTracker.java
com.daskiworks.ghwatch.FullHeightListView.java
com.daskiworks.ghwatch.IabHelper.java
com.daskiworks.ghwatch.LoginDialogFragment.java
com.daskiworks.ghwatch.MainActivity.java
com.daskiworks.ghwatch.MyBackupAgent.java
com.daskiworks.ghwatch.NotificationListAdapter.java
com.daskiworks.ghwatch.NotificationRepositoriesListAdapter.java
com.daskiworks.ghwatch.SettingsActivity.java
com.daskiworks.ghwatch.StartActivity.java
com.daskiworks.ghwatch.SupportAppDevelopmentDialogFragment.java
com.daskiworks.ghwatch.SwipeDismissListViewTouchListener.java
com.daskiworks.ghwatch.UnreadAppWidgetProvider.java
com.daskiworks.ghwatch.Utils.java
com.daskiworks.ghwatch.WatchedRepositoriesActivity.java
com.daskiworks.ghwatch.WatchedRepositoryListAdapter.java
com.daskiworks.ghwatch.alarm.AlarmBroadcastReceiver.java
com.daskiworks.ghwatch.alarm.MarkNotifiationAsReadReceiver.java
com.daskiworks.ghwatch.backend.AuthenticationManager.java
com.daskiworks.ghwatch.backend.GHConstants.java
com.daskiworks.ghwatch.backend.NotificationStreamParser.java
com.daskiworks.ghwatch.backend.OTPAuthenticationException.java
com.daskiworks.ghwatch.backend.PreferencesUtils.java
com.daskiworks.ghwatch.backend.RemoteSystemClient.java
com.daskiworks.ghwatch.backend.UnreadNotificationsService.java
com.daskiworks.ghwatch.backend.ViewDataReloadStrategy.java
com.daskiworks.ghwatch.backend.WatchedRepositoriesParser.java
com.daskiworks.ghwatch.backend.WatchedRepositoriesService.java
com.daskiworks.ghwatch.image.FileCache.java
com.daskiworks.ghwatch.image.ImageLoader.java
com.daskiworks.ghwatch.image.MemoryCache.java
com.daskiworks.ghwatch.model.AccountType.java
com.daskiworks.ghwatch.model.BaseViewData.java
com.daskiworks.ghwatch.model.BooleanViewData.java
com.daskiworks.ghwatch.model.GHCredentials.java
com.daskiworks.ghwatch.model.GHUserInfo.java
com.daskiworks.ghwatch.model.GHUserLoginInfo.java
com.daskiworks.ghwatch.model.LoadingStatus.java
com.daskiworks.ghwatch.model.NotifCount.java
com.daskiworks.ghwatch.model.NotificationStreamViewData.java
com.daskiworks.ghwatch.model.NotificationStream.java
com.daskiworks.ghwatch.model.Notification.java
com.daskiworks.ghwatch.model.Repository.java
com.daskiworks.ghwatch.model.StringViewData.java
com.daskiworks.ghwatch.model.WatchedRepositoriesViewData.java
com.daskiworks.ghwatch.model.WatchedRepositories.java
com.daskiworks.ghwatch.view.preference.ShowTextPreference.java
com.daskiworks.ghwatch.view.preference.ShowTimestampPreference.java