added an option to see all notifications to close #44, added an option to mark all notifications as read to close #37, made all swipeRefreshLayouts to not show until they actually forced to be showing by pulling to refresh to close #25, made notifications to be pageable in case if they are more than 30 notifications.

This commit is contained in:
Kosh 2017-03-02 00:32:26 +08:00
parent c42d3cdd74
commit 596d4bc2fa
50 changed files with 289 additions and 109 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -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}"

View File

@ -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<Pageable<NotificationThreadModel>> getNotifications();
Observable<Pageable<NotificationThreadModel>> getNotifications(@Query("page") int page);
@GET("notifications?all=true")
Observable<Pageable<NotificationThreadModel>> getAllNotifications(@Query("page") int page);
@GET("/notifications/threads/{id}")
Observable<NotificationThreadModel> getNotification(@Path("id") String id);
@PATCH("notifications/threads/{id}") Observable<Response<Boolean>> markAsRead(@Path("id") String id);
@PUT("notifications") Observable<Response<Boolean>> markAllNotificationsAsRead();
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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());

View File

@ -24,10 +24,6 @@ public class NotificationsViewHolder extends BaseViewHolder<NotificationThreadMo
@BindView(R.id.date) FontTextView date;
@BindView(R.id.notificationTitle) FontTextView notificationTitle;
@Override public void onClick(View v) {
super.onClick(v);
}
private NotificationsViewHolder(@NonNull View itemView, @Nullable BaseRecyclerAdapter adapter) {
super(itemView, adapter);
}

View File

@ -38,14 +38,16 @@ public class RepoFilesViewHolder extends BaseViewHolder<RepoFilesModel> {
}
@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);
}
}
}
}

View File

@ -74,7 +74,7 @@ public class FeedsView extends BaseFragment<FeedsMvp.View, FeedsPresenter> imple
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -65,7 +65,7 @@ public class GistsView extends BaseFragment<GistsMvp.View, GistsPresenter> imple
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -84,7 +84,7 @@ public class GistCommentsView extends BaseFragment<GistCommentsMvp.View, GistCom
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -66,7 +66,7 @@ public class LoginView extends BaseActivity<LoginMvp.View, LoginPresenter> imple
if (progress == 100) {
refresh.setRefreshing(false);
} else if (progress < 100) {
refresh.setRefreshing(true);
}
}
});

View File

@ -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<MainMvp.View, MainPresenter> 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);

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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<NotificationThreadModel> {
void onCallApi();
interface Presenter extends BaseViewHolder.OnItemClickListener<NotificationThreadModel>,
BaseMvp.PaginationListener {
void onWorkOffline();
@NonNull ArrayList<NotificationThreadModel> getNotifications();
void onReadAll();
void showAllNotifications(boolean showAll);
}
}

View File

@ -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<NotificationsMvp.View> implements NotificationsMvp.Presenter {
private int page;
private int previousTotal;
private int lastPage = Integer.MAX_VALUE;
private boolean showAll;
private ArrayList<NotificationThreadModel> notifications = new ArrayList<>();
@Override public void onItemClick(int position, View v, NotificationThreadModel item) {
@ -32,7 +41,7 @@ public class NotificationsPresenter extends BasePresenter<NotificationsMvp.View>
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<NotificationsMvp.View>
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<NotificationsMvp.View>
@NonNull @Override public ArrayList<NotificationThreadModel> getNotifications() {
return notifications;
}
@Override public void onReadAll() {
if (!notifications.isEmpty()) {
Observable<Response<Boolean>> observable = Observable.from(notifications)
.filter(NotificationThreadModel::isUnread)
.flatMap(new Func1<NotificationThreadModel, Observable<Response<Boolean>>>() {
@Override public Observable<Response<Boolean>> 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<Pageable<NotificationThreadModel>> 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);
});
}
}

View File

@ -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<NotificationsMvp.View, Notif
@BindView(R.id.refresh) AppbarRefreshLayout refresh;
@BindView(R.id.stateLayout) StateLayout stateLayout;
private OnLoadMore onLoadMore;
private NotificationsAdapter adapter;
public static NotificationsView newInstance() {
return new NotificationsView();
}
@Override public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override public void onRefresh() {
getPresenter().onCallApi();
getPresenter().onCallApi(1, null);
}
@SuppressWarnings("unchecked") @NonNull @Override public OnLoadMore getLoadMore() {
if (onLoadMore == null) {
onLoadMore = new OnLoadMore<>(getPresenter());
}
return onLoadMore;
}
@Override public void onNotifyAdapter() {
@ -40,6 +58,11 @@ public class NotificationsView extends BaseFragment<NotificationsMvp.View, Notif
adapter.notifyDataSetChanged();
}
@Override public void onTypeChanged(boolean unread) {
getPresenter().showAllNotifications(!unread);
onRefresh();
}
@Override protected int fragmentLayout() {
return R.layout.small_grid_refresh_list;
}
@ -49,10 +72,12 @@ public class NotificationsView extends BaseFragment<NotificationsMvp.View, Notif
adapter.setListener(getPresenter());
refresh.setOnRefreshListener(this);
stateLayout.setOnReloadListener(v -> 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<NotificationsMvp.View, Notif
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}
@ -75,4 +100,22 @@ public class NotificationsView extends BaseFragment<NotificationsMvp.View, Notif
stateLayout.showReload(adapter.getItemCount());
super.showErrorMessage(msgRes);
}
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.notification_menu, menu);
}
@Override public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.readAll) {
getPresenter().onReadAll();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override public void onDestroyView() {
recycler.removeOnScrollListener(getLoadMore());
super.onDestroyView();
}
}

