UI overall improvements for dialogs, this commit also closes #105 where markdown now acts like real markdown.

This commit is contained in:
Kosh 2017-04-15 23:51:34 +08:00
parent d459a05dce
commit a9af25716a
44 changed files with 638 additions and 77 deletions

View File

@ -37,7 +37,10 @@ android {
signingConfig signingConfigs.signing
buildConfigString "GITHUB_CLIENT_ID", (buildProperties.secrets['github_client_id'] | buildProperties.notThere['github_client_id']).string
buildConfigString "GITHUB_SECRET", (buildProperties.secrets['github_secret'] | buildProperties.notThere['github_secret']).string
buildConfigString "IMGUR_CLIENT_ID", (buildProperties.secrets['imgur_client_id'] | buildProperties.notThere['imgur_client_id']).string
buildConfigString "IMGUR_SECRET", (buildProperties.secrets['imgur_secret'] | buildProperties.notThere['imgur_secret']).string
buildConfigField "String", "REST_URL", '"https://api.github.com/"'
buildConfigField "String", "IMGUR_URL", '"https://api.imgur.com/3/"'
buildConfigField "int", "DB_VERSION", "2"
multiDexEnabled true
}

View File

@ -0,0 +1,67 @@
package com.fastaccess.data.dao;
import android.os.Parcel;
import android.os.Parcelable;
import lombok.Getter;
import lombok.Setter;
/**
* Created by Kosh on 15 Apr 2017, 8:09 PM
*/
@Getter @Setter public class ImgurReponseModel implements Parcelable {
private boolean success;
private int status;
private ImgurImage data;
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeByte(this.success ? (byte) 1 : (byte) 0);
dest.writeInt(this.status);
dest.writeParcelable(this.data, flags);
}
public ImgurReponseModel() {}
protected ImgurReponseModel(Parcel in) {
this.success = in.readByte() != 0;
this.status = in.readInt();
this.data = in.readParcelable(ImgurImage.class.getClassLoader());
}
public static final Parcelable.Creator<ImgurReponseModel> CREATOR = new Parcelable.Creator<ImgurReponseModel>() {
@Override public ImgurReponseModel createFromParcel(Parcel source) {return new ImgurReponseModel(source);}
@Override public ImgurReponseModel[] newArray(int size) {return new ImgurReponseModel[size];}
};
@Getter @Setter public static class ImgurImage implements Parcelable {
private String title;
private String description;
private String link;
public ImgurImage() {}
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.title);
dest.writeString(this.description);
dest.writeString(this.link);
}
protected ImgurImage(Parcel in) {
this.title = in.readString();
this.description = in.readString();
this.link = in.readString();
}
public static final Creator<ImgurImage> CREATOR = new Creator<ImgurImage>() {
@Override public ImgurImage createFromParcel(Parcel source) {return new ImgurImage(source);}
@Override public ImgurImage[] newArray(int size) {return new ImgurImage[size];}
};
}
}

View File

