mirror of
https://github.com/leanote/leanote-android.git
synced 2025-10-19 00:44:08 +00:00
apply noteFragment in SearchActivity; add pull to push
This commit is contained in:
@@ -59,6 +59,7 @@ public class NoteSyncService extends Service {
|
|||||||
public void call(Subscriber<? super Void> subscriber) {
|
public void call(Subscriber<? super Void> subscriber) {
|
||||||
if (!subscriber.isUnsubscribed()) {
|
if (!subscriber.isUnsubscribed()) {
|
||||||
NoteService.fetchFromServer();
|
NoteService.fetchFromServer();
|
||||||
|
NoteService.pushToServer();
|
||||||
subscriber.onNext(null);
|
subscriber.onNext(null);
|
||||||
subscriber.onCompleted();
|
subscriber.onCompleted();
|
||||||
}
|
}
|
||||||
|
@@ -49,7 +49,6 @@ public class NoteDataStore {
|
|||||||
return SQLite.select()
|
return SQLite.select()
|
||||||
.from(Note.class)
|
.from(Note.class)
|
||||||
.where(Note_Table.userId.eq(userId))
|
.where(Note_Table.userId.eq(userId))
|
||||||
.and(Note_Table.isTrash.eq(false))
|
|
||||||
.and(Note_Table.isDeleted.eq(false))
|
.and(Note_Table.isDeleted.eq(false))
|
||||||
.and(Note_Table.isTrash.eq(false))
|
.and(Note_Table.isTrash.eq(false))
|
||||||
.queryList();
|
.queryList();
|
||||||
@@ -59,9 +58,7 @@ public class NoteDataStore {
|
|||||||
return SQLite.select()
|
return SQLite.select()
|
||||||
.from(Note.class)
|
.from(Note.class)
|
||||||
.where(Note_Table.userId.eq(userId))
|
.where(Note_Table.userId.eq(userId))
|
||||||
.and(Note_Table.isTrash.eq(false))
|
|
||||||
.and(Note_Table.isDeleted.eq(false))
|
.and(Note_Table.isDeleted.eq(false))
|
||||||
.and(Note_Table.isTrash.eq(false))
|
|
||||||
.and(Note_Table.isDirty.eq(true))
|
.and(Note_Table.isDirty.eq(true))
|
||||||
.queryList();
|
.queryList();
|
||||||
}
|
}
|
||||||
@@ -75,7 +72,6 @@ public class NoteDataStore {
|
|||||||
.from(Note.class)
|
.from(Note.class)
|
||||||
.where(Note_Table.notebookId.eq(notebook.getNotebookId()))
|
.where(Note_Table.notebookId.eq(notebook.getNotebookId()))
|
||||||
.and(Note_Table.userId.eq(userId))
|
.and(Note_Table.userId.eq(userId))
|
||||||
.and(Note_Table.isTrash.eq(false))
|
|
||||||
.and(Note_Table.isDeleted.eq(false))
|
.and(Note_Table.isDeleted.eq(false))
|
||||||
.and(Note_Table.isTrash.eq(false))
|
.and(Note_Table.isTrash.eq(false))
|
||||||
.queryList();
|
.queryList();
|
||||||
|
@@ -96,7 +96,6 @@ public class Note extends BaseModel implements Serializable {
|
|||||||
long publicTime;
|
long publicTime;
|
||||||
@Column(name = "tags")
|
@Column(name = "tags")
|
||||||
String tags = "";
|
String tags = "";
|
||||||
boolean uploadSucc = true;
|
|
||||||
|
|
||||||
public long getCreatedTimeVal() {
|
public long getCreatedTimeVal() {
|
||||||
return createdTime;
|
return createdTime;
|
||||||
@@ -174,14 +173,6 @@ public class Note extends BaseModel implements Serializable {
|
|||||||
return usn;
|
return usn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUploadSucc() {
|
|
||||||
return uploadSucc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUploadSucc(boolean uploadSucc) {
|
|
||||||
this.uploadSucc = uploadSucc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsn(int usn) {
|
public void setUsn(int usn) {
|
||||||
this.usn = usn;
|
this.usn = usn;
|
||||||
}
|
}
|
||||||
|
@@ -38,6 +38,7 @@ import okhttp3.MediaType;
|
|||||||
import okhttp3.MultipartBody;
|
import okhttp3.MultipartBody;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
public class NoteService {
|
public class NoteService {
|
||||||
|
|
||||||
@@ -48,6 +49,15 @@ public class NoteService {
|
|||||||
private static final String CONFLICT_SUFFIX = "--conflict";
|
private static final String CONFLICT_SUFFIX = "--conflict";
|
||||||
private static final int MAX_ENTRY = 20;
|
private static final int MAX_ENTRY = 20;
|
||||||
|
|
||||||
|
public static void pushToServer() {
|
||||||
|
List<Note> notes = NoteDataStore.getAllDirtyNotes(Account.getCurrent().getUserId());
|
||||||
|
for (Note note : notes) {
|
||||||
|
if (!note.getTitle().endsWith(CONFLICT_SUFFIX)) {
|
||||||
|
saveNote(note.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void fetchFromServer() {
|
public static void fetchFromServer() {
|
||||||
//sync notebook
|
//sync notebook
|
||||||
int notebookUsn = Account.getCurrent().getNotebookUsn();
|
int notebookUsn = Account.getCurrent().getNotebookUsn();
|
||||||
@@ -310,6 +320,7 @@ public class NoteService {
|
|||||||
requestBodyMap.put("Content", createPartFromString(content));
|
requestBodyMap.put("Content", createPartFromString(content));
|
||||||
requestBodyMap.put("IsMarkdown", createPartFromString(getBooleanString(note.isMarkDown())));
|
requestBodyMap.put("IsMarkdown", createPartFromString(getBooleanString(note.isMarkDown())));
|
||||||
requestBodyMap.put("IsBlog", createPartFromString(getBooleanString(note.isPublicBlog())));
|
requestBodyMap.put("IsBlog", createPartFromString(getBooleanString(note.isPublicBlog())));
|
||||||
|
requestBodyMap.put("IsTrash", createPartFromString(getBooleanString(note.isTrash())));
|
||||||
requestBodyMap.put("CreatedTime", createPartFromString(TimeUtils.toServerTime(note.getCreatedTimeVal())));
|
requestBodyMap.put("CreatedTime", createPartFromString(TimeUtils.toServerTime(note.getCreatedTimeVal())));
|
||||||
requestBodyMap.put("UpdatedTime", createPartFromString(TimeUtils.toServerTime(note.getUpdatedTimeVal())));
|
requestBodyMap.put("UpdatedTime", createPartFromString(TimeUtils.toServerTime(note.getUpdatedTimeVal())));
|
||||||
|
|
||||||
@@ -386,6 +397,18 @@ public class NoteService {
|
|||||||
return localIds;
|
return localIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void trashNotesOnLocal(Note note) {
|
||||||
|
note.setIsTrash(true);
|
||||||
|
note.setIsDirty(true);
|
||||||
|
note.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void trashNote(Note note) {
|
||||||
|
if (!note.isLocalNote()) {
|
||||||
|
saveNote(note.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void deleteNote(Note note) {
|
public static void deleteNote(Note note) {
|
||||||
if (note.isLocalNote()) {
|
if (note.isLocalNote()) {
|
||||||
note.delete();
|
note.delete();
|
||||||
|
@@ -21,7 +21,6 @@ import org.greenrobot.eventbus.ThreadMode;
|
|||||||
import org.houxg.leamonax.R;
|
import org.houxg.leamonax.R;
|
||||||
import org.houxg.leamonax.background.NoteSyncService;
|
import org.houxg.leamonax.background.NoteSyncService;
|
||||||
import org.houxg.leamonax.component.PullToRefresh;
|
import org.houxg.leamonax.component.PullToRefresh;
|
||||||
import org.houxg.leamonax.database.NoteDataStore;
|
|
||||||
import org.houxg.leamonax.database.NotebookDataStore;
|
import org.houxg.leamonax.database.NotebookDataStore;
|
||||||
import org.houxg.leamonax.model.Account;
|
import org.houxg.leamonax.model.Account;
|
||||||
import org.houxg.leamonax.model.Note;
|
import org.houxg.leamonax.model.Note;
|
||||||
@@ -31,7 +30,6 @@ import org.houxg.leamonax.ui.edit.NoteEditActivity;
|
|||||||
import org.houxg.leamonax.utils.NetworkUtils;
|
import org.houxg.leamonax.utils.NetworkUtils;
|
||||||
import org.houxg.leamonax.utils.ToastUtils;
|
import org.houxg.leamonax.utils.ToastUtils;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
@@ -149,8 +147,8 @@ public class MainActivity extends BaseActivity implements Navigation.Callback {
|
|||||||
Note newNote = new Note();
|
Note newNote = new Note();
|
||||||
newNote.setUserId(account.getUserId());
|
newNote.setUserId(account.getUserId());
|
||||||
Notebook notebook;
|
Notebook notebook;
|
||||||
Navigation.Mode currentMode = mNavigation.getCurrentMode();
|
NoteFragment.Mode currentMode = mNavigation.getCurrentMode();
|
||||||
if (currentMode == Navigation.Mode.NOTEBOOK) {
|
if (currentMode == NoteFragment.Mode.NOTEBOOK) {
|
||||||
notebook = NotebookDataStore.getByLocalId(currentMode.notebookId);
|
notebook = NotebookDataStore.getByLocalId(currentMode.notebookId);
|
||||||
} else {
|
} else {
|
||||||
notebook = NotebookDataStore.getRecentNoteBook(Account.getCurrent().getUserId());
|
notebook = NotebookDataStore.getRecentNoteBook(Account.getCurrent().getUserId());
|
||||||
@@ -179,22 +177,8 @@ public class MainActivity extends BaseActivity implements Navigation.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onShowNotes(Navigation.Mode mode) {
|
public boolean onShowNotes(NoteFragment.Mode mode) {
|
||||||
List<Note> notes;
|
mNoteFragment.setMode(mode);
|
||||||
switch (mode) {
|
|
||||||
case RECENT_NOTES:
|
|
||||||
notes = NoteDataStore.getAllNotes(Account.getCurrent().getUserId());
|
|
||||||
break;
|
|
||||||
case NOTEBOOK:
|
|
||||||
notes = NoteDataStore.getNotesFromNotebook(Account.getCurrent().getUserId(), mode.notebookId);
|
|
||||||
break;
|
|
||||||
case TAG:
|
|
||||||
notes = NoteDataStore.getByTagText(mode.tagText, Account.getCurrent().getUserId());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mNoteFragment.setNotes(notes);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -88,7 +88,7 @@ public class Navigation {
|
|||||||
private TagAdapter mTagAdapter;
|
private TagAdapter mTagAdapter;
|
||||||
private AlphabetDrawable mAlphabetDrawable = new AlphabetDrawable();
|
private AlphabetDrawable mAlphabetDrawable = new AlphabetDrawable();
|
||||||
|
|
||||||
private Mode mCurrentMode = Mode.RECENT_NOTES;
|
private NoteFragment.Mode mCurrentMode = NoteFragment.Mode.RECENT_NOTES;
|
||||||
|
|
||||||
public Navigation(Callback callback) {
|
public Navigation(Callback callback) {
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
@@ -255,7 +255,7 @@ public class Navigation {
|
|||||||
mTagAdapter.setListener(new TagAdapter.TagAdapterListener() {
|
mTagAdapter.setListener(new TagAdapter.TagAdapterListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClickedTag(Tag tag) {
|
public void onClickedTag(Tag tag) {
|
||||||
mCurrentMode = Mode.TAG;
|
mCurrentMode = NoteFragment.Mode.TAG;
|
||||||
mCurrentMode.setTagText(tag.getText());
|
mCurrentMode.setTagText(tag.getText());
|
||||||
if (mCallback != null) {
|
if (mCallback != null) {
|
||||||
if (mCallback.onShowNotes(mCurrentMode)) {
|
if (mCallback.onShowNotes(mCurrentMode)) {
|
||||||
@@ -279,7 +279,7 @@ public class Navigation {
|
|||||||
mNotebookAdapter.setListener(new NotebookAdapter.NotebookAdapterListener() {
|
mNotebookAdapter.setListener(new NotebookAdapter.NotebookAdapterListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClickedNotebook(Notebook notebook) {
|
public void onClickedNotebook(Notebook notebook) {
|
||||||
mCurrentMode = Mode.NOTEBOOK;
|
mCurrentMode = NoteFragment.Mode.NOTEBOOK;
|
||||||
mCurrentMode.setNotebookId(notebook.getId());
|
mCurrentMode.setNotebookId(notebook.getId());
|
||||||
if (mCallback != null) {
|
if (mCallback != null) {
|
||||||
if (mCallback.onShowNotes(mCurrentMode)) {
|
if (mCallback.onShowNotes(mCurrentMode)) {
|
||||||
@@ -367,7 +367,7 @@ public class Navigation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mode getCurrentMode() {
|
public NoteFragment.Mode getCurrentMode() {
|
||||||
return mCurrentMode;
|
return mCurrentMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,8 +376,8 @@ public class Navigation {
|
|||||||
mAccountAdapter.load(AccountService.getAccountList());
|
mAccountAdapter.load(AccountService.getAccountList());
|
||||||
mTagAdapter.refresh();
|
mTagAdapter.refresh();
|
||||||
mNotebookAdapter.refresh();
|
mNotebookAdapter.refresh();
|
||||||
if (mCurrentMode == Mode.NOTEBOOK && TextUtils.isEmpty(mNotebookAdapter.getCurrentParentId())) {
|
if (mCurrentMode == NoteFragment.Mode.NOTEBOOK && TextUtils.isEmpty(mNotebookAdapter.getCurrentParentId())) {
|
||||||
mCurrentMode = Mode.RECENT_NOTES;
|
mCurrentMode = NoteFragment.Mode.RECENT_NOTES;
|
||||||
}
|
}
|
||||||
if (mCallback != null) {
|
if (mCallback != null) {
|
||||||
if (mCallback.onShowNotes(mCurrentMode)) {
|
if (mCallback.onShowNotes(mCurrentMode)) {
|
||||||
@@ -458,7 +458,7 @@ public class Navigation {
|
|||||||
|
|
||||||
@OnClick(R.id.rl_recent_notes)
|
@OnClick(R.id.rl_recent_notes)
|
||||||
void clickedRecent() {
|
void clickedRecent() {
|
||||||
mCurrentMode = Mode.RECENT_NOTES;
|
mCurrentMode = NoteFragment.Mode.RECENT_NOTES;
|
||||||
if (mCallback != null) {
|
if (mCallback != null) {
|
||||||
if (mCallback.onShowNotes(mCurrentMode)) {
|
if (mCallback.onShowNotes(mCurrentMode)) {
|
||||||
close();
|
close();
|
||||||
@@ -473,35 +473,12 @@ public class Navigation {
|
|||||||
* @param mode
|
* @param mode
|
||||||
* @return true if processed
|
* @return true if processed
|
||||||
*/
|
*/
|
||||||
boolean onShowNotes(Mode mode);
|
boolean onShowNotes(NoteFragment.Mode mode);
|
||||||
|
|
||||||
void onClickSetting();
|
void onClickSetting();
|
||||||
|
|
||||||
void onClickAbout();
|
void onClickAbout();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Mode {
|
|
||||||
RECENT_NOTES,
|
|
||||||
NOTEBOOK,
|
|
||||||
TAG;
|
|
||||||
|
|
||||||
long notebookId;
|
|
||||||
String tagText;
|
|
||||||
|
|
||||||
public void setNotebookId(long notebookId) {
|
|
||||||
this.notebookId = notebookId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTagText(String tagText) {
|
|
||||||
this.tagText = tagText;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name() + "{" +
|
|
||||||
"notebookId=" + notebookId +
|
|
||||||
", tagText='" + tagText + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -15,12 +15,16 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
import org.houxg.leamonax.Leamonax;
|
||||||
import org.houxg.leamonax.R;
|
import org.houxg.leamonax.R;
|
||||||
import org.houxg.leamonax.adapter.NoteAdapter;
|
import org.houxg.leamonax.adapter.NoteAdapter;
|
||||||
|
import org.houxg.leamonax.database.NoteDataStore;
|
||||||
|
import org.houxg.leamonax.model.Account;
|
||||||
import org.houxg.leamonax.model.Note;
|
import org.houxg.leamonax.model.Note;
|
||||||
import org.houxg.leamonax.service.NoteService;
|
import org.houxg.leamonax.service.NoteService;
|
||||||
import org.houxg.leamonax.utils.ActionModeHandler;
|
import org.houxg.leamonax.utils.ActionModeHandler;
|
||||||
import org.houxg.leamonax.utils.CollectionUtils;
|
import org.houxg.leamonax.utils.CollectionUtils;
|
||||||
|
import org.houxg.leamonax.utils.NetworkUtils;
|
||||||
import org.houxg.leamonax.utils.SharedPreferenceUtils;
|
import org.houxg.leamonax.utils.SharedPreferenceUtils;
|
||||||
import org.houxg.leamonax.utils.ToastUtils;
|
import org.houxg.leamonax.utils.ToastUtils;
|
||||||
import org.houxg.leamonax.widget.NoteList;
|
import org.houxg.leamonax.widget.NoteList;
|
||||||
@@ -51,6 +55,7 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
|||||||
List<Note> mNotes;
|
List<Note> mNotes;
|
||||||
ActionModeHandler<Note> mActionModeHandler;
|
ActionModeHandler<Note> mActionModeHandler;
|
||||||
NoteList mNoteList;
|
NoteList mNoteList;
|
||||||
|
Mode mCurrentMode;
|
||||||
|
|
||||||
public NoteFragment() {
|
public NoteFragment() {
|
||||||
}
|
}
|
||||||
@@ -117,7 +122,27 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
|||||||
EventBus.getDefault().unregister(this);
|
EventBus.getDefault().unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNotes(List<Note> notes) {
|
public void setMode(Mode mode) {
|
||||||
|
mCurrentMode = mode;
|
||||||
|
List<Note> notes;
|
||||||
|
mNoteList.setHighlight("");
|
||||||
|
switch (mode) {
|
||||||
|
case RECENT_NOTES:
|
||||||
|
notes = NoteDataStore.getAllNotes(Account.getCurrent().getUserId());
|
||||||
|
break;
|
||||||
|
case NOTEBOOK:
|
||||||
|
notes = NoteDataStore.getNotesFromNotebook(Account.getCurrent().getUserId(), mode.notebookId);
|
||||||
|
break;
|
||||||
|
case TAG:
|
||||||
|
notes = NoteDataStore.getByTagText(mode.tagText, Account.getCurrent().getUserId());
|
||||||
|
break;
|
||||||
|
case SEARCH:
|
||||||
|
notes = NoteDataStore.searchByTitle(mode.keywords);
|
||||||
|
mNoteList.setHighlight(mode.keywords);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
notes = new ArrayList<>();
|
||||||
|
}
|
||||||
mNotes = notes;
|
mNotes = notes;
|
||||||
Collections.sort(mNotes, new Note.UpdateTimeComparetor());
|
Collections.sort(mNotes, new Note.UpdateTimeComparetor());
|
||||||
mNoteList.render(mNotes);
|
mNoteList.render(mNotes);
|
||||||
@@ -139,7 +164,7 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
|||||||
mNoteList.setSelected(note, isSelected);
|
mNoteList.setSelected(note, isSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteNote(final List<Note> notes) {
|
private void deleteNote(List<Note> notes) {
|
||||||
Observable.from(notes)
|
Observable.from(notes)
|
||||||
.flatMap(new Func1<Note, rx.Observable<Note>>() {
|
.flatMap(new Func1<Note, rx.Observable<Note>>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -148,7 +173,30 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
|||||||
@Override
|
@Override
|
||||||
public void call(Subscriber<? super Note> subscriber) {
|
public void call(Subscriber<? super Note> subscriber) {
|
||||||
if (!subscriber.isUnsubscribed()) {
|
if (!subscriber.isUnsubscribed()) {
|
||||||
NoteService.deleteNote(note);
|
NoteService.trashNotesOnLocal(note);
|
||||||
|
subscriber.onNext(note);
|
||||||
|
subscriber.onCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.buffer(notes.size())
|
||||||
|
.flatMap(new Func1<List<Note>, Observable<Note>>() {
|
||||||
|
@Override
|
||||||
|
public Observable<Note> call(List<Note> notes) {
|
||||||
|
NetworkUtils.checkNetwork();
|
||||||
|
return Observable.from(notes);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.flatMap(new Func1<Note, Observable<Note>>() {
|
||||||
|
@Override
|
||||||
|
public Observable<Note> call(final Note note) {
|
||||||
|
return Observable.create(new Observable.OnSubscribe<Note>() {
|
||||||
|
@Override
|
||||||
|
public void call(Subscriber<? super Note> subscriber) {
|
||||||
|
if (!subscriber.isUnsubscribed()) {
|
||||||
|
NoteService.saveNote(note.getId());
|
||||||
subscriber.onNext(note);
|
subscriber.onNext(note);
|
||||||
subscriber.onCompleted();
|
subscriber.onCompleted();
|
||||||
}
|
}
|
||||||
@@ -166,8 +214,12 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Throwable e) {
|
public void onError(Throwable e) {
|
||||||
ToastUtils.show(getActivity(), R.string.delete_note_failed);
|
if (e instanceof NetworkUtils.NetworkUnavailableException) {
|
||||||
mNoteList.invalidateAllSelected();
|
ToastUtils.show(Leamonax.getContext(), R.string.delete_network_error);
|
||||||
|
} else {
|
||||||
|
ToastUtils.show(Leamonax.getContext(), R.string.delete_note_failed);
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -177,6 +229,9 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refresh() {
|
||||||
|
setMode(mCurrentMode);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onAction(int actionId, List<Note> pendingItems) {
|
public boolean onAction(int actionId, List<Note> pendingItems) {
|
||||||
@@ -217,4 +272,35 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum Mode {
|
||||||
|
RECENT_NOTES,
|
||||||
|
NOTEBOOK,
|
||||||
|
TAG,
|
||||||
|
SEARCH;
|
||||||
|
|
||||||
|
long notebookId;
|
||||||
|
String tagText;
|
||||||
|
String keywords;
|
||||||
|
|
||||||
|
public void setNotebookId(long notebookId) {
|
||||||
|
this.notebookId = notebookId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagText(String tagText) {
|
||||||
|
this.tagText = tagText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeywords(String keywords) {
|
||||||
|
this.keywords = keywords;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name() + "{" +
|
||||||
|
"notebookId=" + notebookId +
|
||||||
|
", tagText='" + tagText + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,56 +1,27 @@
|
|||||||
package org.houxg.leamonax.ui;
|
package org.houxg.leamonax.ui;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.widget.DefaultItemAnimator;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.support.v7.widget.SearchView;
|
import android.support.v7.widget.SearchView;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.transition.Slide;
|
import android.transition.Slide;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import org.houxg.leamonax.R;
|
import org.houxg.leamonax.R;
|
||||||
import org.houxg.leamonax.adapter.NoteAdapter;
|
|
||||||
import org.houxg.leamonax.database.NoteDataStore;
|
|
||||||
import org.houxg.leamonax.model.Note;
|
|
||||||
import org.houxg.leamonax.service.NoteService;
|
|
||||||
import org.houxg.leamonax.utils.ActionModeHandler;
|
|
||||||
import org.houxg.leamonax.utils.CollectionUtils;
|
|
||||||
import org.houxg.leamonax.utils.ToastUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import rx.Observable;
|
|
||||||
import rx.Observer;
|
|
||||||
import rx.Subscriber;
|
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
|
||||||
import rx.functions.Func1;
|
|
||||||
import rx.schedulers.Schedulers;
|
|
||||||
|
|
||||||
public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdapterListener, ActionModeHandler.Callback<Note> {
|
public class SearchActivity extends BaseActivity {
|
||||||
|
|
||||||
private static final String EXT_SCROLL_POSITION = "ext_scroll_position";
|
|
||||||
|
|
||||||
@BindView(R.id.recycler_view)
|
|
||||||
RecyclerView mNoteListView;
|
|
||||||
@BindView(R.id.toolbar)
|
@BindView(R.id.toolbar)
|
||||||
Toolbar mToolbar;
|
Toolbar mToolbar;
|
||||||
@BindView(R.id.search)
|
@BindView(R.id.search)
|
||||||
SearchView mSearchView;
|
SearchView mSearchView;
|
||||||
|
|
||||||
List<Note> mNotes = new ArrayList<>();
|
private NoteFragment mNoteFragment;
|
||||||
private NoteAdapter mAdapter;
|
|
||||||
private ActionModeHandler<Note> mActionModeHandler;
|
|
||||||
private float mScrollPosition;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -62,27 +33,6 @@ public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdap
|
|||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
initToolBar(mToolbar, true);
|
initToolBar(mToolbar, true);
|
||||||
setTitle("");
|
setTitle("");
|
||||||
mActionModeHandler = new ActionModeHandler<>(this, this, R.menu.delete);
|
|
||||||
|
|
||||||
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
|
|
||||||
mNoteListView.setLayoutManager(layoutManager);
|
|
||||||
mNoteListView.setItemAnimator(new DefaultItemAnimator());
|
|
||||||
|
|
||||||
mAdapter = new NoteAdapter(this);
|
|
||||||
mNoteListView.setAdapter(mAdapter);
|
|
||||||
mNoteListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
|
||||||
@Override
|
|
||||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
|
||||||
super.onScrollStateChanged(recyclerView, newState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy);
|
|
||||||
mScrollPosition = dy;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onQueryTextSubmit(String query) {
|
public boolean onQueryTextSubmit(String query) {
|
||||||
@@ -91,11 +41,18 @@ public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdap
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onQueryTextChange(String newText) {
|
public boolean onQueryTextChange(String newText) {
|
||||||
searchTitle(newText);
|
NoteFragment.Mode mode = NoteFragment.Mode.SEARCH;
|
||||||
|
mode.setKeywords(newText);
|
||||||
|
mNoteFragment.setMode(mode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||||
|
mNoteFragment = NoteFragment.newInstance();
|
||||||
|
transaction.add(R.id.container, mNoteFragment);
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
ImageView searchCloseIcon = (ImageView) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
|
ImageView searchCloseIcon = (ImageView) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
|
||||||
searchCloseIcon.setImageResource(R.drawable.ic_clear);
|
searchCloseIcon.setImageResource(R.drawable.ic_clear);
|
||||||
ImageView searchIcon = (ImageView) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
|
ImageView searchIcon = (ImageView) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
|
||||||
@@ -107,125 +64,4 @@ public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdap
|
|||||||
mSearchView.setIconified(false);
|
mSearchView.setIconified(false);
|
||||||
mSearchView.setIconifiedByDefault(false);
|
mSearchView.setIconifiedByDefault(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
|
||||||
super.onRestoreInstanceState(savedInstanceState);
|
|
||||||
mScrollPosition = savedInstanceState.getFloat(EXT_SCROLL_POSITION, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
mNoteListView.scrollTo(0, (int) mScrollPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putFloat(EXT_SCROLL_POSITION, mScrollPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void searchTitle(String keyword) {
|
|
||||||
if (TextUtils.isEmpty(keyword)) {
|
|
||||||
mNotes = new ArrayList<>();
|
|
||||||
} else {
|
|
||||||
mNotes = NoteDataStore.searchByTitle(keyword);
|
|
||||||
Collections.sort(mNotes, new Note.UpdateTimeComparetor());
|
|
||||||
}
|
|
||||||
mAdapter.setHighlight(keyword);
|
|
||||||
mAdapter.load(mNotes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClickNote(Note note) {
|
|
||||||
if (mActionModeHandler.isActionMode()) {
|
|
||||||
boolean isSelected = mActionModeHandler.chooseItem(note);
|
|
||||||
mAdapter.setSelected(note, isSelected);
|
|
||||||
} else {
|
|
||||||
startActivity(NotePreviewActivity.getOpenIntent(this, note.getId()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLongClickNote(final Note note) {
|
|
||||||
boolean isSelected = mActionModeHandler.chooseItem(note);
|
|
||||||
mAdapter.setSelected(note, isSelected);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deleteNote(final List<Note> notes) {
|
|
||||||
Observable.from(notes)
|
|
||||||
.flatMap(new Func1<Note, Observable<Note>>() {
|
|
||||||
@Override
|
|
||||||
public rx.Observable<Note> call(final Note note) {
|
|
||||||
return Observable.create(new Observable.OnSubscribe<Note>() {
|
|
||||||
@Override
|
|
||||||
public void call(Subscriber<? super Note> subscriber) {
|
|
||||||
if (!subscriber.isUnsubscribed()) {
|
|
||||||
NoteService.deleteNote(note);
|
|
||||||
subscriber.onNext(note);
|
|
||||||
subscriber.onCompleted();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(new Observer<Note>() {
|
|
||||||
@Override
|
|
||||||
public void onCompleted() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable e) {
|
|
||||||
ToastUtils.show(SearchActivity.this, R.string.delete_note_failed);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNext(Note note) {
|
|
||||||
mAdapter.delete(note);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onAction(int actionId, List<Note> pendingItems) {
|
|
||||||
if (CollectionUtils.isEmpty(pendingItems)) {
|
|
||||||
ToastUtils.show(this, R.string.no_note_was_selected);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final List<Note> waitToDelete = new ArrayList<>();
|
|
||||||
for (int i = 0; i < pendingItems.size(); i++) {
|
|
||||||
waitToDelete.add(pendingItems.get(i));
|
|
||||||
}
|
|
||||||
new AlertDialog.Builder(this)
|
|
||||||
.setTitle(R.string.delete_note)
|
|
||||||
.setMessage(R.string.are_you_sure_to_delete_note)
|
|
||||||
.setCancelable(true)
|
|
||||||
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
dialog.dismiss();
|
|
||||||
mActionModeHandler.dismiss();
|
|
||||||
deleteNote(waitToDelete);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.show();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy(List<Note> pendingItems) {
|
|
||||||
if (CollectionUtils.isNotEmpty(pendingItems)) {
|
|
||||||
mAdapter.invalidateAllSelected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,10 @@ import android.net.NetworkInfo;
|
|||||||
|
|
||||||
import org.houxg.leamonax.Leamonax;
|
import org.houxg.leamonax.Leamonax;
|
||||||
import org.houxg.leamonax.R;
|
import org.houxg.leamonax.R;
|
||||||
|
import org.houxg.leamonax.model.Note;
|
||||||
|
|
||||||
|
import rx.Observable;
|
||||||
|
import rx.Subscriber;
|
||||||
|
|
||||||
public class NetworkUtils {
|
public class NetworkUtils {
|
||||||
|
|
||||||
@@ -33,6 +37,18 @@ public class NetworkUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> Observable<T> checkNetwork(T data) {
|
||||||
|
return Observable.create(new Observable.OnSubscribe<T>() {
|
||||||
|
@Override
|
||||||
|
public void call(Subscriber<? super T> subscriber) {
|
||||||
|
if (!isNetworkAvailable()) {
|
||||||
|
throw new NetworkUnavailableException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static class NetworkUnavailableException extends IllegalStateException {
|
public static class NetworkUnavailableException extends IllegalStateException {
|
||||||
public NetworkUnavailableException() {
|
public NetworkUnavailableException() {
|
||||||
super(Leamonax.getContext().getResources().getString(R.string.network_is_unavailable));
|
super(Leamonax.getContext().getResources().getString(R.string.network_is_unavailable));
|
||||||
|
@@ -66,6 +66,10 @@ public class NoteList {
|
|||||||
mAdapter.notifyDataSetChanged();
|
mAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHighlight(String keyword) {
|
||||||
|
mAdapter.setHighlight(keyword);
|
||||||
|
}
|
||||||
|
|
||||||
public void toggleType() {
|
public void toggleType() {
|
||||||
int newType = mCurrentType == TYPE_SIMPLE ? TYPE_DETAIL : TYPE_SIMPLE;
|
int newType = mCurrentType == TYPE_SIMPLE ? TYPE_DETAIL : TYPE_SIMPLE;
|
||||||
setType(newType);
|
setType(newType);
|
||||||
|
@@ -21,9 +21,9 @@
|
|||||||
|
|
||||||
</android.support.v7.widget.Toolbar>
|
</android.support.v7.widget.Toolbar>
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<FrameLayout
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@@ -107,4 +107,5 @@
|
|||||||
<string name="conflict_occurs">糟糕,笔记冲突</string>
|
<string name="conflict_occurs">糟糕,笔记冲突</string>
|
||||||
<string name="host_example">登录接口地址将会是:\n%s/api/auth/login</string>
|
<string name="host_example">登录接口地址将会是:\n%s/api/auth/login</string>
|
||||||
<string name="notebook_name_cant_be_empty">笔记本名称不能为空</string>
|
<string name="notebook_name_cant_be_empty">笔记本名称不能为空</string>
|
||||||
|
<string name="delete_network_error">网络不可用,将在下次同步时删除</string>
|
||||||
</resources>
|
</resources>
|
@@ -109,5 +109,6 @@
|
|||||||
<string name="conflict_occurs">Oops! Conflicts occurs</string>
|
<string name="conflict_occurs">Oops! Conflicts occurs</string>
|
||||||
<string name="host_example">For example, login api will be:\n%s/api/auth/login</string>
|
<string name="host_example">For example, login api will be:\n%s/api/auth/login</string>
|
||||||
<string name="notebook_name_cant_be_empty">Notebook\'s name can\'t be empty</string>
|
<string name="notebook_name_cant_be_empty">Notebook\'s name can\'t be empty</string>
|
||||||
|
<string name="delete_network_error">Network is unavailable, these notes will be deleted in next sync</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
Reference in New Issue
Block a user