View File

@ -69,7 +69,7 @@ public class ProfileFollowersView extends BaseFragment<ProfileFollowersMvp.View,
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -69,7 +69,7 @@ public class ProfileFollowingView extends BaseFragment<ProfileFollowingMvp.View,
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -73,7 +73,7 @@ public class ProfileGistsView extends BaseFragment<ProfileGistsMvp.View, Profile
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -69,7 +69,7 @@ public class ProfileReposView extends BaseFragment<ProfileReposMvp.View, Profile
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -70,7 +70,7 @@ public class ProfileStarredView extends BaseFragment<ProfileStarredMvp.View, Pro
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -72,7 +72,7 @@ public class RepoCommitsView extends BaseFragment<RepoCommitsMvp.View, RepoCommi
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -82,7 +82,7 @@ public class CommitCommentsView extends BaseFragment<CommitCommentsMvp.View, Com
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -72,7 +72,7 @@ public class RepoContributorsView extends BaseFragment<RepoContributorsMvp.View,
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -126,7 +126,7 @@ public class RepoFilesView extends BaseFragment<RepoFilesMvp.View, RepoFilesPres
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -107,7 +107,7 @@ public class RepoReleasesView extends BaseFragment<RepoReleasesMvp.View, RepoRel
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -97,7 +97,7 @@ public class RepoIssuesView extends BaseFragment<RepoIssuesMvp.View, RepoIssuesP
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -76,9 +76,11 @@ public class IssuePagerView extends BaseActivity<IssuePagerMvp.View, IssuePagerP
}
@OnClick(R.id.fab) void onAddComment() {
IssueCommentsView view = (IssueCommentsView) pager.getAdapter().instantiateItem(pager, 1);
if (view != null) {
view.onStartNewComment();
if (pager != null && pager.getAdapter() != null) {
IssueCommentsView view = (IssueCommentsView) pager.getAdapter().instantiateItem(pager, 1);
if (view != null) {
view.onStartNewComment();
}
}
}

View File

@ -83,7 +83,7 @@ public class IssueCommentsView extends BaseFragment<IssueCommentsMvp.View, Issue
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -69,7 +69,7 @@ public class IssueDetailsView extends BaseFragment<IssueDetailsMvp.View, IssueDe
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -80,7 +80,7 @@ public class RepoPullRequestView extends BaseFragment<RepoPullRequestMvp.View, R
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -74,7 +74,7 @@ public class PullRequestCommitsView extends BaseFragment<PullRequestCommitsMvp.V
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -75,7 +75,7 @@ public class PullRequestDetailsView extends BaseFragment<PullRequestDetailsMvp.V
}
@Override public void showProgress(@StringRes int msgId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -72,7 +72,7 @@ public class SearchCodeView extends BaseFragment<SearchCodeMvp.View, SearchCodeP
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -70,7 +70,7 @@ public class SearchIssuesView extends BaseFragment<SearchIssuesMvp.View, SearchI
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -70,7 +70,7 @@ public class SearchReposView extends BaseFragment<SearchReposMvp.View, SearchRep
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -69,7 +69,7 @@ public class SearchUsersView extends BaseFragment<SearchUsersMvp.View, SearchUse
}
@Override public void showProgress(@StringRes int resId) {
refresh.setRefreshing(true);
stateLayout.showProgress();
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="@color/primary_text"
android:pathData="M5,13h14v-2L5,11v2zM3,17h14v-2L3,15v2zM7,7v2h14L21,7L7,7z"/>
</vector>

View File

@ -6,7 +6,44 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/appbar_elevation_dark"/>
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
app:elevation="0dp"
app:theme="@style/ToolbarStyleDark">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_scrollFlags="scroll|enterAlways">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="?colorPrimary"
android:theme="@style/ToolbarStyleDark"
app:popupTheme="@style/ToolbarStyleDark"
app:theme="@style/ToolbarStyleDark">
<android.support.v7.widget.AppCompatSpinner
android:id="@+id/notificationType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="150dp"
android:entries="@array/notification_types"/>
</android.support.v7.widget.Toolbar>
</LinearLayout>
<View
android:id="@+id/toolbarShadow"
android:layout_width="match_parent"
android:layout_height="4dp"
android:background="@drawable/toolbar_shadow"/>
</android.support.design.widget.AppBarLayout>
<fragment
android:id="@+id/notificationFragment"

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/readAll"
android:icon="@drawable/ic_clear_all"
android:title="@string/mark_all_as_read"
app:showAsAction="ifRoom"/>
</menu>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="notification_types">
<item>@string/unread</item>
<item>@string/all</item>
</string-array>
</resources>

View File

@ -182,4 +182,8 @@
<string name="creation_date_hint">This date represent the creation date.</string>
<string name="last_updated_hint">This date represent when the last activity happened.</string>
<string name="bbn_fab_default_behavior">com.fastaccess.ui.widgets.FloatingActionButtonBehavior</string>
<string name="mark_all_as_read">Mark all as read</string>
<string name="all_notifications">All Notifications</string>
<string name="unread">Unread</string>
<string name="all">All</string>
</resources>

View File

@ -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'
}