@ -31,6 +31,7 @@ public class PayloadModel implements Parcelable {
private Comment comment;
private User target;
private User member;
private String head;
private TeamsModel team;
@Override public int describeContents() { return 0; }

View File

@ -23,7 +23,7 @@ public enum EventsType {
PullRequestReviewCommentEvent(R.string.pr_comment_review, R.drawable.ic_comment),
PullRequestReviewEvent(R.string.pr_review_event, R.drawable.ic_eye),
RepositoryEvent(R.string.repo_event, R.drawable.ic_repo),
PushEvent(R.string.pushed, R.drawable.ic_arrow_right),
PushEvent(R.string.pushed, R.drawable.ic_push),
StatusEvent(R.string.status, R.drawable.ic_info_outline),
TeamAddEvent(R.string.team_event, R.drawable.ic_profile),
DeleteEvent(R.string.deleted, R.drawable.ic_trash),

View File

@ -0,0 +1,20 @@
package com.fastaccess.data.service;
import android.support.annotation.Nullable;
import com.fastaccess.data.dao.ImgurReponseModel;
import okhttp3.RequestBody;
import retrofit2.http.Body;
import retrofit2.http.POST;
import retrofit2.http.Query;
import rx.Observable;
/**
* Created by Kosh on 15 Apr 2017, 8:06 PM
*/
public interface ImgurService {
@POST("image")
Observable<ImgurReponseModel> postImage(@Nullable @Query("title") String title, @Body RequestBody body);
}

View File

@ -23,7 +23,7 @@ import rx.Observable;
public interface NotificationService {
@GET("notifications")
Observable<Pageable<Notification>> getNotifications(@Query("page") int page);
Observable<Pageable<Notification>> getNotifications(@Query("since") String date, @Query("page") int page);
@GET("notifications?all=true")
Observable<Pageable<Notification>> getAllNotifications(@Query("page") int page);

View File

@ -1,8 +1,37 @@
package com.fastaccess.helper;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* Created by kosh20111 on 10/7/2015. CopyRights @ Innov8tif
*/
public class FileHelper {
public static final long ONE_MB = 1048576L;
@Nullable public static String getPath(@NonNull Context context, @NonNull Uri uri) {
String filePath = null;
String wholeID = DocumentsContract.getDocumentId(uri);
String id = wholeID.split(":")[1];
String[] column = {MediaStore.Images.Media.DATA};
String sel = MediaStore.Images.Media._ID + "=?";
try (Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{id}, null)) {
if (cursor != null) {
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
}
}
Logger.e(filePath);
return filePath;
}
}

View File

@ -15,51 +15,51 @@ import android.widget.TextView;
public class InputHelper {
private static boolean isWhiteSpaces(String s) {
private static boolean isWhiteSpaces(@Nullable String s) {
return s != null && s.matches("\\s+");
}
public static boolean isEmpty(String text) {
public static boolean isEmpty(@Nullable String text) {
return text == null || TextUtils.isEmpty(text) || isWhiteSpaces(text) || text.equalsIgnoreCase("null");
}
public static boolean isEmpty(Object text) {
public static boolean isEmpty(@Nullable Object text) {
return text == null || isEmpty(text.toString());
}
public static boolean isEmpty(EditText text) {
public static boolean isEmpty(@Nullable EditText text) {
return text == null || isEmpty(text.getText().toString());
}
public static boolean isEmpty(TextView text) {
public static boolean isEmpty(@Nullable TextView text) {
return text == null || isEmpty(text.getText().toString());
}
public static boolean isEmpty(TextInputLayout txt) {
public static boolean isEmpty(@Nullable TextInputLayout txt) {
return txt == null || isEmpty(txt.getEditText());
}
public static String toString(EditText editText) {
public static String toString(@NonNull EditText editText) {
return editText.getText().toString();
}
public static String toString(TextView editText) {
public static String toString(@NonNull TextView editText) {
return editText.getText().toString();
}
public static String toString(TextInputLayout textInputLayout) {
return toString(textInputLayout.getEditText());
public static String toString(@NonNull TextInputLayout textInputLayout) {
return textInputLayout.getEditText() != null ? toString(textInputLayout.getEditText()) : "";
}
public static String toNA(@Nullable String value) {
@NonNull public static String toNA(@Nullable String value) {
return isEmpty(value) ? "N/A" : value;
}
@NonNull public static String toString(@NonNull Object object) {
@NonNull public static String toString(@Nullable Object object) {
return !isEmpty(object) ? object.toString() : "";
}
public static long toLong(TextView textView) {
public static long toLong(@NonNull TextView textView) {
if (!isEmpty(textView)) {
try {
return Long.valueOf(toString(textView).replace(".", "").replaceAll(",", ""));

View File

@ -7,6 +7,7 @@ import android.text.format.DateUtils;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
@ -58,4 +59,16 @@ public class ParseDateFormat {
@NonNull private static ParseDateFormat getInstance() {
return INSTANCE;
}
public static String getDateByDays(int days) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
cal.add(Calendar.DAY_OF_YEAR, days);
return s.format(new Date(cal.getTimeInMillis()));
}
public static String getLastWeekDate() {
return getDateByDays(-7);
}
}

View File

@ -131,7 +131,10 @@ public class PrefGetter {
public static long getNotificationTaskDuration(@NonNull Context context) {
String prefValue = PrefHelper.getString("notificationTime");
return notificationDurationMillis(context, prefValue);
if (prefValue != null) {
return notificationDurationMillis(context, prefValue);
}
return 0;
}
public static long notificationDurationMillis(@NonNull Context context, @NonNull String prefValue) {

View File

@ -17,12 +17,6 @@ public class RxHelper {
.observeOn(AndroidSchedulers.mainThread());
}
public static <T> Observable<T> getObserverComputation(@NonNull Observable<T> observable) {
return observable
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread());
}
public static <T> Observable<T> safeObservable(@NonNull Observable<T> observable) {
return getObserver(observable)
.subscribeOn(Schedulers.io())

View File

@ -177,19 +177,27 @@ public class MarkDownProvider {
}
public static void addPhoto(@NonNull EditText editText) {
addLink(editText, "", "");
}
public static void addPhoto(@NonNull EditText editText, @NonNull String title, @NonNull String link) {
int selectionStart = editText.getSelectionStart();
String result = "![]()\n";
String result = "![" + InputHelper.toString(title) + "](" + InputHelper.toString(link) + ")\n";
int length = selectionStart + result.length();
editText.getText().insert(selectionStart, result);
editText.setSelection(length - 2);
editText.setSelection(length);
}
public static void addLink(@NonNull EditText editText) {
addLink(editText, "", "");
}
public static void addLink(@NonNull EditText editText, @NonNull String title, @NonNull String link) {
int selectionStart = editText.getSelectionStart();
String result = "[]()\n";
String result = "[" + InputHelper.toString(title) + "](" + InputHelper.toString(link) + ")\n";
int length = selectionStart + result.length();
editText.getText().insert(selectionStart, result);
editText.setSelection(length - 2);
editText.setSelection(length);
}
private static boolean hasNewLine(@NonNull String source, int selectionStart) {

View File

@ -0,0 +1,62 @@
package com.fastaccess.provider.rest;
import android.support.annotation.NonNull;
import com.fastaccess.BuildConfig;
import com.fastaccess.data.service.ImgurService;
import com.fastaccess.provider.rest.converters.GithubResponseConverter;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.lang.reflect.Modifier;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
/**
* Created by Kosh on 15 Apr 2017, 7:59 PM
*/
public class ImgurProvider {
public final static Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC)
.setPrettyPrinting()
.create();
private ImgurProvider() {}
private static OkHttpClient provideOkHttpClient() {
OkHttpClient.Builder client = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
client.addInterceptor(new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY));
}
client.addInterceptor(chain -> {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder();
requestBuilder.header("Authorization", "Client-ID " + BuildConfig.IMGUR_CLIENT_ID);
requestBuilder.method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
});
return client.build();
}
private static Retrofit provideRetrofit() {
return new Retrofit.Builder()
.baseUrl(BuildConfig.IMGUR_URL)
.client(provideOkHttpClient())
.addConverterFactory(new GithubResponseConverter(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
@NonNull public static ImgurService getImgurService() {
return provideRetrofit().create(ImgurService.class);
}
}

View File

@ -25,6 +25,7 @@ import com.fastaccess.data.dao.model.Notification;
import com.fastaccess.helper.AppHelper;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.Logger;
import com.fastaccess.helper.ParseDateFormat;
import com.fastaccess.helper.PrefGetter;
import com.fastaccess.helper.RxHelper;
import com.fastaccess.provider.rest.RestProvider;
@ -47,7 +48,7 @@ public class NotificationSchedulerJobTask extends JobService {
@Override public boolean onStartJob(JobParameters job) {
if (Login.getUser() != null) {
RestProvider.getNotificationService()
.getNotifications(0)
.getNotifications(ParseDateFormat.getLastWeekDate(), 0)
.subscribeOn(Schedulers.io())
.subscribe(item -> {
AppHelper.cancelAllNotifications(getApplicationContext());

View File

@ -55,6 +55,7 @@ import butterknife.ButterKnife;
import es.dmoral.toasty.Toasty;
import icepick.Icepick;
import icepick.State;
import rx.Subscription;
/**
* Created by Kosh on 24 May 2016, 8:48 PM
@ -63,6 +64,7 @@ import icepick.State;
public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePresenter<V>> extends AdActivity<V, P> implements
BaseMvp.FAView, NavigationView.OnNavigationItemSelectedListener {
private Subscription themeSubscription;
@State boolean isProgressShowing;
@Nullable @BindView(R.id.toolbar) Toolbar toolbar;
@Nullable @BindView(R.id.appbar) AppBarLayout shadowView;

View File

@ -15,7 +15,9 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.fastaccess.R;
import com.fastaccess.helper.AnimHelper;
import com.fastaccess.helper.AppHelper;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
@ -58,6 +60,7 @@ public abstract class BaseDialogFragment<V extends BaseMvp.FAView, P extends Bas
@Override public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_TITLE, AppHelper.isNightMode(getResources()) ? R.style.DialogThemeDark : R.style.DialogThemeLight);
if (savedInstanceState != null && !savedInstanceState.isEmpty()) {
Icepick.restoreInstanceState(this, savedInstanceState);
}

View File

@ -20,6 +20,7 @@ import com.fastaccess.helper.PrefGetter;
import com.fastaccess.helper.ViewHelper;
import com.fastaccess.provider.markdown.MarkDownProvider;
import com.fastaccess.ui.base.BaseActivity;
import com.fastaccess.ui.modules.editor.popup.EditorLinkImageDialogFragment;
import com.fastaccess.ui.widgets.FontEditText;
import com.fastaccess.ui.widgets.ForegroundImageView;
import com.fastaccess.ui.widgets.dialog.MessageDialogView;
@ -96,7 +97,13 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
Snackbar.make(editText, R.string.error_highlighting_editor, Snackbar.LENGTH_SHORT).show();
return;
}
getPresenter().onActionClicked(editText, v.getId());
if (v.getId() == R.id.link) {
EditorLinkImageDialogFragment.newInstance(true).show(getSupportFragmentManager(), "EditorLinkImageDialogFragment");
} else if (v.getId() == R.id.image) {
EditorLinkImageDialogFragment.newInstance(false).show(getSupportFragmentManager(), "EditorLinkImageDialogFragment");
} else {
getPresenter().onActionClicked(editText, v.getId());
}
}
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -198,4 +205,12 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
finish();
}
}
@Override public void onAppendLink(@Nullable String title, @Nullable String link, boolean isLink) {
if (isLink) {
MarkDownProvider.addLink(editText, InputHelper.toString(title), InputHelper.toString(link));
} else {
MarkDownProvider.addPhoto(editText, InputHelper.toString(title), InputHelper.toString(link));
}
}
}

View File

@ -8,6 +8,7 @@ import android.widget.EditText;
import com.fastaccess.data.dao.model.Comment;
import com.fastaccess.helper.BundleConstant;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.modules.editor.popup.EditorLinkImageMvp;
/**
* Created by Kosh on 27 Nov 2016, 1:31 AM
@ -15,7 +16,7 @@ import com.fastaccess.ui.base.mvp.BaseMvp;
interface EditorMvp {
interface View extends BaseMvp.FAView {
interface View extends BaseMvp.FAView, EditorLinkImageMvp.EditorLinkCallback {
void onSendResultAndFinish(@NonNull Comment commentModel, boolean isNew);
void onSendMarkDownResult();

View File

@ -0,0 +1,115 @@
package com.fastaccess.ui.modules.editor.popup;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.view.View;
import com.fastaccess.R;
import com.fastaccess.helper.ActivityHelper;
import com.fastaccess.helper.BundleConstant;
import com.fastaccess.helper.Bundler;
import com.fastaccess.helper.FileHelper;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.ui.base.BaseDialogFragment;
import com.fastaccess.ui.widgets.FontButton;
import java.io.File;
import butterknife.BindView;
import butterknife.OnClick;
/**
* Created by Kosh on 15 Apr 2017, 9:14 PM
*/
public class EditorLinkImageDialogFragment extends BaseDialogFragment<EditorLinkImageMvp.View, EditorLinkImagePresenter>
implements EditorLinkImageMvp.View {
private EditorLinkImageMvp.EditorLinkCallback callback;
@BindView(R.id.title) TextInputLayout title;
@BindView(R.id.link) TextInputLayout link;
@BindView(R.id.select) FontButton select;
public static EditorLinkImageDialogFragment newInstance(boolean isLink) {
EditorLinkImageDialogFragment fragment = new EditorLinkImageDialogFragment();
fragment.setArguments(Bundler
.start()
.put(BundleConstant.YES_NO_EXTRA, isLink)
.end());
return fragment;
}
@Override public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof EditorLinkImageMvp.EditorLinkCallback) {
callback = (EditorLinkImageMvp.EditorLinkCallback) context;
}
}
@Override public void onDetach() {
callback = null;
super.onDetach();
}
@Override public void onUploaded(@Nullable String title, @Nullable String link) {
hideProgress();
if (callback != null) {
callback.onAppendLink(title, link, isLink());
}
dismiss();
}
@Override protected int fragmentLayout() {
return R.layout.markdown_link_image_dialog_layout;
}
@Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
select.setVisibility(isLink() ? View.GONE : View.VISIBLE);
}
@NonNull @Override public EditorLinkImagePresenter providePresenter() {
return new EditorLinkImagePresenter();
}
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == BundleConstant.REQUEST_CODE) {
if (data != null && data.getData() != null) {
String path = FileHelper.getPath(getContext(), data.getData());
if (!InputHelper.isEmpty(path)) {
getPresenter().onSubmit(InputHelper.toString(title), new File(path));
}
}
}
}
@OnClick(R.id.select) public void onSelectClicked() {
if (ActivityHelper.checkAndRequestReadWritePermission(getActivity())) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, getString(R.string.select_picture)), BundleConstant.REQUEST_CODE);
}
}
@OnClick(R.id.cancel) public void onCancelClicked() {
dismiss();
}
@OnClick(R.id.insert) public void onInsertClicked() {
if (callback != null) {
callback.onAppendLink(InputHelper.toString(title), InputHelper.toString(link), isLink());
}
dismiss();
}
private boolean isLink() {
return getArguments() != null && getArguments().getBoolean(BundleConstant.YES_NO_EXTRA);
}
}

View File

@ -0,0 +1,27 @@
package com.fastaccess.ui.modules.editor.popup;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.fastaccess.ui.base.mvp.BaseMvp;
import java.io.File;
/**
* Created by Kosh on 15 Apr 2017, 9:06 PM
*/
public interface EditorLinkImageMvp {
interface EditorLinkCallback {
void onAppendLink(@Nullable String title, @Nullable String link, boolean isLink);
}
interface View extends BaseMvp.FAView {
void onUploaded(@Nullable String title, @Nullable String link);
}
interface Presenter {
void onSubmit(@Nullable String title, @NonNull File file);
}
}

View File

@ -0,0 +1,36 @@
package com.fastaccess.ui.modules.editor.popup;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.fastaccess.data.dao.ImgurReponseModel;
import com.fastaccess.provider.rest.ImgurProvider;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
import java.io.File;
import okhttp3.MediaType;
import okhttp3.RequestBody;
/**
* Created by Kosh on 15 Apr 2017, 9:08 PM
*/
public class EditorLinkImagePresenter extends BasePresenter<EditorLinkImageMvp.View> implements EditorLinkImageMvp.Presenter {
@Override public void onSubmit(@Nullable String title, @NonNull File file) {
if (file.exists()) {
RequestBody image = RequestBody.create(MediaType.parse("image/*"), file);
makeRestCall(ImgurProvider.getImgurService().postImage(title, image),
imgurReponseModel -> {
if (imgurReponseModel.getData() != null) {
ImgurReponseModel.ImgurImage imageResponse = imgurReponseModel.getData();
sendToView(view -> view.onUploaded(title == null ? imageResponse.getTitle() : title, imageResponse.getLink()));
return;
}
sendToView(view -> view.onUploaded(null, null));
});
} else {
if (getView() != null) getView().onUploaded(null, null);
}
}
}

View File

@ -1,5 +1,6 @@
package com.fastaccess.ui.modules.feeds;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -19,6 +20,7 @@ import com.fastaccess.provider.rest.RestProvider;
import com.fastaccess.provider.scheme.SchemeParser;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
import com.fastaccess.ui.modules.repos.RepoPagerActivity;
import com.fastaccess.ui.modules.repos.code.commit.details.CommitPagerActivity;
import java.util.ArrayList;
@ -108,7 +110,14 @@ class FeedsPresenter extends BasePresenter<FeedsMvp.View> implements FeedsMvp.Pr
} else {
PayloadModel payloadModel = item.getPayload();
if (payloadModel != null) {
if (item.getPayload().getIssue() != null) {
if (payloadModel.getHead() != null) {
Repo repoModel = item.getRepo();
Uri uri = Uri.parse(repoModel.getName());
if (uri == null || uri.getPathSegments().size() < 1) return;
Intent intent = CommitPagerActivity.createIntent(v.getContext(), uri.getLastPathSegment(), uri.getPathSegments().get(0),
payloadModel.getHead(), true);
v.getContext().startActivity(intent);
} else if (item.getPayload().getIssue() != null) {
SchemeParser.launchUri(v.getContext(), Uri.parse(item.getPayload().getIssue().getHtmlUrl()), true);
} else if (item.getPayload().getPullRequest() != null) {
SchemeParser.launchUri(v.getContext(), Uri.parse(item.getPayload().getPullRequest().getHtmlUrl()), true);

View File

@ -12,6 +12,7 @@ import com.fastaccess.R;
import com.fastaccess.ui.adapter.UsersAdapter;
import com.fastaccess.ui.base.BaseDialogFragment;
import com.fastaccess.ui.widgets.StateLayout;
import com.fastaccess.ui.widgets.dialog.MessageDialogView;
import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView;
import butterknife.BindView;
@ -38,19 +39,20 @@ public class OrgListDialogFragment extends BaseDialogFragment<OrgListDialogMvp.V
adapter.notifyDataSetChanged();
}
@Override public void onNoOrgs() {
hideProgress();
stateLayout.hideReload();
stateLayout.setEmptyText(getString(R.string.no_orgs_description));
stateLayout.showEmptyState();
}
@Override protected int fragmentLayout() {
return R.layout.milestone_dialog_layout;
}
@Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
toolbar.setTitle(R.string.organizations);
toolbar.inflateMenu(R.menu.add_menu);
toolbar.getMenu().findItem(R.id.add).setIcon(R.drawable.ic_info_outline)
.setTitle(R.string.no_orgs);
toolbar.setOnMenuItemClickListener(item -> {
MessageDialogView.newInstance(getString(R.string.no_orgs), getString(R.string.no_orgs_description))
.show(getChildFragmentManager(), MessageDialogView.TAG);
return true;
});
toolbar.setNavigationIcon(R.drawable.ic_clear);
toolbar.setNavigationOnClickListener(v -> dismiss());
stateLayout.setEmptyText(R.string.no_orgs);

View File

@ -16,7 +16,6 @@ public interface OrgListDialogMvp {
interface View extends BaseMvp.FAView {
void onNotifyAdapter();
void onNoOrgs();
}
interface Presenter {

View File

@ -22,11 +22,9 @@ public class OrgListDialogPresenter extends BasePresenter<OrgListDialogMvp.View>
if (userPageable.getItems() != null && !userPageable.getItems().isEmpty()) {
orgs.clear();
orgs.addAll(userPageable.getItems());
sendToView(OrgListDialogMvp.View::onNotifyAdapter);
return;
}
}
sendToView(OrgListDialogMvp.View::onNoOrgs);
sendToView(OrgListDialogMvp.View::onNotifyAdapter);
});
}

View File

@ -9,6 +9,7 @@ import android.view.View;
import com.fastaccess.data.dao.Pageable;
import com.fastaccess.data.dao.model.Notification;
import com.fastaccess.helper.BundleConstant;
import com.fastaccess.helper.ParseDateFormat;
import com.fastaccess.helper.PrefGetter;
import com.fastaccess.helper.RxHelper;
import com.fastaccess.provider.rest.RestProvider;
@ -118,7 +119,7 @@ public class NotificationsPresenter extends BasePresenter<NotificationsMvp.View>
setCurrentPage(page);
Observable<Pageable<Notification>> observable =
showAll ? RestProvider.getNotificationService().getAllNotifications(page)
: RestProvider.getNotificationService().getNotifications(page);
: RestProvider.getNotificationService().getNotifications(ParseDateFormat.getDateByDays(-30), page);
makeRestCall(observable, response -> {
if (response.getItems() != null) {
lastPage = response.getLast();

View File

@ -74,8 +74,8 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Prefer
restartActivity();
return true;
} else if (preference.getKey().equalsIgnoreCase("appTheme")) {
restartActivity();
Toasty.warning(getContext(), getString(R.string.change_theme_warning), Toast.LENGTH_LONG).show();
restartActivity();
return true;
}
return false;

View File

@ -30,10 +30,10 @@ public class RoundBackgroundSpan extends ReplacementSpan {
public void draw(@NonNull Canvas canvas, @NonNull CharSequence charSequence,
int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
paint.setColor(color);
rectF.set(x, top, width + x, bottom);
rectF.set(x, top, width + x, bottom - 20);
canvas.drawRoundRect(rectF, 5, 5, paint);
paint.setColor(ViewHelper.generateTextColor(color));
canvas.drawText(charSequence, start, end, x + (5 * 2.0f), (float) y, paint);
canvas.drawText(charSequence, start, end, x + (5 * 2.0f), (float) y - 5, paint);
}
}

View File

@ -62,7 +62,7 @@ public class GithubHelper {
}
String link;
if (!InputHelper.isEmpty(MimeTypeMap.getFileExtensionFromUrl(href))) {
link = "https://raw.githubusercontent.com/" + owner + "/" + repoName + "/master/" + href;
link = "https://raw.githubusercontent.com/" + owner + "/" + repoName + "/master/" + href; //assuming always master is bad :'(
} else {
String formattedLink = href.replaceFirst("./", "/");
link = "https://api.github.com/repos/" + owner + "/" + repoName +
@ -84,7 +84,7 @@ public class GithubHelper {
"\n" +
"<body>\n" +
source +
(!wrap ? "\n<script src=\"./intercept-touch.js\"></script>\n" : "") +
(!wrap ? "\n<script src=\"./intercept-touch.js\"></script>\n" : "\n") +
HASH_LINK_SCRIPT + "\n" +
"</body>\n" +
"\n" +

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="16.0"
android:viewportWidth="14.0">
<path
android:fillColor="?icon_color"
android:pathData="M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z"/>
</vector>

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="?icon_color"
android:pathData="M5,4v3h5.5v12h3V7H19V4z"/>
</vector>

View File

@ -5,7 +5,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:minWidth="300dp"
android:orientation="vertical"
android:paddingBottom="@dimen/spacing_xs_large">

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/spacing_xs_large">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.fastaccess.ui.widgets.ForegroundImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:contentDescription="@string/title"
android:padding="@dimen/spacing_normal"
android:src="@drawable/ic_title"/>
<android.support.design.widget.TextInputLayout
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:hintTextAppearance="@style/TextAppearance.AppCompat.Title">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/title"
android:inputType="textCapSentences"
android:maxLines="1"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_normal"
android:orientation="horizontal">
<com.fastaccess.ui.widgets.ForegroundImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:contentDescription="@string/title"
android:padding="@dimen/spacing_normal"
android:src="@drawable/ic_insert_link"/>
<android.support.design.widget.TextInputLayout
android:id="@+id/link"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:hintTextAppearance="@style/TextAppearance.AppCompat.Title"
app:passwordToggleEnabled="false">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/link"
android:inputType="textWebEditText"
android:maxLines="1"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.fastaccess.ui.widgets.FontButton
android:id="@+id/select"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="@string/select"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:textColor="@color/material_orange_accent_400"
android:visibility="gone"
tools:visibility="visible"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end">
<com.fastaccess.ui.widgets.FontButton
android:id="@+id/cancel"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:text="@string/cancel"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:textColor="@color/material_pink_700"/>
<com.fastaccess.ui.widgets.FontButton
android:id="@+id/insert"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:text="@string/insert"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:textColor="?colorAccent"/>
</LinearLayout>
</FrameLayout>
</LinearLayout>

View File

@ -6,7 +6,6 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_xs_large"
android:layout_marginTop="@dimen/spacing_xs_large"
android:minWidth="300dp"
android:orientation="vertical"
android:padding="@dimen/spacing_xs_large">

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/windowBackground"
@ -9,13 +8,7 @@
<include layout="@layout/appbar_elevation_dark"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="300dp"
app:layout_behavior="@string/scroll_behavior">
<include layout="@layout/vertical_refresh_list"/>
<include layout="@layout/vertical_refresh_list"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>

View File

@ -8,8 +8,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="@dimen/spacing_s_large"
android:gravity="center"
android:minHeight="250dp"
android:orientation="vertical">
<com.fastaccess.ui.widgets.FontTextView

View File

@ -6,7 +6,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:minWidth="300dp"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
@ -77,12 +76,10 @@
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
app:layoutManager="@string/linear_layout_manager"
tools:listitem="@layout/simple_row_item"/>
app:layoutManager="@string/linear_layout_manager"/>
</LinearLayout>

View File

@ -4,7 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:orientation="vertical">
@ -13,7 +13,6 @@
style="@style/TextAppearance.AppCompat.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="300dp"
android:padding="@dimen/spacing_xs_large"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"

View File

@ -58,6 +58,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:lineSpacingExtra="@dimen/spacing_normal"
android:ellipsize="end"
android:maxLines="5"
tools:text="For a divided large loaf, add some champaign and cinnamon."/>

View File

@ -67,9 +67,9 @@
<item android:title="@string/action">
<menu>
<!--<item-->
<!--android:id="@+id/settings"-->
<!--android:icon="@drawable/ic_settings"-->
<!--android:title="@string/settings"/>-->
<!--android:id="@+id/settings"-->
<!--android:icon="@drawable/ic_settings"-->
<!--android:title="@string/settings"/>-->
<item
android:id="@+id/logout"

View File

@ -373,4 +373,7 @@
below.\nhttps://help.github.com/articles/about-third-party-application-restrictions\nPS: The reason FastHub didn\'t use "Access Token" was
due to the fact that if one has 2fa enabled, their OTP code lifetime could only survive for a maximum of one minute or so, which will cause
FastHub to log you out immediately due to GitHub responded with an unauthorized access.</string>
<string name="insert">Insert</string>
<string name="select">Select</string>
<string name="select_picture">Select Picture</string>
</resources>

View File

@ -36,6 +36,7 @@
<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowContentTransitions">true</item>
<item name="android:dialogTheme">@style/DialogThemeDark</item>
<item name="android:alertDialogTheme">@style/DialogThemeDark</item>
<item name="android:toolbarStyle">@style/ToolbarStyleDark</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
</style>
@ -45,6 +46,11 @@
<item name="android:textColorPrimary">@color/white</item>
<item name="colorControlNormal">@color/white</item>
<item name="colorControlHighlight">?colorAccent</item>
<item name="popupTheme">@style/PopupThemeDark</item>
</style>
<style name="PopupThemeDark" parent="ThemeOverlay.AppCompat">
<item name="android:colorBackground">@color/darkWindowBackground</item>
</style>
<style name="TimeLineBackgroundDark">
@ -52,9 +58,10 @@
<item name="android:backgroundTint">#2D3035</item>
</style>
<style name="DialogThemeDark" parent="@style/Theme.AppCompat.Dialog">
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
<style name="DialogThemeDark" parent="Theme.AppCompat.Dialog.Alert">
<item name="colorPrimary">#2D3035</item>
<item name="colorPrimaryDark">#26282C</item>
<item name="colorAccent">#2196F3</item>
<item name="android:windowBackground">@color/darkWindowBackground</item>
</style>
@ -67,4 +74,5 @@
<item name="mal_color_primary">#fff</item>
<item name="mal_color_secondary">#ffe0e0e0</item>
</style>
</resources>

View File

@ -37,6 +37,7 @@
<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowContentTransitions">true</item>
<item name="android:dialogTheme">@style/DialogThemeLight</item>
<item name="android:alertDialogTheme">@style/DialogThemeLight</item>
<item name="android:toolbarStyle">@style/ToolbarStyleLight</item>
</style>
@ -44,6 +45,11 @@
<item name="android:textColorPrimary">@color/black</item>
<item name="colorControlNormal">@color/black</item>
<item name="colorControlHighlight">?colorAccent</item>
<item name="popupTheme">@style/PopupThemeLight</item>
</style>
<style name="PopupThemeLight" parent="ThemeOverlay.AppCompat.Light">
<item name="android:colorBackground">@color/lightWindowBackground</item>
</style>
<style name="TimeLineBackgroundLight">
@ -51,9 +57,10 @@
</style>
<style name="DialogThemeLight" parent="@style/Theme.AppCompat.Light.Dialog">
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
<style name="DialogThemeLight" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="colorPrimary">#F5F5F5</item>
<item name="colorPrimaryDark">#E0E0E0</item>
<item name="colorAccent">#2962FF</item>
<item name="android:windowBackground">@color/lightWindowBackground</item>
</style>

View File

@ -3,4 +3,6 @@ android_store_password=PASSWORD
android_key_password=PASSWORD
android_key_alias=ALIAS
github_client_id=GITHUB_CLIENT_ID
github_secret=GITHUB_SECRET
github_secret=GITHUB_SECRET
imgur_client_id=imgur_client_id
imgur_secret=imgur_secret