diff --git a/app/build.gradle b/app/build.gradle index ec71259..ec1329a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -27,6 +27,16 @@ android { versionName "1.0.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } + + lintOptions { + abortOnError false + } + + packagingOptions { + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + } + buildTypes { release { minifyEnabled false @@ -82,4 +92,6 @@ dependencies { compile 'com.facebook.stetho:stetho:1.4.1' compile 'com.github.houxg:FlexLayout:1.2' compile 'com.flurry.android:analytics:6.4.2' + + compile 'net.danlew:android.joda:2.9.5' } diff --git a/app/src/main/java/org/houxg/leamonax/Leamonax.java b/app/src/main/java/org/houxg/leamonax/Leamonax.java index 076ffaa..f1dcea7 100644 --- a/app/src/main/java/org/houxg/leamonax/Leamonax.java +++ b/app/src/main/java/org/houxg/leamonax/Leamonax.java @@ -9,6 +9,8 @@ import com.flurry.android.FlurryAgent; import com.raizlabs.android.dbflow.config.FlowConfig; import com.raizlabs.android.dbflow.config.FlowManager; +import net.danlew.android.joda.JodaTimeAndroid; + import org.greenrobot.eventbus.EventBus; public class Leamonax extends Application { @@ -33,5 +35,6 @@ public class Leamonax extends Application { .installDefaultEventBus(); FlowManager.init(new FlowConfig.Builder(this).build()); Stetho.initializeWithDefaults(this); + JodaTimeAndroid.init(this); } } diff --git a/app/src/main/java/org/houxg/leamonax/service/NoteService.java b/app/src/main/java/org/houxg/leamonax/service/NoteService.java index 6f86a69..cb23556 100644 --- a/app/src/main/java/org/houxg/leamonax/service/NoteService.java +++ b/app/src/main/java/org/houxg/leamonax/service/NoteService.java @@ -208,19 +208,18 @@ public class NoteService { }, noteLocalId); } - public static boolean updateNote(final Note modifiedNote) { + public static void updateNote(final long noteLocalId) { + Note localNote = AppDataBase.getNoteByLocalId(noteLocalId); + NoteService.updateNote(localNote); + } + + private static void updateNote(final Note modifiedNote) throws IllegalStateException { Note note; if (modifiedNote.getUsn() == 0) { - note = RetrofitUtils.excute(addNote(modifiedNote)); + note = RetrofitUtils.excuteWithException(addNote(modifiedNote)); } else { - Note remoteNote = RetrofitUtils.excute(getNoteByServerId(modifiedNote.getNoteId())); - if (remoteNote == null) { - return false; - } - note = RetrofitUtils.excute(updateNote(remoteNote, modifiedNote)); - } - if (note == null) { - return false; + Note remoteNote = RetrofitUtils.excuteWithException(getNoteByServerId(modifiedNote.getNoteId())); + note = RetrofitUtils.excuteWithException(updateNote(remoteNote, modifiedNote)); } if (note.isOk()) { note.setId(modifiedNote.getId()); @@ -232,9 +231,8 @@ public class NoteService { note.save(); updateUsnIfNeed(note.getUsn()); } else { - throw new IllegalArgumentException(note.getMsg()); + throw new IllegalStateException(note.getMsg()); } - return true; } private static String convertToServerImageLinkForMD(String noteContent) { diff --git a/app/src/main/java/org/houxg/leamonax/ui/MainActivity.java b/app/src/main/java/org/houxg/leamonax/ui/MainActivity.java index eef9388..1982fb1 100644 --- a/app/src/main/java/org/houxg/leamonax/ui/MainActivity.java +++ b/app/src/main/java/org/houxg/leamonax/ui/MainActivity.java @@ -29,7 +29,6 @@ import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import org.houxg.leamonax.R; import org.houxg.leamonax.adapter.NotebookAdapter; -import org.houxg.leamonax.database.AppDataBase; import org.houxg.leamonax.model.Account; import org.houxg.leamonax.model.Note; import org.houxg.leamonax.model.Notebook; @@ -243,8 +242,6 @@ public class MainActivity extends BaseActivity implements NotebookAdapter.Notebo void clickedFab() { Account account = AccountService.getCurrent(); Note newNote = new Note(); - Notebook notebook = AppDataBase.getRecentNoteBook(account.getUserId()); - newNote.setNoteBookId(notebook.getNotebookId()); newNote.setUserId(account.getUserId()); newNote.setIsMarkDown(account.getDefaultEditor() == Account.EDITOR_MARKDOWN); newNote.save(); diff --git a/app/src/main/java/org/houxg/leamonax/ui/NotePreviewActivity.java b/app/src/main/java/org/houxg/leamonax/ui/NotePreviewActivity.java index 50e0391..b62e1b6 100644 --- a/app/src/main/java/org/houxg/leamonax/ui/NotePreviewActivity.java +++ b/app/src/main/java/org/houxg/leamonax/ui/NotePreviewActivity.java @@ -16,6 +16,7 @@ import org.houxg.leamonax.model.Note; import org.houxg.leamonax.service.NoteService; import org.houxg.leamonax.ui.edit.EditorFragment; import org.houxg.leamonax.ui.edit.NoteEditActivity; +import org.houxg.leamonax.utils.DialogDisplayer; import org.houxg.leamonax.utils.NetworkUtils; import org.houxg.leamonax.utils.ToastUtils; @@ -23,6 +24,7 @@ import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import rx.Observable; +import rx.Observer; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action0; @@ -95,16 +97,14 @@ public class NotePreviewActivity extends BaseActivity implements EditorFragment. @OnClick(R.id.tv_save) void push() { - if (!NetworkUtils.isNetworkAvailable(this)) { - ToastUtils.showNetworkUnavailable(this); - return; - } Observable.create( - new Observable.OnSubscribe() { + new Observable.OnSubscribe() { @Override - public void call(Subscriber subscriber) { + public void call(Subscriber subscriber) { if (!subscriber.isUnsubscribed()) { - subscriber.onNext(NoteService.updateNote(AppDataBase.getNoteByLocalId(mNote.getId()))); + NetworkUtils.checkNetwork(); + NoteService.updateNote(mNote.getId()); + subscriber.onNext(mNote.getId()); subscriber.onCompleted(); } } @@ -114,26 +114,27 @@ public class NotePreviewActivity extends BaseActivity implements EditorFragment. .doOnSubscribe(new Action0() { @Override public void call() { - showProgress(getString(R.string.saving_note)); + DialogDisplayer.showProgress(NotePreviewActivity.this, R.string.saving_note); } }) - .doOnCompleted(new Action0() { + .subscribe(new Observer() { @Override - public void call() { - dismissProgress(); + public void onCompleted() { + DialogDisplayer.dismissProgress(); } - }) - .subscribe(new Action1() { + @Override - public void call(Boolean isSucceed) { - if (isSucceed) { - mNote = AppDataBase.getNoteByLocalId(mNote.getId()); - mNote.setIsDirty(false); - mNote.save(); - refresh(); - } else { - ToastUtils.show(NotePreviewActivity.this, R.string.save_note_failed); - } + public void onError(Throwable e) { + DialogDisplayer.dismissProgress(); + ToastUtils.show(NotePreviewActivity.this, e.getMessage()); + } + + @Override + public void onNext(Long aLong) { + mNote = AppDataBase.getNoteByLocalId(mNote.getId()); + mNote.setIsDirty(false); + mNote.save(); + refresh(); } }); } @@ -159,13 +160,13 @@ public class NotePreviewActivity extends BaseActivity implements EditorFragment. .doOnSubscribe(new Action0() { @Override public void call() { - showProgress(getString(R.string.reverting)); + DialogDisplayer.showProgress(NotePreviewActivity.this, R.string.reverting); } }) .doOnCompleted(new Action0() { @Override public void call() { - dismissProgress(); + DialogDisplayer.dismissProgress(); } }) .subscribe(new Action1() { @@ -180,18 +181,6 @@ public class NotePreviewActivity extends BaseActivity implements EditorFragment. } - private void showProgress(String message) { - dismissProgress(); - mProgressDialog = ProgressDialog.show(NotePreviewActivity.this, "", message, false); - } - - private void dismissProgress() { - if (mProgressDialog != null && mProgressDialog.isShowing()) { - mProgressDialog.dismiss(); - mProgressDialog = null; - } - } - @Override public Uri createImage(String filePath) { return null; diff --git a/app/src/main/java/org/houxg/leamonax/ui/edit/NoteEditActivity.java b/app/src/main/java/org/houxg/leamonax/ui/edit/NoteEditActivity.java index 24ad9d9..e672df8 100644 --- a/app/src/main/java/org/houxg/leamonax/ui/edit/NoteEditActivity.java +++ b/app/src/main/java/org/houxg/leamonax/ui/edit/NoteEditActivity.java @@ -22,6 +22,7 @@ import org.houxg.leamonax.service.NoteFileService; import org.houxg.leamonax.service.NoteService; import org.houxg.leamonax.ui.BaseActivity; import org.houxg.leamonax.utils.CollectionUtils; +import org.houxg.leamonax.utils.DialogDisplayer; import org.houxg.leamonax.utils.NetworkUtils; import org.houxg.leamonax.utils.ToastUtils; import org.houxg.leamonax.widget.LeaViewPager; @@ -30,10 +31,12 @@ import java.util.ArrayList; import java.util.List; import rx.Observable; +import rx.Observer; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action0; import rx.functions.Action1; +import rx.functions.Func1; import rx.schedulers.Schedulers; //TODO: hide action bar @@ -107,31 +110,50 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi switch (item.getItemId()) { case R.id.action_save: filterUnchanged() - .doOnCompleted(new Action0() { - @Override - public void call() { - finish(); - } - }) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Action1() { + .doOnNext(new Action1() { @Override public void call(Wrapper wrapper) { saveAsDraft(wrapper); setResult(RESULT_OK); - if (NetworkUtils.isNetworkAvailable(NoteEditActivity.this)) { - boolean isSucceed = NoteService.updateNote(AppDataBase.getNoteByLocalId(wrapper.note.getId())); - if (isSucceed) { - Note localNote = AppDataBase.getNoteByLocalId(wrapper.note.getId()); - localNote.setIsDirty(false); - localNote.save(); - } else { - ToastUtils.show(NoteEditActivity.this, R.string.save_note_failed); - } - } else { - ToastUtils.showNetworkUnavailable(NoteEditActivity.this); + NetworkUtils.checkNetwork(); + } + }) + .flatMap(new Func1>() { + @Override + public Observable call(Wrapper wrapper) { + return uploadToServer(wrapper.note.getId()); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .doOnSubscribe(new Action0() { + @Override + public void call() { + DialogDisplayer.showProgress(NoteEditActivity.this, R.string.saving_note); + } + }) + .subscribe(new Observer() { + @Override + public void onCompleted() { + DialogDisplayer.dismissProgress(); + finish(); + } + + @Override + public void onError(Throwable e) { + DialogDisplayer.dismissProgress(); + ToastUtils.show(NoteEditActivity.this, e.getMessage()); + if (e instanceof NetworkUtils.NetworkUnavailableException) { + finish(); } } + + @Override + public void onNext(Long noteLocalId) { + Note localNote = AppDataBase.getNoteByLocalId(noteLocalId); + localNote.setIsDirty(false); + localNote.save(); + } }); return true; case R.id.action_settings: @@ -141,6 +163,20 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi return super.onOptionsItemSelected(item); } + private Observable uploadToServer(final long noteLocalId) { + return Observable.create( + new Observable.OnSubscribe() { + @Override + public void call(Subscriber subscriber) { + if (!subscriber.isUnsubscribed()) { + NoteService.updateNote(noteLocalId); + subscriber.onNext(noteLocalId); + subscriber.onCompleted(); + } + } + }); + } + @Override public void onBackPressed() { if (mPager.getCurrentItem() > FRAG_EDITOR) { diff --git a/app/src/main/java/org/houxg/leamonax/utils/DialogDisplayer.java b/app/src/main/java/org/houxg/leamonax/utils/DialogDisplayer.java new file mode 100644 index 0000000..afbc360 --- /dev/null +++ b/app/src/main/java/org/houxg/leamonax/utils/DialogDisplayer.java @@ -0,0 +1,25 @@ +package org.houxg.leamonax.utils; + + +import android.app.ProgressDialog; +import android.content.Context; + +public class DialogDisplayer { + private static ProgressDialog mProgressDialog; + + public static void showProgress(Context context, String message) { + dismissProgress(); + mProgressDialog = ProgressDialog.show(context, "", message, false); + } + + public static void showProgress(Context context, int messageResId) { + showProgress(context, context.getString(messageResId)); + } + + public static void dismissProgress() { + if (mProgressDialog != null && mProgressDialog.isShowing()) { + mProgressDialog.dismiss(); + mProgressDialog = null; + } + } +} diff --git a/app/src/main/java/org/houxg/leamonax/utils/NetworkUtils.java b/app/src/main/java/org/houxg/leamonax/utils/NetworkUtils.java index fe877fa..c8cf277 100644 --- a/app/src/main/java/org/houxg/leamonax/utils/NetworkUtils.java +++ b/app/src/main/java/org/houxg/leamonax/utils/NetworkUtils.java @@ -5,6 +5,9 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import org.houxg.leamonax.Leamonax; +import org.houxg.leamonax.R; + public class NetworkUtils { private static NetworkInfo getActiveNetworkInfo(Context context) { @@ -23,4 +26,16 @@ public class NetworkUtils { NetworkInfo info = getActiveNetworkInfo(context); return (info != null && info.isConnected()); } + + public static void checkNetwork() throws NetworkUnavailableException { + if (!isNetworkAvailable(Leamonax.getContext())) { + throw new NetworkUnavailableException(); + } + } + + public static class NetworkUnavailableException extends IllegalStateException { + public NetworkUnavailableException() { + super(Leamonax.getContext().getResources().getString(R.string.network_is_unavailable)); + } + } } diff --git a/app/src/main/java/org/houxg/leamonax/utils/RetrofitUtils.java b/app/src/main/java/org/houxg/leamonax/utils/RetrofitUtils.java index 78e7803..2a015cb 100644 --- a/app/src/main/java/org/houxg/leamonax/utils/RetrofitUtils.java +++ b/app/src/main/java/org/houxg/leamonax/utils/RetrofitUtils.java @@ -1,6 +1,9 @@ package org.houxg.leamonax.utils; +import org.houxg.leamonax.Leamonax; +import org.houxg.leamonax.R; + import java.io.IOException; import retrofit2.Call; @@ -50,10 +53,10 @@ public class RetrofitUtils { if (response.isSuccessful()) { return response.body(); } else { - throw new IllegalStateException("response not successful"); + throw new IllegalStateException(Leamonax.getContext().getString(R.string.network_error)); } } catch (IOException e) { - throw new IllegalStateException(e.getCause()); + throw new IllegalStateException(Leamonax.getContext().getString(R.string.network_error)); } } } diff --git a/app/src/main/java/org/houxg/leamonax/utils/TimeUtils.java b/app/src/main/java/org/houxg/leamonax/utils/TimeUtils.java index f52677c..2f6936e 100644 --- a/app/src/main/java/org/houxg/leamonax/utils/TimeUtils.java +++ b/app/src/main/java/org/houxg/leamonax/utils/TimeUtils.java @@ -1,73 +1,32 @@ package org.houxg.leamonax.utils; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; + import java.util.Calendar; -import java.util.Date; -import java.util.Locale; public class TimeUtils { - - private static final SimpleDateFormat mServerWithMillsFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.US); - private static final SimpleDateFormat mServerFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.US); - private static final SimpleDateFormat mTimeFormat = new SimpleDateFormat("H:mm:ss", Locale.US); - private static final SimpleDateFormat mDateFormat = new SimpleDateFormat("M-dd H:mm:ss", Locale.US); - private static final SimpleDateFormat mYearFormat = new SimpleDateFormat("yyyy-M-dd H:mm:ss", Locale.US); + public static final String TAG = "TimeUtils"; public static long toTimestamp(String serverTime) { - try { - serverTime = StringUtils.replace(serverTime, - "T\\d{2}:\\d{2}:\\d{2}.\\d+\\+", - "\\.\\d+", - new StringUtils.Replacer() { - @Override - public String replaceWith(String original, Object... extraData) { - String modified; - if (original.length() > 4) { - modified = original.substring(0, 4); - } else { - modified = original; - } - return modified; - } - }); - serverTime = StringUtils.replace(serverTime, - "\\+\\d+:\\d+", - "\\d+:\\d+", - new StringUtils.Replacer() { - @Override - public String replaceWith(String original, Object... extraData) { - String[] vals = original.split(":"); - return String.format(Locale.US, "%02d:%02d", Integer.valueOf(vals[0]), Integer.valueOf(vals[1])); - } - }); - Date date = mServerWithMillsFormat.parse(serverTime); - return date.getTime(); - } catch (ParseException e) { - try { - return mServerFormat.parse(serverTime).getTime(); - } catch (ParseException e1) { - e.printStackTrace(); - return -1; - } - } + return DateTime.parse(serverTime).getMillis(); } public static String toServerTime(long timeInMills) { - return mServerWithMillsFormat.format(new Date(timeInMills)); + return DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").print(timeInMills); } public static String toTimeFormat(long timeInMills) { - return mTimeFormat.format(new Date(timeInMills)); + return DateTimeFormat.forPattern("H:mm:ss").print(timeInMills); } public static String toDateFormat(long timeInMills) { - return mDateFormat.format(new Date(timeInMills)); + return DateTimeFormat.forPattern("M-dd H:mm:ss").print(timeInMills); } public static String toYearFormat(long timeInMills) { - return mYearFormat.format(new Date(timeInMills)); + return DateTimeFormat.forPattern("yyyy-M-dd H:mm:ss").print(timeInMills); } public static Calendar getToday() { diff --git a/img-selector/build.gradle b/img-selector/build.gradle index 9dcdb46..d143297 100644 --- a/img-selector/build.gradle +++ b/img-selector/build.gradle @@ -12,6 +12,11 @@ android { versionCode 7 versionName "1.2.0" } + + lintOptions { + abortOnError false + } + buildTypes { release { minifyEnabled false