diff --git a/.gitignore b/.gitignore index 7c7dfa40..2330057f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ /app/src/main/res/values/secrets.xml /app/src/productionApp/ /app/fastaccess-key +fast-for-github-firebase-crashreporting-7lngx-6b5be91d98.json diff --git a/app/build.gradle b/app/build.gradle index 2b2ef0bd..56bf9ac0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,6 +3,7 @@ apply plugin: 'me.tatarka.retrolambda' apply plugin: "com.neenbedankt.android-apt" apply plugin: 'com.jakewharton.hugo' apply plugin: 'com.siimkinks.sqlitemagic' +apply plugin: 'com.google.firebase.firebase-crash' android { signingConfigs { @@ -96,8 +97,6 @@ dependencies { compile "com.android.support:recyclerview-v7:${supportVerion}" compile "com.android.support:preference-v14:${supportVerion}" compile "com.android.support:customtabs:${supportVerion}" - compile "com.google.firebase:firebase-messaging:${firebase}" - compile "com.google.firebase:firebase-analytics:${firebase}" compile "com.google.firebase:firebase-ads:${firebase}" compile "com.google.firebase:firebase-crash:${firebase}" compile "net.grandcentrix.thirtyinch:thirtyinch:${thirtyinchVersion}" diff --git a/app/src/main/java/com/fastaccess/data/service/NotificationService.java b/app/src/main/java/com/fastaccess/data/service/NotificationService.java index 83bee895..090b8d34 100644 --- a/app/src/main/java/com/fastaccess/data/service/NotificationService.java +++ b/app/src/main/java/com/fastaccess/data/service/NotificationService.java @@ -6,7 +6,9 @@ import com.fastaccess.data.dao.Pageable; import retrofit2.Response; import retrofit2.http.GET; import retrofit2.http.PATCH; +import retrofit2.http.PUT; import retrofit2.http.Path; +import retrofit2.http.Query; import rx.Observable; /** @@ -16,10 +18,15 @@ import rx.Observable; public interface NotificationService { @GET("notifications") - Observable> getNotifications(); + Observable> getNotifications(@Query("page") int page); + + @GET("notifications?all=true") + Observable> getAllNotifications(@Query("page") int page); @GET("/notifications/threads/{id}") Observable getNotification(@Path("id") String id); @PATCH("notifications/threads/{id}") Observable> markAsRead(@Path("id") String id); + + @PUT("notifications") Observable> markAllNotificationsAsRead(); } diff --git a/app/src/main/java/com/fastaccess/helper/InputHelper.java b/app/src/main/java/com/fastaccess/helper/InputHelper.java index e63b39c8..cee4b461 100644 --- a/app/src/main/java/com/fastaccess/helper/InputHelper.java +++ b/app/src/main/java/com/fastaccess/helper/InputHelper.java @@ -61,7 +61,9 @@ public class InputHelper { public static long toLong(TextView textView) { if (!isEmpty(textView)) { - return Long.valueOf(toString(textView)); + try { + return Long.valueOf(toString(textView)); + } catch (NumberFormatException ignored) {} } return 0; } diff --git a/app/src/main/java/com/fastaccess/provider/rest/RestProvider.java b/app/src/main/java/com/fastaccess/provider/rest/RestProvider.java index 7bc07c39..9366fd18 100644 --- a/app/src/main/java/com/fastaccess/provider/rest/RestProvider.java +++ b/app/src/main/java/com/fastaccess/provider/rest/RestProvider.java @@ -86,7 +86,7 @@ public class RestProvider { Request request = requestBuilder.build(); return chain.proceed(request); }); - client.cache(provideCache());//disable cache, since we are going offline. +// client.cache(provideCache());//disable cache, since we are going offline. return client.build(); } diff --git a/app/src/main/java/com/fastaccess/provider/tasks/NotificationJobTask.java b/app/src/main/java/com/fastaccess/provider/tasks/NotificationJobTask.java index da83eef3..7d9a0a35 100644 --- a/app/src/main/java/com/fastaccess/provider/tasks/NotificationJobTask.java +++ b/app/src/main/java/com/fastaccess/provider/tasks/NotificationJobTask.java @@ -40,7 +40,7 @@ public class NotificationJobTask extends JobService { @Override public boolean onStartJob(JobParameters job) { if (LoginModel.getUser() != null) { RestProvider.getNotificationService() - .getNotifications() + .getNotifications(0) .subscribeOn(Schedulers.io()) .subscribe(item -> { if (item != null) onSave(item.getItems()); diff --git a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/NotificationsViewHolder.java b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/NotificationsViewHolder.java index 596bf107..94780c55 100644 --- a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/NotificationsViewHolder.java +++ b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/NotificationsViewHolder.java @@ -24,10 +24,6 @@ public class NotificationsViewHolder extends BaseViewHolder { } @Override public void bind(@NonNull RepoFilesModel filesModel) { - contentTypeImage.setImageResource(filesModel.getType().getIcon()); contentTypeImage.setContentDescription(String.format("%s %s", filesModel.getName(), file)); title.setText(filesModel.getName()); - if (filesModel.getType() == FilesType.file) { - size.setText(Formatter.formatFileSize(size.getContext(), filesModel.getSize())); - size.setVisibility(View.VISIBLE); - } else { - size.setVisibility(View.GONE); + if (filesModel.getType() != null) { + contentTypeImage.setImageResource(filesModel.getType().getIcon()); + if (filesModel.getType() == FilesType.file) { + size.setText(Formatter.formatFileSize(size.getContext(), filesModel.getSize())); + size.setVisibility(View.VISIBLE); + } else { + size.setVisibility(View.GONE); + } } } } diff --git a/app/src/main/java/com/fastaccess/ui/modules/feeds/FeedsView.java b/app/src/main/java/com/fastaccess/ui/modules/feeds/FeedsView.java index 394f8fec..87354612 100644 --- a/app/src/main/java/com/fastaccess/ui/modules/feeds/FeedsView.java +++ b/app/src/main/java/com/fastaccess/ui/modules/feeds/FeedsView.java @@ -74,7 +74,7 @@ public class FeedsView extends BaseFragment imple } @Override public void showProgress(@StringRes int resId) { - refresh.setRefreshing(true); + stateLayout.showProgress(); } diff --git a/app/src/main/java/com/fastaccess/ui/modules/gists/GistsView.java b/app/src/main/java/com/fastaccess/ui/modules/gists/GistsView.java index 3eddc1d5..ab8751ff 100644 --- a/app/src/main/java/com/fastaccess/ui/modules/gists/GistsView.java +++ b/app/src/main/java/com/fastaccess/ui/modules/gists/GistsView.java @@ -65,7 +65,7 @@ public class GistsView extends BaseFragment imple } @Override public void showProgress(@StringRes int resId) { - refresh.setRefreshing(true); + stateLayout.showProgress(); } diff --git a/app/src/main/java/com/fastaccess/ui/modules/gists/gist/comments/GistCommentsView.java b/app/src/main/java/com/fastaccess/ui/modules/gists/gist/comments/GistCommentsView.java index 6343b6e9..589a2501 100644 --- a/app/src/main/java/com/fastaccess/ui/modules/gists/gist/comments/GistCommentsView.java +++ b/app/src/main/java/com/fastaccess/ui/modules/gists/gist/comments/GistCommentsView.java @@ -84,7 +84,7 @@ public class GistCommentsView extends BaseFragment imple if (progress == 100) { refresh.setRefreshing(false); } else if (progress < 100) { - refresh.setRefreshing(true); + } } }); diff --git a/app/src/main/java/com/fastaccess/ui/modules/main/MainView.java b/app/src/main/java/com/fastaccess/ui/modules/main/MainView.java index 7533ce04..7a603b7b 100644 --- a/app/src/main/java/com/fastaccess/ui/modules/main/MainView.java +++ b/app/src/main/java/com/fastaccess/ui/modules/main/MainView.java @@ -29,7 +29,7 @@ import com.fastaccess.helper.ViewHelper; import com.fastaccess.ui.base.BaseActivity; import com.fastaccess.ui.modules.feeds.FeedsView; import com.fastaccess.ui.modules.gists.create.CreateGistView; -import com.fastaccess.ui.modules.notification.NotificationsBottomSheet; +import com.fastaccess.ui.modules.notification.NotificationActivityView; import com.fastaccess.ui.modules.repos.RepoPagerView; import com.fastaccess.ui.modules.repos.issues.create.CreateIssueView; import com.fastaccess.ui.modules.search.SearchView; @@ -122,8 +122,7 @@ public class MainView extends BaseActivity implemen return true; } else if (item.getItemId() == R.id.notifications) { ViewHelper.tintDrawable(item.getIcon(), ContextCompat.getColor(this, R.color.primary_text)); - NotificationsBottomSheet.newInstance() - .show(getSupportFragmentManager(), "NotificationsBottomSheet"); + startActivity(new Intent(this,NotificationActivityView.class)); return true; } return super.onOptionsItemSelected(item); diff --git a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationActivityView.java b/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationActivityView.java index c92c07fd..c607c573 100644 --- a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationActivityView.java +++ b/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationActivityView.java @@ -11,11 +11,18 @@ import com.fastaccess.ui.base.mvp.presenter.BasePresenter; import net.grandcentrix.thirtyinch.TiPresenter; +import butterknife.OnItemSelected; + /** * Created by Kosh on 27 Feb 2017, 12:36 PM */ public class NotificationActivityView extends BaseActivity { + + private NotificationsView notificationsView; + private boolean userSelectedSpinner = false; + + @Override protected int layout() { return R.layout.notification_activity_layout; } @@ -38,6 +45,23 @@ public class NotificationActivityView extends BaseActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setTitle(""); AppHelper.cancelNotification(this); } + + @Override public void onUserInteraction() { + super.onUserInteraction(); + userSelectedSpinner = true; + } + + @OnItemSelected(R.id.notificationType) void onTypeSelected(int position) { + if (userSelectedSpinner) getNotificationsView().onTypeChanged(position == 0); + } + + public NotificationsView getNotificationsView() { + if (notificationsView == null) { + notificationsView = (NotificationsView) getSupportFragmentManager().findFragmentById(R.id.notificationFragment); + } + return notificationsView; + } } diff --git a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsBottomSheet.java b/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsBottomSheet.java deleted file mode 100644 index 46ef011c..00000000 --- a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsBottomSheet.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.fastaccess.ui.modules.notification; - -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v7.widget.Toolbar; -import android.view.View; - -import com.fastaccess.R; -import com.fastaccess.ui.base.BaseBottomSheetDialog; - -import butterknife.BindView; - -/** - * Created by Kosh on 20 Feb 2017, 8:58 PM - */ - -public class NotificationsBottomSheet extends BaseBottomSheetDialog { - - @BindView(R.id.toolbar) Toolbar toolbar; - - public static NotificationsBottomSheet newInstance() { - return new NotificationsBottomSheet(); - } - - @Override protected int layoutRes() { - return R.layout.notifications_bottom_sheet_layout; - } - - @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - toolbar.setNavigationIcon(R.drawable.ic_arrow_drop_down); - toolbar.setNavigationContentDescription(getString(R.string.back)); - toolbar.setTitle(R.string.notifictions); - toolbar.setNavigationOnClickListener(v -> dismiss()); - if (savedInstanceState == null) { - getChildFragmentManager() - .beginTransaction() - .replace(R.id.notificationView, NotificationsView.newInstance()) - .commit(); - } - } -} diff --git a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsMvp.java b/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsMvp.java index 57261701..e98018b4 100644 --- a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsMvp.java +++ b/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsMvp.java @@ -4,6 +4,7 @@ import android.support.annotation.NonNull; import android.support.v4.widget.SwipeRefreshLayout; import com.fastaccess.data.dao.NotificationThreadModel; +import com.fastaccess.provider.rest.loadmore.OnLoadMore; import com.fastaccess.ui.base.mvp.BaseMvp; import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder; @@ -16,15 +17,23 @@ import java.util.ArrayList; public interface NotificationsMvp { interface View extends BaseMvp.FAView, SwipeRefreshLayout.OnRefreshListener { + + @NonNull OnLoadMore getLoadMore(); + void onNotifyAdapter(); + + void onTypeChanged(boolean unread); } - interface Presenter extends BaseViewHolder.OnItemClickListener { - - void onCallApi(); + interface Presenter extends BaseViewHolder.OnItemClickListener, + BaseMvp.PaginationListener { void onWorkOffline(); @NonNull ArrayList getNotifications(); + + void onReadAll(); + + void showAllNotifications(boolean showAll); } } diff --git a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsPresenter.java index f9771284..c62cb142 100644 --- a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsPresenter.java +++ b/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsPresenter.java @@ -2,9 +2,12 @@ package com.fastaccess.ui.modules.notification; import android.net.Uri; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.view.View; import com.fastaccess.data.dao.NotificationThreadModel; +import com.fastaccess.data.dao.Pageable; +import com.fastaccess.helper.RxHelper; import com.fastaccess.provider.rest.RestProvider; import com.fastaccess.provider.scheme.SchemeParser; import com.fastaccess.ui.base.mvp.BaseMvp; @@ -12,13 +15,19 @@ import com.fastaccess.ui.base.mvp.presenter.BasePresenter; import java.util.ArrayList; +import retrofit2.Response; import rx.Observable; +import rx.functions.Func1; /** * Created by Kosh on 20 Feb 2017, 8:46 PM */ public class NotificationsPresenter extends BasePresenter implements NotificationsMvp.Presenter { + private int page; + private int previousTotal; + private int lastPage = Integer.MAX_VALUE; + private boolean showAll; private ArrayList notifications = new ArrayList<>(); @Override public void onItemClick(int position, View v, NotificationThreadModel item) { @@ -32,7 +41,7 @@ public class NotificationsPresenter extends BasePresenter sendToView(NotificationsMvp.View::onNotifyAdapter); }); } - if (item.getSubject() != null) { + if (item.getSubject() != null && item.getSubject().getUrl() != null) { SchemeParser.launchUri(v.getContext(), Uri.parse(item.getSubject().getUrl())); } } @@ -46,18 +55,6 @@ public class NotificationsPresenter extends BasePresenter return super.onError(throwable, observable); } - @Override public void onCallApi() { - makeRestCall(RestProvider.getNotificationService().getNotifications(), - response -> { - notifications.clear(); - if (response.getItems() != null) { - manageSubscription(NotificationThreadModel.save(response.getItems()).subscribe()); - notifications.addAll(response.getItems()); - } - sendToView(NotificationsMvp.View::onNotifyAdapter); - }); - } - @Override public void onWorkOffline() { if (notifications.isEmpty()) { manageSubscription(NotificationThreadModel.getNotifications() @@ -75,4 +72,76 @@ public class NotificationsPresenter extends BasePresenter @NonNull @Override public ArrayList getNotifications() { return notifications; } + + @Override public void onReadAll() { + if (!notifications.isEmpty()) { + Observable> observable = Observable.from(notifications) + .filter(NotificationThreadModel::isUnread) + .flatMap(new Func1>>() { + @Override public Observable> call(NotificationThreadModel notificationThreadModel) { + return RxHelper.getObserver(RestProvider.getNotificationService() + .markAsRead(String.valueOf(notificationThreadModel.getId()))); + } + }); + manageSubscription(observable.isEmpty().subscribe(isEmpty -> { + if (!isEmpty) { + makeRestCall(observable, booleanResponse -> { + if (booleanResponse.code() == 205) { + if (!notifications.isEmpty()) { + notifications.clear(); + manageSubscription(NotificationThreadModel.deleteTable().observe().subscribe()); + sendToView(NotificationsMvp.View::onNotifyAdapter); + } + } + }); + } + })); + } + } + + @Override public void showAllNotifications(boolean showAll) { + this.showAll = showAll; + } + + @Override public int getCurrentPage() { + return page; + } + + @Override public int getPreviousTotal() { + return previousTotal; + } + + @Override public void setCurrentPage(int page) { + this.page = page; + } + + @Override public void setPreviousTotal(int previousTotal) { + this.previousTotal = previousTotal; + } + + @Override public void onCallApi(int page, @Nullable Object parameter) { + if (page == 1) { + lastPage = Integer.MAX_VALUE; + sendToView(view -> view.getLoadMore().reset()); + } + if (page > lastPage || lastPage == 0) { + sendToView(NotificationsMvp.View::hideProgress); + return; + } + setCurrentPage(page); + Observable> observable = showAll ? RestProvider.getNotificationService().getAllNotifications(page) + : RestProvider.getNotificationService().getNotifications(page); + makeRestCall(observable, response -> { + notifications.clear(); + if (response.getItems() != null) { + lastPage = response.getLast(); + if (page == 1) { + notifications.clear(); + manageSubscription(NotificationThreadModel.save(response.getItems()).subscribe()); + } + notifications.addAll(response.getItems()); + } + sendToView(NotificationsMvp.View::onNotifyAdapter); + }); + } } diff --git a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsView.java b/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsView.java index 542ada83..f4c859cc 100644 --- a/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsView.java +++ b/app/src/main/java/com/fastaccess/ui/modules/notification/NotificationsView.java @@ -4,9 +4,13 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringRes; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import com.fastaccess.R; +import com.fastaccess.provider.rest.loadmore.OnLoadMore; import com.fastaccess.ui.adapter.NotificationsAdapter; import com.fastaccess.ui.base.BaseFragment; import com.fastaccess.ui.widgets.AppbarRefreshLayout; @@ -26,13 +30,27 @@ public class NotificationsView extends BaseFragment(getPresenter()); + } + return onLoadMore; } @Override public void onNotifyAdapter() { @@ -40,6 +58,11 @@ public class NotificationsView extends BaseFragment onRefresh()); + getLoadMore().setCurrent_page(getPresenter().getCurrentPage(), getPresenter().getPreviousTotal()); recycler.setEmptyView(stateLayout, refresh); recycler.setAdapter(adapter); + recycler.addOnScrollListener(getLoadMore()); if (savedInstanceState == null || !getPresenter().isApiCalled()) { - getPresenter().onCallApi(); + onRefresh(); } } @@ -61,7 +86,7 @@ public class NotificationsView extends BaseFragment + + diff --git a/app/src/main/res/layouts/main_layouts/layout/notification_activity_layout.xml b/app/src/main/res/layouts/main_layouts/layout/notification_activity_layout.xml index c39b5e20..562d63bd 100644 --- a/app/src/main/res/layouts/main_layouts/layout/notification_activity_layout.xml +++ b/app/src/main/res/layouts/main_layouts/layout/notification_activity_layout.xml @@ -6,7 +6,44 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/res/mipmap-hdpi/ic_launcher.png deleted file mode 100755 index b2de32d4..00000000 Binary files a/app/src/main/res/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/res/mipmap-mdpi/ic_launcher.png deleted file mode 100755 index 715f0028..00000000 Binary files a/app/src/main/res/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100755 index 189e7712..00000000 Binary files a/app/src/main/res/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100755 index d3b1ff2d..00000000 Binary files a/app/src/main/res/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100755 index b38ac659..00000000 Binary files a/app/src/main/res/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml new file mode 100644 index 00000000..de45e13e --- /dev/null +++ b/app/src/main/res/values/arrays.xml @@ -0,0 +1,7 @@ + + + + @string/unread + @string/all + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 49799498..96a248a8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -182,4 +182,8 @@ This date represent the creation date. This date represent when the last activity happened. com.fastaccess.ui.widgets.FloatingActionButtonBehavior + Mark all as read + All Notifications + Unread + All diff --git a/build.gradle b/build.gradle index 2175323b..a600e386 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ buildscript { classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2' classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1' classpath 'com.siimkinks.sqlitemagic:sqlitemagic-plugin:0.11.0' + classpath 'com.google.firebase:firebase-plugins:1.0.5' } configurations.classpath.exclude group: 'com.android.tools.external.lombok' }