preparing for notifications, added backPress handling for repo folders, added FastHub icon and removed few unused methods.
@ -93,11 +93,10 @@ dependencies {
|
||||
compile "com.google.firebase:firebase-analytics:${firebase}"
|
||||
compile "net.grandcentrix.thirtyinch:thirtyinch:${thirtyinchVersion}"
|
||||
compile "net.grandcentrix.thirtyinch:thirtyinch-rx:${thirtyinchVersion}"
|
||||
compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4'
|
||||
compile 'com.firebase:firebase-jobdispatcher:0.5.2'
|
||||
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||
compile 'de.hdodenhof:circleimageview:2.1.0'
|
||||
compile 'com.jakewharton:butterknife:8.4.0'
|
||||
compile 'org.greenrobot:eventbus:3.0.0'
|
||||
compile 'frankiesardo:icepick:3.1.0'
|
||||
compile 'it.sephiroth.android.library.bottomnavigation:bottom-navigation:1.0.7'
|
||||
compile 'pub.devrel:easypermissions:0.2.1'
|
||||
|
||||
@ -5,13 +5,14 @@
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:roundIcon="@mipmap/ic_launcher"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
@ -117,6 +118,14 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".provider.tasks.NotificationJobTask"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@ -5,6 +5,7 @@ import android.support.annotation.NonNull;
|
||||
|
||||
import com.commonsware.cwac.anddown.AndDown;
|
||||
import com.fastaccess.helper.TypeFaceHelper;
|
||||
import com.fastaccess.provider.tasks.NotificationJobTask;
|
||||
import com.fastaccess.provider.uil.UILProvider;
|
||||
import com.siimkinks.sqlitemagic.SqliteMagic;
|
||||
|
||||
@ -25,13 +26,13 @@ public class App extends Application {
|
||||
SqliteMagic.init(this);
|
||||
UILProvider.initUIL(this);
|
||||
TypeFaceHelper.generateTypeface(this);
|
||||
NotificationJobTask.scheduleJob(this);//schedule the job for the notifications
|
||||
}
|
||||
|
||||
@NonNull public static App getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
@NonNull public AndDown getAndDown() {
|
||||
if (andDown == null) {
|
||||
andDown = new AndDown();
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
package com.fastaccess.data.dao;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.siimkinks.sqlitemagic.annotation.Column;
|
||||
import com.siimkinks.sqlitemagic.annotation.Table;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Created by Kosh on 19 Feb 2017, 6:11 PM
|
||||
*/
|
||||
|
||||
@Getter @Setter @NoArgsConstructor @Table(persistAll = true)
|
||||
public class NotificationSubjectModel implements Parcelable {
|
||||
@Column String title;
|
||||
@Column String url;
|
||||
@Column String type;
|
||||
@Column String latestCommentUrl;
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.title);
|
||||
dest.writeString(this.url);
|
||||
dest.writeString(this.type);
|
||||
dest.writeString(this.latestCommentUrl);
|
||||
dest.writeLong(this.id);
|
||||
}
|
||||
|
||||
protected NotificationSubjectModel(Parcel in) {
|
||||
this.title = in.readString();
|
||||
this.url = in.readString();
|
||||
this.type = in.readString();
|
||||
this.latestCommentUrl = in.readString();
|
||||
this.id = in.readLong();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<NotificationSubjectModel> CREATOR = new Parcelable.Creator<NotificationSubjectModel>() {
|
||||
@Override public NotificationSubjectModel createFromParcel(Parcel source) {return new NotificationSubjectModel(source);}
|
||||
|
||||
@Override public NotificationSubjectModel[] newArray(int size) {return new NotificationSubjectModel[size];}
|
||||
};
|
||||
|
||||
@Override public String toString() {
|
||||
return "NotificationSubjectModel{" +
|
||||
"id=" + id +
|
||||
", title='" + title + '\'' +
|
||||
", url='" + url + '\'' +
|
||||
", type='" + type + '\'' +
|
||||
", latestCommentUrl='" + latestCommentUrl + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
package com.fastaccess.data.dao;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.fastaccess.data.dao.types.NotificationReason;
|
||||
import com.siimkinks.sqlitemagic.Delete;
|
||||
import com.siimkinks.sqlitemagic.NotificationThreadModelTable;
|
||||
import com.siimkinks.sqlitemagic.Select;
|
||||
import com.siimkinks.sqlitemagic.annotation.Column;
|
||||
import com.siimkinks.sqlitemagic.annotation.Id;
|
||||
import com.siimkinks.sqlitemagic.annotation.Table;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import rx.Completable;
|
||||
import rx.Observable;
|
||||
|
||||
/**
|
||||
* Created by Kosh on 19 Feb 2017, 6:09 PM
|
||||
*/
|
||||
|
||||
@Getter @Setter @NoArgsConstructor @Table(persistAll = true)
|
||||
public class NotificationThreadModel implements Parcelable {
|
||||
|
||||
@Column @Id(autoIncrement = false) long id;
|
||||
@Column(onDeleteCascade = true) RepoModel repository;
|
||||
@Column(onDeleteCascade = true) NotificationSubjectModel subject;
|
||||
@Column NotificationReason reason;
|
||||
@Column String url;
|
||||
@Column boolean unread;
|
||||
@Column Date updatedAt;
|
||||
@Column Date lastReadAt;
|
||||
|
||||
public Completable save() {
|
||||
return persist().observe().toCompletable();
|
||||
}
|
||||
|
||||
public static Completable save(@NonNull List<NotificationThreadModel> models) {
|
||||
return Delete.from(NotificationThreadModelTable.NOTIFICATION_THREAD_MODEL)
|
||||
.observe()
|
||||
.toCompletable()
|
||||
.andThen(persist(models).observe());
|
||||
}
|
||||
|
||||
public static Observable<List<NotificationThreadModel>> getNotifications() {
|
||||
return Select.from(NotificationThreadModelTable.NOTIFICATION_THREAD_MODEL)
|
||||
.orderBy(NotificationThreadModelTable.NOTIFICATION_THREAD_MODEL.UPDATED_AT.desc(),
|
||||
NotificationThreadModelTable.NOTIFICATION_THREAD_MODEL.UNREAD.is(false).desc())
|
||||
.observe()
|
||||
.runQuery();
|
||||
}
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeLong(this.id);
|
||||
dest.writeParcelable(this.repository, flags);
|
||||
dest.writeParcelable(this.subject, flags);
|
||||
dest.writeInt(this.reason == null ? -1 : this.reason.ordinal());
|
||||
dest.writeString(this.url);
|
||||
dest.writeValue(this.unread);
|
||||
dest.writeLong(this.updatedAt != null ? this.updatedAt.getTime() : -1);
|
||||
dest.writeLong(this.lastReadAt != null ? this.lastReadAt.getTime() : -1);
|
||||
}
|
||||
|
||||
protected NotificationThreadModel(Parcel in) {
|
||||
this.id = in.readLong();
|
||||
this.repository = in.readParcelable(RepoModel.class.getClassLoader());
|
||||
this.subject = in.readParcelable(NotificationSubjectModel.class.getClassLoader());
|
||||
int tmpReason = in.readInt();
|
||||
this.reason = tmpReason == -1 ? null : NotificationReason.values()[tmpReason];
|
||||
this.url = in.readString();
|
||||
this.unread = (Boolean) in.readValue(Boolean.class.getClassLoader());
|
||||
long tmpUpdatedAt = in.readLong();
|
||||
this.updatedAt = tmpUpdatedAt == -1 ? null : new Date(tmpUpdatedAt);
|
||||
long tmpLastReadAt = in.readLong();
|
||||
this.lastReadAt = tmpLastReadAt == -1 ? null : new Date(tmpLastReadAt);
|
||||
}
|
||||
|
||||
public static final Creator<NotificationThreadModel> CREATOR = new Creator<NotificationThreadModel>() {
|
||||
@Override public NotificationThreadModel createFromParcel(Parcel source) {return new NotificationThreadModel(source);}
|
||||
|
||||
@Override public NotificationThreadModel[] newArray(int size) {return new NotificationThreadModel[size];}
|
||||
};
|
||||
|
||||
@Override public String toString() {
|
||||
return "NotificationThreadModel{" +
|
||||
"subject=" + subject +
|
||||
", reason=" + reason +
|
||||
", unread=" + unread +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.fastaccess.data.dao.transformer;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.fastaccess.data.dao.types.NotificationReason;
|
||||
import com.siimkinks.sqlitemagic.annotation.transformer.DbValueToObject;
|
||||
import com.siimkinks.sqlitemagic.annotation.transformer.ObjectToDbValue;
|
||||
import com.siimkinks.sqlitemagic.annotation.transformer.Transformer;
|
||||
|
||||
/**
|
||||
* Created by Kosh on 11 Feb 2017, 11:43 PM
|
||||
*/
|
||||
|
||||
@Transformer public class NotificatinReasonsTransformer {
|
||||
|
||||
@ObjectToDbValue @NonNull public static String objectToDbValue(NotificationReason javaObject) {
|
||||
return javaObject == null ? NotificationReason.mention.name() : javaObject.name();
|
||||
}
|
||||
|
||||
@DbValueToObject @NonNull public static NotificationReason dbValueToObject(String dbObject) {
|
||||
return dbObject != null ? NotificationReason.valueOf(dbObject) : NotificationReason.mention;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.fastaccess.data.service;
|
||||
|
||||
import com.fastaccess.data.dao.NotificationThreadModel;
|
||||
import com.fastaccess.data.dao.Pageable;
|
||||
|
||||
import retrofit2.Response;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.PATCH;
|
||||
import retrofit2.http.Path;
|
||||
import rx.Observable;
|
||||
|
||||
/**
|
||||
* Created by Kosh on 19 Feb 2017, 6:34 PM
|
||||
*/
|
||||
|
||||
public interface NotificationService {
|
||||
|
||||
@GET("notifications") Observable<Pageable<NotificationThreadModel>> getNotifications();
|
||||
|
||||
@GET("/notifications/threads/{id}")
|
||||
Observable<NotificationThreadModel> getNotification(@Path("id") String id);
|
||||
|
||||
@PATCH("notifications/threads/{id}") Observable<Response<Boolean>> markAsRead(@Path("id") String id);
|
||||
}
|
||||
@ -1,10 +1,6 @@
|
||||
package com.fastaccess.helper;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
@ -18,37 +14,6 @@ import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
public class AppHelper {
|
||||
|
||||
@SuppressWarnings("deprecation") public static boolean isOnline(@NonNull Context context) {
|
||||
boolean haveConnectedWifi = false;
|
||||
boolean haveConnectedMobile = false;
|
||||
try {
|
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
if (isM()) {
|
||||
Network networks = cm.getActiveNetwork();
|
||||
NetworkInfo netInfo = cm.getNetworkInfo(networks);
|
||||
haveConnectedWifi = netInfo.getType() == ConnectivityManager.TYPE_WIFI && netInfo.getState().equals(NetworkInfo.State.CONNECTED);
|
||||
haveConnectedMobile = netInfo.getType() == ConnectivityManager.TYPE_MOBILE && netInfo.getState().equals(NetworkInfo.State.CONNECTED);
|
||||
} else {
|
||||
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
|
||||
for (NetworkInfo ni : netInfo) {
|
||||
if (ni.getTypeName().equalsIgnoreCase("WIFI")) {
|
||||
if (ni.isConnected())
|
||||
haveConnectedWifi = true;
|
||||
}
|
||||
if (ni.getTypeName().equalsIgnoreCase("MOBILE")) {
|
||||
if (ni.isConnected())
|
||||
haveConnectedMobile = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return haveConnectedWifi || haveConnectedMobile;
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess") public static boolean isM() {return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;}
|
||||
|
||||
public static void hideKeyboard(@NonNull View view) {
|
||||
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
||||
|
||||
@ -12,6 +12,7 @@ import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.GitHubErrorResponse;
|
||||
import com.fastaccess.data.service.GistService;
|
||||
import com.fastaccess.data.service.IssueService;
|
||||
import com.fastaccess.data.service.NotificationService;
|
||||
import com.fastaccess.data.service.PullRequestService;
|
||||
import com.fastaccess.data.service.RepoService;
|
||||
import com.fastaccess.data.service.SearchService;
|
||||
@ -162,6 +163,10 @@ public class RestProvider {
|
||||
return provideRetrofit().create(SearchService.class);
|
||||
}
|
||||
|
||||
@NonNull public static NotificationService getNotificationService() {
|
||||
return provideRetrofit().create(NotificationService.class);
|
||||
}
|
||||
|
||||
@Nullable public static GitHubErrorResponse getErrorResponse(@NonNull Throwable throwable) {
|
||||
if (throwable instanceof HttpException) {
|
||||
ResponseBody body = ((HttpException) throwable).response().errorBody();
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
package com.fastaccess.provider.tasks;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.LoginModel;
|
||||
import com.fastaccess.data.dao.NotificationThreadModel;
|
||||
import com.fastaccess.helper.BundleConstant;
|
||||
import com.fastaccess.helper.Logger;
|
||||
import com.fastaccess.provider.rest.RestProvider;
|
||||
import com.firebase.jobdispatcher.Constraint;
|
||||
import com.firebase.jobdispatcher.FirebaseJobDispatcher;
|
||||
import com.firebase.jobdispatcher.GooglePlayDriver;
|
||||
import com.firebase.jobdispatcher.Job;
|
||||
import com.firebase.jobdispatcher.JobParameters;
|
||||
import com.firebase.jobdispatcher.JobService;
|
||||
import com.firebase.jobdispatcher.Lifetime;
|
||||
import com.firebase.jobdispatcher.RetryStrategy;
|
||||
import com.firebase.jobdispatcher.Trigger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import rx.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* Created by Kosh on 19 Feb 2017, 6:32 PM
|
||||
*/
|
||||
|
||||
public class NotificationJobTask extends JobService {
|
||||
private final static String EVERY_30_MINS = "every_30_mins";
|
||||
|
||||
@Override public boolean onStartJob(JobParameters job) {
|
||||
if (LoginModel.getUser() != null) {
|
||||
RestProvider.getNotificationService()
|
||||
.getNotifications()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(item -> {
|
||||
if (item != null) onSave(item.getItems());
|
||||
}, throwable -> Logger.e(throwable.getMessage()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean onStopJob(JobParameters job) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void scheduleJob(@NonNull Context context) {
|
||||
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
|
||||
Job.Builder builder = dispatcher
|
||||
.newJobBuilder()
|
||||
.setTag(EVERY_30_MINS)
|
||||
.setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
|
||||
.setLifetime(Lifetime.FOREVER)
|
||||
.setRecurring(true)
|
||||
.setConstraints(Constraint.ON_ANY_NETWORK)
|
||||
.setTrigger(Trigger.executionWindow(10, 30 * 60 /*every 30 seconds*/))
|
||||
.setService(NotificationJobTask.class);
|
||||
dispatcher.mustSchedule(builder.build());
|
||||
}
|
||||
|
||||
private void onSave(@Nullable List<NotificationThreadModel> notificationThreadModels) {
|
||||
if (notificationThreadModels != null) {
|
||||
NotificationThreadModel.save(notificationThreadModels)
|
||||
.subscribe(() -> onNotifyUser(notificationThreadModels));
|
||||
}
|
||||
}
|
||||
|
||||
private void onNotifyUser(@NonNull List<NotificationThreadModel> notificationThreadModels) {
|
||||
long count = Stream.of(notificationThreadModels)
|
||||
.filter(NotificationThreadModel::isUnread)
|
||||
.count();
|
||||
Logger.e(count, notificationThreadModels);
|
||||
if (count > 0) {
|
||||
Context context = getApplicationContext();
|
||||
Notification notification = new NotificationCompat.Builder(context)
|
||||
.setSmallIcon(R.drawable.ic_announcement)
|
||||
.setContentTitle(context.getString(R.string.notifictions))
|
||||
.setContentText(context.getString(R.string.unread_notification))
|
||||
.setNumber((int) count)
|
||||
.addAction(R.drawable.ic_github, context.getString(R.string.open), PendingIntent.getActivity(context, 0, new Intent(),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.build();
|
||||
((NotificationManager) context.getSystemService(NOTIFICATION_SERVICE)).notify(BundleConstant.REQUEST_CODE, notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,6 +87,8 @@ public class MainView extends BaseActivity<MainMvp.View, MainPresenter> implemen
|
||||
} else if (item.getItemId() == R.id.search) {
|
||||
startActivity(new Intent(this, SearchView.class));
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.notifications) {
|
||||
//TODO
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
package com.fastaccess.ui.modules.notification;
|
||||
|
||||
/**
|
||||
* Created by Kosh on 19 Feb 2017, 7:53 PM
|
||||
*/
|
||||
|
||||
public interface NotificationsMvp {
|
||||
|
||||
}
|
||||
@ -23,6 +23,7 @@ import com.fastaccess.helper.InputHelper;
|
||||
import com.fastaccess.helper.ParseDateFormat;
|
||||
import com.fastaccess.helper.TypeFaceHelper;
|
||||
import com.fastaccess.ui.base.BaseActivity;
|
||||
import com.fastaccess.ui.modules.repos.code.RepoCodePagerView;
|
||||
import com.fastaccess.ui.modules.repos.issues.RepoIssuesPagerView;
|
||||
import com.fastaccess.ui.widgets.AvatarLayout;
|
||||
import com.fastaccess.ui.widgets.FontTextView;
|
||||
@ -245,6 +246,21 @@ public class RepoPagerView extends BaseActivity<RepoPagerMvp.View, RepoPagerPres
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override public void onBackPressed() {
|
||||
if (navType == RepoPagerMvp.CODE) {
|
||||
RepoCodePagerView codePagerView = (RepoCodePagerView) AppHelper.getFragmentByTag(getSupportFragmentManager(), RepoCodePagerView.TAG);
|
||||
if (codePagerView != null) {
|
||||
if (codePagerView.canPressBack()) {
|
||||
super.onBackPressed();
|
||||
} else {
|
||||
codePagerView.onBackPressed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
private void showHideFab() {
|
||||
if (navType == RepoPagerMvp.ISSUES) {
|
||||
fab.show();
|
||||
|
||||
@ -8,7 +8,11 @@ import com.fastaccess.ui.base.mvp.BaseMvp;
|
||||
|
||||
interface RepoCodePagerMvp {
|
||||
|
||||
interface View extends BaseMvp.FAView {}
|
||||
interface View extends BaseMvp.FAView {
|
||||
boolean canPressBack();
|
||||
|
||||
void onBackPressed();
|
||||
}
|
||||
|
||||
interface Presenter extends BaseMvp.FAPresenter {}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import com.fastaccess.helper.Bundler;
|
||||
import com.fastaccess.helper.InputHelper;
|
||||
import com.fastaccess.ui.adapter.FragmentsPagerAdapter;
|
||||
import com.fastaccess.ui.base.BaseFragment;
|
||||
import com.fastaccess.ui.modules.repos.code.files.paths.RepoFilePathView;
|
||||
import com.fastaccess.ui.widgets.ViewPagerView;
|
||||
|
||||
import butterknife.BindView;
|
||||
@ -57,4 +58,17 @@ public class RepoCodePagerView extends BaseFragment<RepoCodePagerMvp.View, RepoC
|
||||
@NonNull @Override public RepoCodePagerPresenter providePresenter() {
|
||||
return new RepoCodePagerPresenter();
|
||||
}
|
||||
|
||||
@Override public boolean canPressBack() {
|
||||
if (pager.getCurrentItem() != 1) return true;
|
||||
RepoFilePathView pathView = (RepoFilePathView) pager.getAdapter().instantiateItem(pager, 1);
|
||||
return pathView == null || pathView.canPressBack();
|
||||
}
|
||||
|
||||
@Override public void onBackPressed() {
|
||||
RepoFilePathView pathView = (RepoFilePathView) pager.getAdapter().instantiateItem(pager, 1);
|
||||
if (pathView != null) {
|
||||
pathView.onBackPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,10 @@ interface RepoFilePathMvp {
|
||||
void onAppendPath(@NonNull RepoFilesModel model);
|
||||
|
||||
void onSendData();
|
||||
|
||||
boolean canPressBack();
|
||||
|
||||
void onBackPressed();
|
||||
}
|
||||
|
||||
interface Presenter extends BaseMvp.FAPresenter,
|
||||
|
||||
@ -10,6 +10,7 @@ import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.RepoFilesModel;
|
||||
import com.fastaccess.helper.BundleConstant;
|
||||
import com.fastaccess.helper.Bundler;
|
||||
import com.fastaccess.helper.Logger;
|
||||
import com.fastaccess.ui.adapter.RepoFilePathsAdapter;
|
||||
import com.fastaccess.ui.base.BaseFragment;
|
||||
import com.fastaccess.ui.modules.repos.code.files.RepoFilesView;
|
||||
@ -52,16 +53,17 @@ public class RepoFilePathView extends BaseFragment<RepoFilePathMvp.View, RepoFil
|
||||
|
||||
@Override public void onItemClicked(@NonNull RepoFilesModel model, int position) {
|
||||
if (getRepoFilesView().isRefreshing()) return; // avoid calling for path while the other still loading...
|
||||
if ((adapter.getItemCount() - 1) > position) {
|
||||
if ((position + 1) < adapter.getItemCount()) {
|
||||
adapter.subList(position + 1, adapter.getItemCount());
|
||||
}
|
||||
getRepoFilesView().onSetData(getPresenter().getLogin(), getPresenter().getRepoId(), model.getPath());
|
||||
|
||||
}
|
||||
|
||||
@Override public void onAppendPath(@NonNull RepoFilesModel model) {
|
||||
adapter.addItem(model);
|
||||
onShowHideBackBtn();
|
||||
recycler.scrollToPosition(adapter.getItemCount() - 1); //smoothScrollToPosition(index) hides the recyclerview? WTF GOOGLE.
|
||||
recycler.scrollToPosition(adapter.getItemCount() - 1); //smoothScrollToPosition(index) hides the recyclerview? MIND-BLOWING??.
|
||||
getRepoFilesView().onSetData(getPresenter().getLogin(), getPresenter().getRepoId(), model.getPath());
|
||||
}
|
||||
|
||||
@ -69,6 +71,22 @@ public class RepoFilePathView extends BaseFragment<RepoFilePathMvp.View, RepoFil
|
||||
getRepoFilesView().onSetData(getPresenter().getLogin(), getPresenter().getRepoId(), getPresenter().getPath());
|
||||
}
|
||||
|
||||
@Override public boolean canPressBack() {
|
||||
return adapter == null || adapter.getItemCount() == 0;
|
||||
}
|
||||
|
||||
@Override public void onBackPressed() {
|
||||
int position = adapter.getItemCount() > 2 ? adapter.getItemCount() - 2 : adapter.getItemCount() - 1;
|
||||
Logger.e(position, adapter.getItemCount());
|
||||
if (position > 0 && position <= adapter.getItemCount()) {
|
||||
if (position == 1) position = 0;
|
||||
RepoFilesModel repoFilesModel = adapter.getItem(position);
|
||||
onItemClicked(repoFilesModel, position);
|
||||
} else {
|
||||
onBackClicked();
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected int fragmentLayout() {
|
||||
return R.layout.repo_file_layout;
|
||||
}
|
||||
|
||||
@ -120,7 +120,6 @@ public abstract class BaseRecyclerAdapter<M, VH extends BaseViewHolder,
|
||||
}
|
||||
|
||||
public void subList(int fromPosition, int toPosition) {
|
||||
toPosition = data.size() > toPosition ? toPosition : data.size();
|
||||
data.subList(fromPosition, toPosition).clear();
|
||||
notifyItemRangeRemoved(fromPosition, toPosition);
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM13,11h-2L11,5h2v6zM13,15h-2v-2h2v2z"/>
|
||||
|
||||
9
app/src/main/res/drawable/ic_notifications.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/>
|
||||
</vector>
|
||||
@ -2,9 +2,15 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/notifications"
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:title="@string/notifictions"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/search"
|
||||
android:icon="@drawable/ic_search"
|
||||
android:title="@string/search"
|
||||
app:showAsAction="always"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
</menu>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 9.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 14 KiB |
@ -141,4 +141,7 @@
|
||||
<string name="error_creating_issue">Error creating issue.</string>
|
||||
<string name="create_issue">Create Issue</string>
|
||||
<string name="error_highlighting_editor">Please un-select highlighting to continue editing.</string>
|
||||
<string name="notifictions">Notifications</string>
|
||||
<string name="unread_notification">You have unread notifications</string>
|
||||
<string name="open">Open</string>
|
||||
</resources>
|
||||
|
||||
BIN
art/web_hi_res_512.png
Executable file
|
After Width: | Height: | Size: 68 KiB |
@ -6,7 +6,7 @@ buildscript {
|
||||
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.0-beta4'
|
||||
classpath 'com.android.tools.build:gradle:2.3.0-rc1'
|
||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||
classpath 'com.google.gms:google-services:3.0.0'
|
||||
classpath 'me.tatarka:gradle-retrolambda:3.2.4'
|
||||
|
||||