Merge branch 'develop'

This commit is contained in:
xingxing
2017-03-11 22:38:48 +08:00
41 changed files with 708 additions and 764 deletions

View File

@@ -18,11 +18,11 @@ import android.widget.TextView;
import com.bumptech.glide.Glide;
import org.houxg.leamonax.R;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.NotebookDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.model.NoteFile;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.service.AccountService;
import org.houxg.leamonax.service.NoteFileService;
import org.houxg.leamonax.utils.FileUtils;
import org.houxg.leamonax.utils.TimeUtils;
@@ -107,7 +107,7 @@ public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder> {
}
private void updateNotebookMap() {
List<Notebook> notebooks = AppDataBase.getAllNotebook(AccountService.getCurrent().getUserId());
List<Notebook> notebooks = NotebookDataStore.getAllNotebooks(Account.getCurrent().getUserId());
mNotebookId2TitleMaps = new HashMap<>();
for (Notebook notebook : notebooks) {
mNotebookId2TitleMaps.put(notebook.getNotebookId(), notebook.getTitle());

View File

@@ -10,9 +10,9 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.houxg.leamonax.R;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.NotebookDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.service.AccountService;
import org.houxg.leamonax.utils.CollectionUtils;
import org.houxg.leamonax.utils.ToastUtils;
@@ -57,14 +57,14 @@ public class NotebookAdapter extends RecyclerView.Adapter<NotebookAdapter.Notebo
private void getSafeNotebook(Stack<String> stack) {
if (stack.isEmpty()) {
mData = AppDataBase.getRootNotebooks(AccountService.getCurrent().getUserId());
mData = NotebookDataStore.getRootNotebooks(Account.getCurrent().getUserId());
} else {
Notebook parent = AppDataBase.getNotebookByServerId(stack.peek());
Notebook parent = NotebookDataStore.getByServerId(stack.peek());
if (parent.isDeleted()) {
stack.pop();
getSafeNotebook(stack);
} else {
mData = AppDataBase.getChildNotebook(mStack.peek(), AccountService.getCurrent().getUserId());
mData = NotebookDataStore.getChildNotebook(mStack.peek(), Account.getCurrent().getUserId());
mData.add(0, parent);
}
}
@@ -159,7 +159,7 @@ public class NotebookAdapter extends RecyclerView.Adapter<NotebookAdapter.Notebo
}
private boolean hasChild(String notebookId) {
return CollectionUtils.isNotEmpty(AppDataBase.getChildNotebook(notebookId, AccountService.getCurrent().getUserId()));
return CollectionUtils.isNotEmpty(NotebookDataStore.getChildNotebook(notebookId, Account.getCurrent().getUserId()));
}
private void listUpper() {
@@ -169,11 +169,11 @@ public class NotebookAdapter extends RecyclerView.Adapter<NotebookAdapter.Notebo
mStack.pop();
if (mStack.isEmpty()) {
mData = AppDataBase.getRootNotebooks(AccountService.getCurrent().getUserId());
mData = NotebookDataStore.getRootNotebooks(Account.getCurrent().getUserId());
} else {
String parentId = mStack.peek();
mData.add(AppDataBase.getNotebookByServerId(parentId));
mData.addAll(AppDataBase.getChildNotebook(parentId, AccountService.getCurrent().getUserId()));
mData.add(NotebookDataStore.getByServerId(parentId));
mData.addAll(NotebookDataStore.getChildNotebook(parentId, Account.getCurrent().getUserId()));
}
notifyItemRangeInserted(0, mData.size());
}
@@ -192,7 +192,7 @@ public class NotebookAdapter extends RecyclerView.Adapter<NotebookAdapter.Notebo
notifyItemChanged(0);
mStack.push(notebook.getNotebookId());
List<Notebook> children = AppDataBase.getChildNotebook(notebook.getNotebookId(), AccountService.getCurrent().getUserId());
List<Notebook> children = NotebookDataStore.getChildNotebook(notebook.getNotebookId(), Account.getCurrent().getUserId());
int childrenSize = children.size();
mData.addAll(children);
notifyItemRangeInserted(1, childrenSize);

View File

@@ -8,11 +8,9 @@ import android.view.ViewGroup;
import android.widget.TextView;
import org.houxg.leamonax.R;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Tag;
import org.houxg.leamonax.service.AccountService;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
@@ -28,7 +26,7 @@ public class TagAdapter extends RecyclerView.Adapter<TagAdapter.TagHolder> {
}
public void refresh() {
mData = AppDataBase.getAllTags(AccountService.getCurrent().getUserId());
mData = Tag.getAllTags(Account.getCurrent().getUserId());
notifyDataSetChanged();
}

View File

@@ -59,6 +59,7 @@ public class NoteSyncService extends Service {
public void call(Subscriber<? super Void> subscriber) {
if (!subscriber.isUnsubscribed()) {
NoteService.fetchFromServer();
NoteService.pushToServer();
subscriber.onNext(null);
subscriber.onCompleted();
}

View File

@@ -0,0 +1,33 @@
package org.houxg.leamonax.component;
import android.support.v4.widget.SwipeRefreshLayout;
import com.elvishew.xlog.XLog;
public class PullToRefresh {
private SwipeRefreshLayout refreshLayout;
private SwipeRefreshLayout.OnRefreshListener listener;
public PullToRefresh(SwipeRefreshLayout refreshLayout, SwipeRefreshLayout.OnRefreshListener listener) {
this.listener = listener;
this.refreshLayout = refreshLayout;
refreshLayout.setOnRefreshListener(listener);
}
public void forceRefresh() {
refreshLayout.postDelayed(new Runnable() {
@Override
public void run() {
XLog.i("fetching notes");
refreshLayout.setRefreshing(true);
listener.onRefresh();
}
}, 200);
}
public void stopRefreshing() {
refreshLayout.setRefreshing(false);
}
}

View File

@@ -0,0 +1,43 @@
package org.houxg.leamonax.database;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import com.raizlabs.android.dbflow.sql.language.Select;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Account_Table;
import java.util.List;
public class AccountDataStore {
public static Account getAccount(String email, String host) {
return SQLite.select()
.from(Account.class)
.where(Account_Table.email.eq(email))
.and(Account_Table.host.eq(host))
.querySingle();
}
public static Account getCurrent() {
return SQLite.select()
.from(Account.class)
.where(Account_Table.token.notEq(""))
.orderBy(Account_Table.lastUseTime, false)
.querySingle();
}
public static List<Account> getAccountListWithToken() {
return SQLite.select()
.from(Account.class)
.where(Account_Table.token.notEq(""))
.orderBy(Account_Table.lastUseTime, false)
.queryList();
}
public static Account getAccountById(long id) {
return new Select()
.from(Account.class)
.where(Account_Table.id.eq(id))
.querySingle();
}
}

View File

@@ -6,10 +6,7 @@ import android.text.TextUtils;
import com.raizlabs.android.dbflow.annotation.Database;
import com.raizlabs.android.dbflow.annotation.Migration;
import com.raizlabs.android.dbflow.sql.SQLiteType;
import com.raizlabs.android.dbflow.sql.language.Join;
import com.raizlabs.android.dbflow.sql.language.NameAlias;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import com.raizlabs.android.dbflow.sql.language.property.IProperty;
import com.raizlabs.android.dbflow.sql.migration.AlterTableMigration;
import com.raizlabs.android.dbflow.sql.migration.BaseMigration;
import com.raizlabs.android.dbflow.structure.database.DatabaseWrapper;
@@ -17,26 +14,14 @@ import com.raizlabs.android.dbflow.structure.database.DatabaseWrapper;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Account_Table;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.model.NoteFile;
import org.houxg.leamonax.model.NoteFile_Table;
import org.houxg.leamonax.model.Note_Table;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.model.Notebook_Table;
import org.houxg.leamonax.model.RelationshipOfNoteTag;
import org.houxg.leamonax.model.RelationshipOfNoteTag_Table;
import org.houxg.leamonax.model.Tag;
import org.houxg.leamonax.model.Tag_Table;
import org.houxg.leamonax.utils.CollectionUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Database(name = "leanote_db", version = 4)
public class AppDataBase {
private static final String TAG = "AppDataBase:";
@Migration(version = 2, database = AppDataBase.class)
public static class UpdateTag extends BaseMigration {
@@ -97,7 +82,7 @@ public class AppDataBase {
}
}
@Migration(version = 3, priority = 0, database = AppDataBase.class)
@Migration(version = 3, priority = 0, database = AppDataBase.class)
public static class UpdateUsn extends BaseMigration {
@Override
@@ -142,7 +127,7 @@ public class AppDataBase {
}
}
@Migration(version = 4, priority = 0, database = AppDataBase.class)
@Migration(version = 4, priority = 0, database = AppDataBase.class)
public static class UpdateLastUseTime extends BaseMigration {
@Override
@@ -172,241 +157,4 @@ public class AppDataBase {
cursor.close();
}
}
public static void deleteNoteByLocalId(long localId) {
SQLite.delete().from(Note.class)
.where(Note_Table.id.eq(localId))
.async()
.execute();
}
public static Note getNoteByServerId(String serverId) {
return SQLite.select()
.from(Note.class)
.where(Note_Table.noteId.eq(serverId))
.querySingle();
}
public static Note getNoteByLocalId(long localId) {
return SQLite.select()
.from(Note.class)
.where(Note_Table.id.eq(localId))
.querySingle();
}
public static List<Note> getNotesFromNotebook(String userId, long localNotebookId) {
Notebook notebook = getNotebookByLocalId(localNotebookId);
if (notebook == null) {
return new ArrayList<>();
}
return SQLite.select()
.from(Note.class)
.where(Note_Table.notebookId.eq(notebook.getNotebookId()))
.and(Note_Table.userId.eq(userId))
.and(Note_Table.isTrash.eq(false))
.and(Note_Table.isDeleted.eq(false))
.and(Note_Table.isTrash.eq(false))
.queryList();
}
public static List<Note> getNotesByTagText(String tagText, String userId) {
Tag tag = getTagByText(tagText, userId);
if (tag == null) {
return new ArrayList<>();
}
return getNotesByTagId(tag.getId());
}
public static List<Note> getAllNotes(String userId) {
return SQLite.select()
.from(Note.class)
.where(Note_Table.userId.eq(userId))
.and(Note_Table.isTrash.eq(false))
.and(Note_Table.isDeleted.eq(false))
.and(Note_Table.isTrash.eq(false))
.queryList();
}
public static Notebook getNotebookByServerId(String serverId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.notebookId.eq(serverId))
.querySingle();
}
public static Notebook getNotebookByLocalId(long localId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.id.eq(localId))
.querySingle();
}
public static Notebook getRecentNoteBook(String userId) {
Note recentNotes = SQLite.select()
.from(Note.class)
.where(Note_Table.userId.eq(userId))
.and(Note_Table.notebookId.notEq(""))
.orderBy(Note_Table.updatedTime, false)
.querySingle();
if (recentNotes != null) {
Notebook notebook = getNotebookByServerId(recentNotes.getNoteBookId());
if (notebook != null && !notebook.isDeleted()) {
return notebook;
}
}
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(userId))
.and(Notebook_Table.isDeletedOnServer.eq(false))
.querySingle();
}
public static List<Notebook> getAllNotebook(String userId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(userId))
.and(Notebook_Table.isDeletedOnServer.eq(false))
.queryList();
}
public static List<Notebook> getRootNotebooks(String userId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(userId))
.and(Notebook_Table.parentNotebookId.eq(""))
.and(Notebook_Table.isDeletedOnServer.eq(false))
.queryList();
}
public static List<Notebook> getChildNotebook(String notebookId, String userId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(userId))
.and(Notebook_Table.parentNotebookId.eq(notebookId))
.and(Notebook_Table.isDeletedOnServer.eq(false))
.queryList();
}
public static List<NoteFile> getAllRelatedFile(long noteLocalId) {
return SQLite.select()
.from(NoteFile.class)
.where(NoteFile_Table.noteLocalId.eq(noteLocalId))
.queryList();
}
public static NoteFile getNoteFileByLocalId(String localId) {
return SQLite.select()
.from(NoteFile.class)
.where(NoteFile_Table.localId.eq(localId))
.querySingle();
}
public static NoteFile getNoteFileByServerId(String serverId) {
return SQLite.select()
.from(NoteFile.class)
.where(NoteFile_Table.serverId.eq(serverId))
.querySingle();
}
public static void deleteFileExcept(long noteLocalId, Collection<String> excepts) {
SQLite.delete()
.from(NoteFile.class)
.where(NoteFile_Table.noteLocalId.eq(noteLocalId))
.and(NoteFile_Table.localId.notIn(excepts))
.async()
.execute();
}
public static Account getAccount(String email, String host) {
return SQLite.select()
.from(Account.class)
.where(Account_Table.email.eq(email))
.and(Account_Table.host.eq(host))
.querySingle();
}
public static Account getAccountWithToken() {
return SQLite.select()
.from(Account.class)
.where(Account_Table.token.notEq(""))
.orderBy(Account_Table.lastUseTime, false)
.querySingle();
}
public static List<Account> getAccountListWithToken() {
return SQLite.select()
.from(Account.class)
.where(Account_Table.token.notEq(""))
.orderBy(Account_Table.lastUseTime, false)
.queryList();
}
public static List<Tag> getTagByNoteLocalId(long noteLocalId) {
return SQLite.select()
.from(Tag.class).as("T")
.join(RelationshipOfNoteTag.class, Join.JoinType.INNER).as("R")
.on(Tag_Table.id.withTable(NameAlias.builder("T").build())
.eq(RelationshipOfNoteTag_Table.tagLocalId.withTable(NameAlias.builder("R").build())))
.where(RelationshipOfNoteTag_Table.noteLocalId.withTable(NameAlias.builder("R").build()).eq(noteLocalId))
.queryList();
}
public static List<Note> getNotesByTagId(long tagId) {
IProperty[] properties = Note_Table.ALL_COLUMN_PROPERTIES;
NameAlias nameAlias = NameAlias.builder("N").build();
for (int i = 0; i < properties.length; i++) {
properties[i] = properties[i].withTable(nameAlias);
}
return SQLite.select(properties)
.from(Note.class).as("N")
.join(RelationshipOfNoteTag.class, Join.JoinType.INNER).as("R")
.on(Tag_Table.id.withTable(NameAlias.builder("N").build())
.eq(RelationshipOfNoteTag_Table.noteLocalId.withTable(NameAlias.builder("R").build())))
.where(RelationshipOfNoteTag_Table.tagLocalId.withTable(NameAlias.builder("R").build()).eq(tagId))
.queryList();
}
public static RelationshipOfNoteTag getRelationShip(long noteLocalId, long tagId, String userId) {
return SQLite.select()
.from(RelationshipOfNoteTag.class)
.where(RelationshipOfNoteTag_Table.userId.eq(userId))
.and(RelationshipOfNoteTag_Table.tagLocalId.eq(tagId))
.and(RelationshipOfNoteTag_Table.noteLocalId.eq(noteLocalId))
.querySingle();
}
public static Tag getTagByText(String text, String userId) {
return SQLite.select()
.from(Tag.class)
.where(Tag_Table.userId.eq(userId))
.and(Tag_Table.text.eq(text))
.querySingle();
}
public static void deleteAllRelatedTags(long noteLocalId, String userId) {
SQLite.delete()
.from(RelationshipOfNoteTag.class)
.where(RelationshipOfNoteTag_Table.userId.eq(userId))
.and(RelationshipOfNoteTag_Table.noteLocalId.eq(noteLocalId))
.async()
.execute();
}
public static void deleteRelatedTags(long noteLocalId, String userId, long firstReservedId, long... reservedIds) {
SQLite.delete()
.from(RelationshipOfNoteTag.class)
.where(RelationshipOfNoteTag_Table.userId.eq(userId))
.and(RelationshipOfNoteTag_Table.noteLocalId.eq(noteLocalId))
.and(RelationshipOfNoteTag_Table.id.notIn(firstReservedId, reservedIds))
.async()
.execute();
}
public static List<Tag> getAllTags(String userId) {
return SQLite.select()
.from(Tag.class)
.where(Tag_Table.userId.eq(userId))
.queryList();
}
}

View File

@@ -0,0 +1,109 @@
package org.houxg.leamonax.database;
import com.raizlabs.android.dbflow.sql.language.Join;
import com.raizlabs.android.dbflow.sql.language.NameAlias;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import com.raizlabs.android.dbflow.sql.language.property.IProperty;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.model.Note_Table;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.model.RelationshipOfNoteTag;
import org.houxg.leamonax.model.RelationshipOfNoteTag_Table;
import org.houxg.leamonax.model.Tag;
import org.houxg.leamonax.model.Tag_Table;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class NoteDataStore {
public static List<Note> searchByTitle(String keyword) {
keyword = String.format(Locale.US, "%%%s%%", keyword);
return SQLite.select()
.from(Note.class)
.where(Note_Table.userId.eq(Account.getCurrent().getUserId()))
.and(Note_Table.title.like(keyword))
.and(Note_Table.isTrash.eq(false))
.and(Note_Table.isDeleted.eq(false))
.queryList();
}
public static Note getByServerId(String serverId) {
return SQLite.select()
.from(Note.class)
.where(Note_Table.noteId.eq(serverId))
.querySingle();
}
public static Note getByLocalId(long localId) {
return SQLite.select()
.from(Note.class)
.where(Note_Table.id.eq(localId))
.querySingle();
}
public static List<Note> getAllNotes(String userId) {
return SQLite.select()
.from(Note.class)
.where(Note_Table.userId.eq(userId))
.and(Note_Table.isDeleted.eq(false))
.and(Note_Table.isTrash.eq(false))
.queryList();
}
public static List<Note> getAllDirtyNotes(String userId) {
return SQLite.select()
.from(Note.class)
.where(Note_Table.userId.eq(userId))
.and(Note_Table.isDeleted.eq(false))
.and(Note_Table.isDirty.eq(true))
.queryList();
}
public static List<Note> getNotesFromNotebook(String userId, long localNotebookId) {
Notebook notebook = NotebookDataStore.getByLocalId(localNotebookId);
if (notebook == null) {
return new ArrayList<>();
}
return SQLite.select()
.from(Note.class)
.where(Note_Table.notebookId.eq(notebook.getNotebookId()))
.and(Note_Table.userId.eq(userId))
.and(Note_Table.isDeleted.eq(false))
.and(Note_Table.isTrash.eq(false))
.queryList();
}
public static List<Note> getByTagText(String tagText, String userId) {
Tag tag = Tag.getByText(tagText, userId);
if (tag == null) {
return new ArrayList<>();
}
return getNotesByTagId(tag.getId());
}
private static List<Note> getNotesByTagId(long tagId) {
IProperty[] properties = Note_Table.ALL_COLUMN_PROPERTIES;
NameAlias nameAlias = NameAlias.builder("N").build();
for (int i = 0; i < properties.length; i++) {
properties[i] = properties[i].withTable(nameAlias);
}
return SQLite.select(properties)
.from(Note.class).as("N")
.join(RelationshipOfNoteTag.class, Join.JoinType.INNER).as("R")
.on(Tag_Table.id.withTable(NameAlias.builder("N").build())
.eq(RelationshipOfNoteTag_Table.noteLocalId.withTable(NameAlias.builder("R").build())))
.where(RelationshipOfNoteTag_Table.tagLocalId.withTable(NameAlias.builder("R").build()).eq(tagId))
.queryList();
}
public static void deleteAll(String userId) {
SQLite.delete()
.from(Note.class)
.where(Note_Table.userId.eq(userId))
.execute();
}
}

View File

@@ -0,0 +1,43 @@
package org.houxg.leamonax.database;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import org.houxg.leamonax.model.NoteFile;
import org.houxg.leamonax.model.NoteFile_Table;
import java.util.Collection;
import java.util.List;
public class NoteFileDataStore {
public static List<NoteFile> getAllRelated(long noteLocalId) {
return SQLite.select()
.from(NoteFile.class)
.where(NoteFile_Table.noteLocalId.eq(noteLocalId))
.queryList();
}
public static NoteFile getByLocalId(String localId) {
return SQLite.select()
.from(NoteFile.class)
.where(NoteFile_Table.localId.eq(localId))
.querySingle();
}
public static NoteFile getByServerId(String serverId) {
return SQLite.select()
.from(NoteFile.class)
.where(NoteFile_Table.serverId.eq(serverId))
.querySingle();
}
public static void deleteExcept(long noteLocalId, Collection<String> excepts) {
SQLite.delete()
.from(NoteFile.class)
.where(NoteFile_Table.noteLocalId.eq(noteLocalId))
.and(NoteFile_Table.localId.notIn(excepts))
.async()
.execute();
}
}

View File

@@ -0,0 +1,16 @@
package org.houxg.leamonax.database;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import org.houxg.leamonax.model.RelationshipOfNoteTag;
import org.houxg.leamonax.model.RelationshipOfNoteTag_Table;
public class NoteTagDataStore {
public static void deleteAll(String userId) {
SQLite.delete()
.from(RelationshipOfNoteTag.class)
.where(RelationshipOfNoteTag_Table.userId.eq(userId))
.execute();
}
}

View File

@@ -0,0 +1,81 @@
package org.houxg.leamonax.database;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.model.Note_Table;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.model.Notebook_Table;
import java.util.List;
public class NotebookDataStore {
public static List<Notebook> getAllNotebooks(String userId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(userId))
.and(Notebook_Table.isDeletedOnServer.eq(false))
.queryList();
}
public static Notebook getByLocalId(long localId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.id.eq(localId))
.querySingle();
}
public static Notebook getByServerId(String serverId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.notebookId.eq(serverId))
.querySingle();
}
public static Notebook getRecentNoteBook(String userId) {
Note recentNotes = SQLite.select()
.from(Note.class)
.where(Note_Table.userId.eq(userId))
.and(Note_Table.notebookId.notEq(""))
.orderBy(Note_Table.updatedTime, false)
.querySingle();
if (recentNotes != null) {
Notebook notebook = getByServerId(recentNotes.getNoteBookId());
if (notebook != null && !notebook.isDeleted()) {
return notebook;
}
}
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(userId))
.and(Notebook_Table.isDeletedOnServer.eq(false))
.querySingle();
}
public static List<Notebook> getRootNotebooks(String userId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(userId))
.and(Notebook_Table.parentNotebookId.eq(""))
.and(Notebook_Table.isDeletedOnServer.eq(false))
.queryList();
}
public static List<Notebook> getChildNotebook(String notebookId, String userId) {
return SQLite.select()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(userId))
.and(Notebook_Table.parentNotebookId.eq(notebookId))
.and(Notebook_Table.isDeletedOnServer.eq(false))
.queryList();
}
public static void deleteAll(String userId) {
SQLite.delete()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(userId))
.execute();
}
}

View File

@@ -6,6 +6,7 @@ import com.raizlabs.android.dbflow.annotation.PrimaryKey;
import com.raizlabs.android.dbflow.annotation.Table;
import com.raizlabs.android.dbflow.structure.BaseModel;
import org.houxg.leamonax.database.AccountDataStore;
import org.houxg.leamonax.database.AppDataBase;
@Table(name = "Account", database = AppDataBase.class)
@@ -170,6 +171,10 @@ public class Account extends BaseModel {
return lastUseTime;
}
public static Account getCurrent() {
return AccountDataStore.getCurrent();
}
@Override
public String toString() {
return "Account{" +

View File

@@ -17,9 +17,6 @@ import java.io.Serializable;
import java.util.Comparator;
import java.util.List;
/**
* Created by binnchx on 10/18/15.
*/
@Table(name = "Note", database = AppDataBase.class)
public class Note extends BaseModel implements Serializable {
@@ -93,7 +90,6 @@ public class Note extends BaseModel implements Serializable {
long publicTime;
@Column(name = "tags")
String tags = "";
boolean uploadSucc = true;
public long getCreatedTimeVal() {
return createdTime;
@@ -171,14 +167,6 @@ public class Note extends BaseModel implements Serializable {
return usn;
}
public boolean isUploadSucc() {
return uploadSucc;
}
public void setUploadSucc(boolean uploadSucc) {
this.uploadSucc = uploadSucc;
}
public void setUsn(int usn) {
this.usn = usn;
}
@@ -230,33 +218,6 @@ public class Note extends BaseModel implements Serializable {
return noteFiles;
}
//TODO:delete this
public String getUpdatedTime() {
return updatedTimeData;
}
//TODO:delete this
public String getCreatedTime() {
return updatedTimeData;
}
//TODO:delete this
public String getPublicTime() {
return publicTimeData;
}
//TODO:delete this
public void setUpdatedTime(String v) {
}
//TODO:delete this
public void setCreatedTime(String v) {
}
//TODO:delete this
public void setPublicTime(String publicTime) {
}
@Override
public String toString() {
return "Note{" +

View File

@@ -5,11 +5,16 @@ import com.google.gson.annotations.SerializedName;
import com.raizlabs.android.dbflow.annotation.Column;
import com.raizlabs.android.dbflow.annotation.PrimaryKey;
import com.raizlabs.android.dbflow.annotation.Table;
import com.raizlabs.android.dbflow.sql.language.Join;
import com.raizlabs.android.dbflow.sql.language.NameAlias;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import com.raizlabs.android.dbflow.structure.BaseModel;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.utils.TimeUtils;
import java.util.List;
@Table(name = "Tag", database = AppDataBase.class)
public class Tag extends BaseModel{
@@ -116,4 +121,64 @@ public class Tag extends BaseModel{
createdTime = TimeUtils.toTimestamp(createTimeData);
updatedTime = TimeUtils.toTimestamp(updatedTimeData);
}
public static Tag getByText(String text, String userId) {
return SQLite.select()
.from(Tag.class)
.where(Tag_Table.userId.eq(userId))
.and(Tag_Table.text.eq(text))
.querySingle();
}
public static List<Tag> getAllTags(String userId) {
return SQLite.select()
.from(Tag.class)
.where(Tag_Table.userId.eq(userId))
.queryList();
}
public static List<Tag> getByNoteLocalId(long noteLocalId) {
return SQLite.select()
.from(Tag.class).as("T")
.join(RelationshipOfNoteTag.class, Join.JoinType.INNER).as("R")
.on(Tag_Table.id.withTable(NameAlias.builder("T").build())
.eq(RelationshipOfNoteTag_Table.tagLocalId.withTable(NameAlias.builder("R").build())))
.where(RelationshipOfNoteTag_Table.noteLocalId.withTable(NameAlias.builder("R").build()).eq(noteLocalId))
.queryList();
}
public static RelationshipOfNoteTag getRelationShip(long noteLocalId, long tagId, String userId) {
return SQLite.select()
.from(RelationshipOfNoteTag.class)
.where(RelationshipOfNoteTag_Table.userId.eq(userId))
.and(RelationshipOfNoteTag_Table.tagLocalId.eq(tagId))
.and(RelationshipOfNoteTag_Table.noteLocalId.eq(noteLocalId))
.querySingle();
}
public static void deleteAllRelatedTags(long noteLocalId, String userId) {
SQLite.delete()
.from(RelationshipOfNoteTag.class)
.where(RelationshipOfNoteTag_Table.userId.eq(userId))
.and(RelationshipOfNoteTag_Table.noteLocalId.eq(noteLocalId))
.async()
.execute();
}
public static void deleteRelatedTags(long noteLocalId, String userId, long firstReservedId, long... reservedIds) {
SQLite.delete()
.from(RelationshipOfNoteTag.class)
.where(RelationshipOfNoteTag_Table.userId.eq(userId))
.and(RelationshipOfNoteTag_Table.noteLocalId.eq(noteLocalId))
.and(RelationshipOfNoteTag_Table.id.notIn(firstReservedId, reservedIds))
.async()
.execute();
}
public static void deleteAll(String userId) {
SQLite.delete()
.from(Tag.class)
.where(Tag_Table.userId.eq(userId))
.execute();
}
}

View File

@@ -4,8 +4,6 @@ package org.houxg.leamonax.model;
import com.google.gson.annotations.SerializedName;
import com.raizlabs.android.dbflow.annotation.Column;
import org.houxg.leamonax.service.AccountService;
public class User extends BaseResponse {
@SerializedName("UserId")
@@ -37,7 +35,7 @@ public class User extends BaseResponse {
}
public String getAvatar() {
Account current = AccountService.getCurrent();
Account current = Account.getCurrent();
String host = current.getHost();
if(host.equals("https://leanote.com")){
return avatar;}

View File

@@ -9,7 +9,6 @@ import org.houxg.leamonax.network.api.AuthApi;
import org.houxg.leamonax.network.api.NoteApi;
import org.houxg.leamonax.network.api.NotebookApi;
import org.houxg.leamonax.network.api.UserApi;
import org.houxg.leamonax.service.AccountService;
import java.io.IOException;
@@ -30,7 +29,7 @@ public class ApiProvider {
}
public static ApiProvider getInstance() {
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
if (account != null && SingletonHolder.INSTANCE.mApiRetrofit == null) {
SingletonHolder.INSTANCE.init(account.getHost());
}
@@ -51,7 +50,7 @@ public class ApiProvider {
HttpUrl newUrl = url;
if (shouldAddTokenToQuery(path)) {
newUrl = url.newBuilder()
.addQueryParameter("token", AccountService.getCurrent().getAccessToken())
.addQueryParameter("token", Account.getCurrent().getAccessToken())
.build();
}
Request newRequest = request.newBuilder()

View File

@@ -1,10 +1,7 @@
package org.houxg.leamonax.service;
import com.raizlabs.android.dbflow.sql.language.Select;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.AccountDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Account_Table;
import org.houxg.leamonax.model.Authentication;
import org.houxg.leamonax.model.BaseResponse;
import org.houxg.leamonax.model.User;
@@ -30,7 +27,7 @@ public class AccountService {
}
public static long saveToAccount(Authentication authentication, String host) {
Account localAccount = AppDataBase.getAccount(authentication.getEmail(), host);
Account localAccount = AccountDataStore.getAccount(authentication.getEmail(), host);
if (localAccount == null) {
localAccount = new Account();
}
@@ -44,7 +41,7 @@ public class AccountService {
}
public static void saveToAccount(User user, String host) {
Account localAccount = AppDataBase.getAccount(user.getEmail(), host);
Account localAccount = AccountDataStore.getAccount(user.getEmail(), host);
if (localAccount == null) {
localAccount = new Account();
}
@@ -58,7 +55,7 @@ public class AccountService {
}
public static void logout() {
Account account = getCurrent();
Account account = Account.getCurrent();
account.setAccessToken("");
account.update();
}
@@ -71,22 +68,11 @@ public class AccountService {
return RetrofitUtils.create(ApiProvider.getInstance().getUserApi().updateUsername(userName));
}
public static Account getCurrent() {
return AppDataBase.getAccountWithToken();
}
public static List<Account> getAccountList() {
return AppDataBase.getAccountListWithToken();
}
public static Account getAccountById(long id) {
return new Select()
.from(Account.class)
.where(Account_Table.id.eq(id))
.querySingle();
return AccountDataStore.getAccountListWithToken();
}
public static boolean isSignedIn() {
return getCurrent() != null;
return Account.getCurrent() != null;
}
}

View File

@@ -7,7 +7,8 @@ import com.elvishew.xlog.XLog;
import org.bson.types.ObjectId;
import org.houxg.leamonax.Leamonax;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.NoteFileDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.NoteFile;
import java.io.File;
@@ -32,7 +33,7 @@ public class NoteFileService {
private static final String IMAGE_PATH_WITH_SLASH = "/getImage";
public static String convertFromLocalIdToServerId(String localId) {
NoteFile noteFile = AppDataBase.getNoteFileByLocalId(localId);
NoteFile noteFile = NoteFileDataStore.getByLocalId(localId);
return noteFile == null ? null : noteFile.getServerId();
}
@@ -51,7 +52,7 @@ public class NoteFileService {
}
public static Uri getServerImageUri(String serverId) {
Uri uri = Uri.parse(AccountService.getCurrent().getHost());
Uri uri = Uri.parse(Account.getCurrent().getHost());
return uri.buildUpon().appendEncodedPath("api/file/getImage").appendQueryParameter("fileId", serverId).build();
}
@@ -61,7 +62,7 @@ public class NoteFileService {
public static String getImagePath(Uri uri) {
String localId = uri.getQueryParameter("id");
NoteFile noteFile = AppDataBase.getNoteFileByLocalId(localId);
NoteFile noteFile = NoteFileDataStore.getByLocalId(localId);
if (noteFile == null) {
return null;
}
@@ -74,11 +75,11 @@ public class NoteFileService {
}
public static List<NoteFile> getRelatedNoteFiles(long noteLocalId) {
return AppDataBase.getAllRelatedFile(noteLocalId);
return NoteFileDataStore.getAllRelated(noteLocalId);
}
public static InputStream getImage(String localId) {
NoteFile noteFile = AppDataBase.getNoteFileByLocalId(localId);
NoteFile noteFile = NoteFileDataStore.getByLocalId(localId);
if (noteFile == null) {
return null;
}
@@ -87,7 +88,7 @@ public class NoteFileService {
filePath = noteFile.getLocalPath();
XLog.i(TAG + "use local image, path=" + filePath);
} else {
String url = NoteFileService.getUrl(AccountService.getCurrent().getHost(), noteFile.getServerId(), AccountService.getCurrent().getAccessToken());
String url = NoteFileService.getUrl(Account.getCurrent().getHost(), noteFile.getServerId(), Account.getCurrent().getAccessToken());
XLog.i(TAG + "use server image, url=" + url);
try {
filePath = NoteFileService.getImageFromServer(Uri.parse(url), Leamonax.getContext().getCacheDir());

View File

@@ -7,16 +7,16 @@ import android.text.TextUtils;
import android.webkit.MimeTypeMap;
import com.elvishew.xlog.XLog;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import org.bson.types.ObjectId;
import org.houxg.leamonax.R;
import org.houxg.leamonax.ReadableException;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.NoteDataStore;
import org.houxg.leamonax.database.NoteFileDataStore;
import org.houxg.leamonax.database.NotebookDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.model.NoteFile;
import org.houxg.leamonax.model.Note_Table;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.model.RelationshipOfNoteTag;
import org.houxg.leamonax.model.Tag;
@@ -39,7 +39,6 @@ import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import rx.Observable;
import rx.Subscriber;
public class NoteService {
@@ -50,14 +49,23 @@ public class NoteService {
private static final String CONFLICT_SUFFIX = "--conflict";
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() {
//sync notebook
int notebookUsn = AccountService.getCurrent().getNotebookUsn();
int notebookUsn = Account.getCurrent().getNotebookUsn();
List<Notebook> notebooks;
do {
notebooks = RetrofitUtils.excuteWithException(ApiProvider.getInstance().getNotebookApi().getSyncNotebooks(notebookUsn, MAX_ENTRY));
for (Notebook remoteNotebook : notebooks) {
Notebook localNotebook = AppDataBase.getNotebookByServerId(remoteNotebook.getNotebookId());
Notebook localNotebook = NotebookDataStore.getByServerId(remoteNotebook.getNotebookId());
if (localNotebook == null) {
XLog.i(TAG + "notebook insert, usn=" + remoteNotebook.getUsn() + ", id=" + remoteNotebook.getNotebookId());
remoteNotebook.insert();
@@ -68,7 +76,7 @@ public class NoteService {
remoteNotebook.update();
}
notebookUsn = remoteNotebook.getUsn();
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
account.setNotebookUsn(notebookUsn);
account.save();
}
@@ -76,13 +84,13 @@ public class NoteService {
//sync note
int noteUsn = AccountService.getCurrent().getNoteUsn();
int noteUsn = Account.getCurrent().getNoteUsn();
List<Note> notes;
do {
notes = RetrofitUtils.excuteWithException(ApiProvider.getInstance().getNoteApi().getSyncNotes(noteUsn, MAX_ENTRY));
for (Note noteMeta : notes) {
Note remoteNote = RetrofitUtils.excuteWithException(ApiProvider.getInstance().getNoteApi().getNoteAndContent(noteMeta.getNoteId()));
Note localNote = AppDataBase.getNoteByServerId(noteMeta.getNoteId());
Note localNote = NoteDataStore.getByServerId(noteMeta.getNoteId());
noteUsn = remoteNote.getUsn();
long localId;
if (localNote == null) {
@@ -116,7 +124,7 @@ public class NoteService {
remoteNote.update();
handleFile(localId, remoteNote.getNoteFiles());
updateTagsToLocal(localId, remoteNote.getTagData());
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
account.setNoteUsn(noteUsn);
account.save();
}
@@ -132,9 +140,9 @@ public class NoteService {
for (NoteFile remote : remoteFiles) {
NoteFile local;
if (TextUtils.isEmpty(remote.getLocalId())) {
local = AppDataBase.getNoteFileByServerId(remote.getServerId());
local = NoteFileDataStore.getByServerId(remote.getServerId());
} else {
local = AppDataBase.getNoteFileByLocalId(remote.getLocalId());
local = NoteFileDataStore.getByLocalId(remote.getLocalId());
}
if (local != null) {
XLog.i(TAG + "has local file, id=" + remote.getServerId());
@@ -149,20 +157,20 @@ public class NoteService {
local.save();
excepts.add(local.getLocalId());
}
AppDataBase.deleteFileExcept(noteLocalId, excepts);
NoteFileDataStore.deleteExcept(noteLocalId, excepts);
}
private static String convertToLocalImageLinkForRichText(long noteLocalId, String noteContent) {
return StringUtils.replace(noteContent,
"<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>",
String.format(Locale.US, "\\ssrc\\s*=\\s*\"%s/api/file/getImage\\?fileId=.*?\"", AccountService.getCurrent().getHost()),
String.format(Locale.US, "\\ssrc\\s*=\\s*\"%s/api/file/getImage\\?fileId=.*?\"", Account.getCurrent().getHost()),
new StringUtils.Replacer() {
@Override
public String replaceWith(String original, Object... extraData) {
XLog.i(TAG + "in=" + original);
Uri linkUri = Uri.parse(original.substring(6, original.length() - 1));
String serverId = linkUri.getQueryParameter("fileId");
NoteFile noteFile = AppDataBase.getNoteFileByServerId(serverId);
NoteFile noteFile = NoteFileDataStore.getByServerId(serverId);
if (noteFile == null) {
noteFile = new NoteFile();
noteFile.setNoteId((Long) extraData[0]);
@@ -180,14 +188,14 @@ public class NoteService {
private static String convertToLocalImageLinkForMD(long noteLocalId, String noteContent) {
return StringUtils.replace(noteContent,
String.format(Locale.US, "!\\[.*?\\]\\(%s/api/file/getImage\\?fileId=.*?\\)", AccountService.getCurrent().getHost()),
String.format(Locale.US, "\\(%s/api/file/getImage\\?fileId=.*?\\)", AccountService.getCurrent().getHost()),
String.format(Locale.US, "!\\[.*?\\]\\(%s/api/file/getImage\\?fileId=.*?\\)", Account.getCurrent().getHost()),
String.format(Locale.US, "\\(%s/api/file/getImage\\?fileId=.*?\\)", Account.getCurrent().getHost()),
new StringUtils.Replacer() {
@Override
public String replaceWith(String original, Object... extraData) {
Uri linkUri = Uri.parse(original.substring(1, original.length() - 1));
String serverId = linkUri.getQueryParameter("fileId");
NoteFile noteFile = AppDataBase.getNoteFileByServerId(serverId);
NoteFile noteFile = NoteFileDataStore.getByServerId(serverId);
if (noteFile == null) {
noteFile = new NoteFile();
noteFile.setNoteId((Long) extraData[0]);
@@ -202,7 +210,7 @@ public class NoteService {
}
public static void saveNote(final long noteLocalId) {
Note modifiedNote = AppDataBase.getNoteByLocalId(noteLocalId);
Note modifiedNote = NoteDataStore.getByLocalId(noteLocalId);
Map<String, RequestBody> requestBodyMap = generateCommonBodyMap(modifiedNote);
List<MultipartBody.Part> fileBodies = handleFileBodies(modifiedNote, requestBodyMap);
@@ -210,7 +218,7 @@ public class NoteService {
if (modifiedNote.isLocalNote()) {
call = ApiProvider.getInstance().getNoteApi().add(requestBodyMap, fileBodies);
} else {
Note remoteNote = RetrofitUtils.excuteWithException(getNoteByServerId(modifiedNote.getNoteId()));
Note remoteNote = RetrofitUtils.excuteWithException(ApiProvider.getInstance().getNoteApi().getNoteAndContent(modifiedNote.getNoteId()));
if (remoteNote.getUsn() != modifiedNote.getUsn()) {
remoteNote.setId(modifiedNote.getId());
remoteNote.update();
@@ -277,24 +285,12 @@ public class NoteService {
});
}
private static Call<List<Note>> getSyncNotes(int afterUsn, int maxEntry) {
return ApiProvider.getInstance().getNoteApi().getSyncNotes(afterUsn, maxEntry);
}
private static Call<List<Notebook>> getSyncNotebooks(int afterUsn, int maxEntry) {
return ApiProvider.getInstance().getNotebookApi().getSyncNotebooks(afterUsn, maxEntry);
}
public static Call<Note> getNoteByServerId(String serverId) {
return ApiProvider.getInstance().getNoteApi().getNoteAndContent(serverId);
}
public static boolean revertNote(String serverId) {
Note serverNote = RetrofitUtils.excute(NoteService.getNoteByServerId(serverId));
Note serverNote = RetrofitUtils.excute(ApiProvider.getInstance().getNoteApi().getNoteAndContent(serverId));
if (serverNote == null) {
return false;
}
Note localNote = AppDataBase.getNoteByServerId(serverId);
Note localNote = NoteDataStore.getByServerId(serverId);
long localId;
if (localNote == null) {
localId = serverNote.insert();
@@ -313,8 +309,6 @@ public class NoteService {
return true;
}
@NonNull
private static Map<String, RequestBody> generateCommonBodyMap(Note note) {
Map<String, RequestBody> requestBodyMap = new HashMap<>();
@@ -329,10 +323,11 @@ public class NoteService {
requestBodyMap.put("Content", createPartFromString(content));
requestBodyMap.put("IsMarkdown", createPartFromString(getBooleanString(note.isMarkDown())));
requestBodyMap.put("IsBlog", createPartFromString(getBooleanString(note.isPublicBlog())));
requestBodyMap.put("IsTrash", createPartFromString(getBooleanString(note.isTrash())));
requestBodyMap.put("CreatedTime", createPartFromString(TimeUtils.toServerTime(note.getCreatedTimeVal())));
requestBodyMap.put("UpdatedTime", createPartFromString(TimeUtils.toServerTime(note.getUpdatedTimeVal())));
List<Tag> tags = AppDataBase.getTagByNoteLocalId(note.getId());
List<Tag> tags = Tag.getByNoteLocalId(note.getId());
if (CollectionUtils.isNotEmpty(tags)) {
int size = tags.size();
@@ -354,8 +349,8 @@ public class NoteService {
} else {
imageLocalIds = getImagesFromContentForRichText(note.getContent());
}
AppDataBase.deleteFileExcept(note.getId(), imageLocalIds);
List<NoteFile> files = AppDataBase.getAllRelatedFile(note.getId());
NoteFileDataStore.deleteExcept(note.getId(), imageLocalIds);
List<NoteFile> files = NoteFileDataStore.getAllRelated(note.getId());
if (CollectionUtils.isNotEmpty(files)) {
int size = files.size();
for (int index = 0; index < size; index++) {
@@ -405,45 +400,46 @@ public class NoteService {
return localIds;
}
public static Observable<Note> deleteNote(final Note note) {
return Observable.create(
new Observable.OnSubscribe<Note>() {
@Override
public void call(Subscriber<? super Note> subscriber) {
if (!subscriber.isUnsubscribed()) {
if (TextUtils.isEmpty(note.getNoteId())) {
AppDataBase.deleteNoteByLocalId(note.getId());
} else {
UpdateRe response = RetrofitUtils.excuteWithException(
ApiProvider.getInstance().getNoteApi().delete(note.getNoteId(), note.getUsn()));
if (response.isOk()) {
AppDataBase.deleteNoteByLocalId(note.getId());
updateNoteUsnIfNeed(response.getUsn());
} else {
throw new IllegalStateException(response.getMsg());
}
}
subscriber.onNext(note);
subscriber.onCompleted();
}
}
});
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) {
if (note.isLocalNote()) {
note.delete();
} else {
Call<UpdateRe> call = ApiProvider.getInstance().getNoteApi().delete(note.getNoteId(), note.getUsn());
UpdateRe response = RetrofitUtils.excuteWithException(call);
if (response.isOk()) {
note.delete();
updateNoteUsnIfNeed(response.getUsn());
} else {
throw new IllegalStateException(response.getMsg());
}
}
}
/**
* if new usn equals to (current usn + 1), then just simply update usn without syncing.
*/
private static void updateNoteUsnIfNeed(int newUsn) {
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
if (newUsn - account.getNoteUsn() == 1) {
account.setNoteUsn(newUsn);
account.update();
}
}
public static Call<UpdateRe> deleteNote(String noteId, int usn) {
return ApiProvider.getInstance().getNoteApi().delete(noteId, usn);
}
public static void updateTagsToLocal(long noteLocalId, List<String> tags) {
String currentUid = AccountService.getCurrent().getUserId();
String currentUid = Account.getCurrent().getUserId();
if (tags == null) {
tags = new ArrayList<>();
}
@@ -453,7 +449,7 @@ public class NoteService {
if (TextUtils.isEmpty(tagText)) {
continue;
}
Tag tag = AppDataBase.getTagByText(tagText, currentUid);
Tag tag = Tag.getByText(tagText, currentUid);
long tagId;
long relationShipId;
RelationshipOfNoteTag relationShip;
@@ -464,7 +460,7 @@ public class NoteService {
tagId = tag.getId();
}
relationShip = AppDataBase.getRelationShip(noteLocalId, tagId, currentUid);
relationShip = Tag.getRelationShip(noteLocalId, tagId, currentUid);
if (relationShip == null) {
relationShip = new RelationshipOfNoteTag(noteLocalId, tagId, currentUid);
relationShipId = relationShip.insert();
@@ -474,9 +470,9 @@ public class NoteService {
reservedIds.add(relationShipId);
}
if (CollectionUtils.isEmpty(reservedIds)) {
AppDataBase.deleteAllRelatedTags(noteLocalId, currentUid);
Tag.deleteAllRelatedTags(noteLocalId, currentUid);
} else {
AppDataBase.deleteRelatedTags(noteLocalId,
Tag.deleteRelatedTags(noteLocalId,
currentUid,
reservedIds.get(0),
CollectionUtils.toPrimitive(reservedIds.subList(1, reservedIds.size()))
@@ -484,7 +480,6 @@ public class NoteService {
}
}
private static RequestBody createPartFromString(String content) {
return RequestBody.create(MediaType.parse(MULTIPART_FORM_DATA), content);
}
@@ -509,15 +504,4 @@ public class NoteService {
RequestBody fileBody = RequestBody.create(MediaType.parse(mimeType), tempFile);
return MultipartBody.Part.createFormData(String.format("FileDatas[%s]", noteFile.getLocalId()), tempFile.getName(), fileBody);
}
public static List<Note> searchNoteWithTitle(String keyword) {
keyword = String.format(Locale.US, "%%%s%%", keyword);
return SQLite.select()
.from(Note.class)
.where(Note_Table.userId.eq(AccountService.getCurrent().getUserId()))
.and(Note_Table.title.like(keyword))
.and(Note_Table.isTrash.eq(false))
.and(Note_Table.isDeleted.eq(false))
.queryList();
}
}

View File

@@ -3,7 +3,7 @@ package org.houxg.leamonax.service;
import com.elvishew.xlog.XLog;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.NotebookDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.network.ApiProvider;
@@ -19,7 +19,7 @@ public class NotebookService {
throw new IllegalStateException("Network error");
}
if (notebook.isOk()) {
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
if (notebook.getUsn() - account.getNotebookUsn() == 1) {
XLog.d(TAG + "update usn=" + notebook.getUsn());
account.setNotebookUsn(notebook.getUsn());
@@ -33,7 +33,7 @@ public class NotebookService {
}
public static String getTitle(long notebookLocalId) {
Notebook notebook = AppDataBase.getNotebookByLocalId(notebookLocalId);
Notebook notebook = NotebookDataStore.getByLocalId(notebookLocalId);
return notebook != null ? notebook.getTitle() : "";
}
@@ -44,7 +44,7 @@ public class NotebookService {
throw new IllegalStateException("Network error");
}
if (newNotebook.isOk()) {
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
if (notebook.getUsn() - account.getNotebookUsn() == 1) {
account.setNotebookUsn(notebook.getUsn());
account.save();

View File

@@ -13,8 +13,8 @@ import org.bson.types.ObjectId;
import org.houxg.leamonax.BuildConfig;
import org.houxg.leamonax.R;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.service.AccountService;
import org.houxg.leamonax.utils.OpenUtils;
import org.houxg.leamonax.utils.TestUtils;
@@ -54,7 +54,7 @@ public class AboutActivity extends BaseActivity {
new Observable.OnSubscribe<Void>() {
@Override
public void call(Subscriber<? super Void> subscriber) {
String userId = AccountService.getCurrent().getUserId();
String userId = Account.getCurrent().getUserId();
SecureRandom random = new SecureRandom();
String notebookId = new ObjectId().toString();
List<Note> notes = new ArrayList<>(8000);

View File

@@ -15,7 +15,7 @@ public class LaunchActivity extends Activity {
super.onCreate(savedInstanceState);
Intent intent;
if (AccountService.isSignedIn()) {
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
ApiProvider.getInstance().init(account.getHost());
intent = MainActivity.getOpenIntent(this, false);
} else {

View File

@@ -19,17 +19,16 @@ import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.houxg.leamonax.R;
import org.houxg.leamonax.background.NoteSyncService;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.component.PullToRefresh;
import org.houxg.leamonax.database.NotebookDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.model.SyncEvent;
import org.houxg.leamonax.service.AccountService;
import org.houxg.leamonax.ui.edit.NoteEditActivity;
import org.houxg.leamonax.utils.NetworkUtils;
import org.houxg.leamonax.utils.ToastUtils;
import java.util.List;
import java.util.Locale;
import butterknife.BindView;
@@ -45,9 +44,8 @@ public class MainActivity extends BaseActivity implements Navigation.Callback {
@BindView(R.id.drawer)
View mNavigationView;
@BindView(R.id.swiperefresh)
SwipeRefreshLayout mSwipeRefresh;
PullToRefresh mPullToRefresh;
Navigation mNavigation;
public static Intent getOpenIntent(Context context, boolean shouldReload) {
@@ -64,7 +62,7 @@ public class MainActivity extends BaseActivity implements Navigation.Callback {
initToolBar((Toolbar) findViewById(R.id.toolbar));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_white);
CrashReport.setUserId(AccountService.getCurrent().getUserId());
CrashReport.setUserId(Account.getCurrent().getUserId());
mNavigation = new Navigation(this);
mNavigation.init(this, mNavigationView);
@@ -78,31 +76,26 @@ public class MainActivity extends BaseActivity implements Navigation.Callback {
mNoteFragment = (NoteFragment) getSupportFragmentManager().findFragmentByTag(TAG_NOTE_FRAGMENT);
}
mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
syncNotes();
}
});
mPullToRefresh = new PullToRefresh(
(SwipeRefreshLayout) findViewById(R.id.swiperefresh),
new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
syncNotes();
}
});
EventBus.getDefault().register(this);
if (shouldReload) {
mSwipeRefresh.postDelayed(new Runnable() {
@Override
public void run() {
XLog.i("fetching notes");
mSwipeRefresh.setRefreshing(true);
syncNotes();
}
}, 200);
mPullToRefresh.forceRefresh();
}
}
private void syncNotes() {
if (!NetworkUtils.isNetworkAvailable()) {
ToastUtils.showNetworkUnavailable(MainActivity.this);
mSwipeRefresh.setRefreshing(false);
mPullToRefresh.stopRefreshing();
return;
}
NoteSyncService.startServiceForNote(MainActivity.this);
@@ -149,15 +142,15 @@ public class MainActivity extends BaseActivity implements Navigation.Callback {
@OnClick(R.id.fab)
void clickedFab() {
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
Note newNote = new Note();
newNote.setUserId(account.getUserId());
Notebook notebook;
Navigation.Mode currentMode = mNavigation.getCurrentMode();
if (currentMode == Navigation.Mode.NOTEBOOK) {
notebook = AppDataBase.getNotebookByLocalId(currentMode.notebookId);
NoteFragment.Mode currentMode = mNavigation.getCurrentMode();
if (currentMode == NoteFragment.Mode.NOTEBOOK) {
notebook = NotebookDataStore.getByLocalId(currentMode.notebookId);
} else {
notebook = AppDataBase.getRecentNoteBook(AccountService.getCurrent().getUserId());
notebook = NotebookDataStore.getRecentNoteBook(Account.getCurrent().getUserId());
}
if (notebook != null) {
newNote.setNoteBookId(notebook.getNotebookId());
@@ -177,28 +170,14 @@ public class MainActivity extends BaseActivity implements Navigation.Callback {
account.updateLastUseTime();
account.update();
mNavigation.refresh();
mSwipeRefresh.setRefreshing(true);
mPullToRefresh.stopRefreshing();
syncNotes();
return true;
}
@Override
public boolean onShowNotes(Navigation.Mode mode) {
List<Note> notes;
switch (mode) {
case RECENT_NOTES:
notes = AppDataBase.getAllNotes(AccountService.getCurrent().getUserId());
break;
case NOTEBOOK:
notes = AppDataBase.getNotesFromNotebook(AccountService.getCurrent().getUserId(), mode.notebookId);
break;
case TAG:
notes = AppDataBase.getNotesByTagText(mode.tagText, AccountService.getCurrent().getUserId());
break;
default:
return false;
}
mNoteFragment.setNotes(notes);
public boolean onShowNotes(NoteFragment.Mode mode) {
mNoteFragment.setMode(mode);
return true;
}
@@ -217,7 +196,7 @@ public class MainActivity extends BaseActivity implements Navigation.Callback {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(SyncEvent event) {
XLog.i("RequestNotes rcv: isSucceed=" + event.isSucceed());
mSwipeRefresh.setRefreshing(false);
mPullToRefresh.stopRefreshing();
if (event.isSucceed()) {
mNavigation.refresh();
} else {

View File

@@ -29,6 +29,7 @@ import org.houxg.leamonax.R;
import org.houxg.leamonax.adapter.AccountAdapter;
import org.houxg.leamonax.adapter.NotebookAdapter;
import org.houxg.leamonax.adapter.TagAdapter;
import org.houxg.leamonax.database.AccountDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.model.Tag;
@@ -96,7 +97,7 @@ public class Navigation {
private TagAdapter mTagAdapter;
private AlphabetDrawable mAlphabetDrawable = new AlphabetDrawable();
private Mode mCurrentMode = Mode.RECENT_NOTES;
private NoteFragment.Mode mCurrentMode = NoteFragment.Mode.RECENT_NOTES;
public Navigation(Callback callback) {
mCallback = callback;
@@ -112,7 +113,7 @@ public class Navigation {
}
private void fetchInfo() {
AccountService.getInfo(AccountService.getCurrent().getUserId())
AccountService.getInfo(Account.getCurrent().getUserId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@@ -128,8 +129,8 @@ public class Navigation {
@Override
public void onNext(User user) {
AccountService.saveToAccount(user, AccountService.getCurrent().getHost());
refreshUserInfo(AccountService.getCurrent());
AccountService.saveToAccount(user, Account.getCurrent().getHost());
refreshUserInfo(Account.getCurrent());
mAccountAdapter.notifyDataSetChanged();
}
});
@@ -264,7 +265,7 @@ public class Navigation {
mTagAdapter.setListener(new TagAdapter.TagAdapterListener() {
@Override
public void onClickedTag(Tag tag) {
mCurrentMode = Mode.TAG;
mCurrentMode = NoteFragment.Mode.TAG;
mCurrentMode.setTagText(tag.getText());
if (mCallback != null) {
if (mCallback.onShowNotes(mCurrentMode)) {
@@ -288,7 +289,7 @@ public class Navigation {
mNotebookAdapter.setListener(new NotebookAdapter.NotebookAdapterListener() {
@Override
public void onClickedNotebook(Notebook notebook) {
mCurrentMode = Mode.NOTEBOOK;
mCurrentMode = NoteFragment.Mode.NOTEBOOK;
mCurrentMode.setNotebookId(notebook.getId());
if (mCallback != null) {
if (mCallback.onShowNotes(mCurrentMode)) {
@@ -454,17 +455,17 @@ public class Navigation {
}
}
public Mode getCurrentMode() {
public NoteFragment.Mode getCurrentMode() {
return mCurrentMode;
}
public void refresh() {
refreshUserInfo(AccountService.getCurrent());
refreshUserInfo(Account.getCurrent());
mAccountAdapter.load(AccountService.getAccountList());
mTagAdapter.refresh();
mNotebookAdapter.refresh();
if (mCurrentMode == Mode.NOTEBOOK && TextUtils.isEmpty(mNotebookAdapter.getCurrentParentId())) {
mCurrentMode = Mode.RECENT_NOTES;
if (mCurrentMode == NoteFragment.Mode.NOTEBOOK && TextUtils.isEmpty(mNotebookAdapter.getCurrentParentId())) {
mCurrentMode = NoteFragment.Mode.RECENT_NOTES;
}
if (mCallback != null) {
if (mCallback.onShowNotes(mCurrentMode)) {
@@ -504,7 +505,7 @@ public class Navigation {
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQ_ADD_ACCOUNT) {
if (resultCode == RESULT_OK) {
Account account = AccountService.getAccountById(SignInActivity.getAccountIdFromData(data));
Account account = AccountDataStore.getAccountById(SignInActivity.getAccountIdFromData(data));
if (account != null) {
changeAccount(account);
}
@@ -545,7 +546,7 @@ public class Navigation {
@OnClick(R.id.rl_recent_notes)
void clickedRecent() {
mCurrentMode = Mode.RECENT_NOTES;
mCurrentMode = NoteFragment.Mode.RECENT_NOTES;
if (mCallback != null) {
if (mCallback.onShowNotes(mCurrentMode)) {
close();
@@ -560,41 +561,16 @@ public class Navigation {
* @param mode
* @return true if processed
*/
boolean onShowNotes(Mode mode);
boolean onShowNotes(NoteFragment.Mode mode);
void onClickSetting();
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 + '\'' +
'}';
}
}
@OnClick(R.id.rl_blog)
void clickedMyBlog() {
Account current = AccountService.getCurrent();
Account current = Account.getCurrent();
String host = current.getHost();
if (host == null || host.equals("")) {
host = "https://leanote.com";

View File

@@ -6,10 +6,7 @@ import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -17,18 +14,13 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.elvishew.xlog.XLog;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.houxg.leamonax.Leamonax;
import org.houxg.leamonax.R;
import org.houxg.leamonax.adapter.NoteAdapter;
import org.houxg.leamonax.background.NoteSyncService;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.NoteDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.model.SyncEvent;
import org.houxg.leamonax.service.AccountService;
import org.houxg.leamonax.service.NoteService;
import org.houxg.leamonax.utils.ActionModeHandler;
import org.houxg.leamonax.utils.CollectionUtils;
@@ -40,12 +32,12 @@ import org.houxg.leamonax.widget.NoteList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import butterknife.BindView;
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;
@@ -63,6 +55,7 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
List<Note> mNotes;
ActionModeHandler<Note> mActionModeHandler;
NoteList mNoteList;
Mode mCurrentMode;
public NoteFragment() {
}
@@ -129,7 +122,27 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
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;
Collections.sort(mNotes, new Note.UpdateTimeComparetor());
mNoteList.render(mNotes);
@@ -151,12 +164,44 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
mNoteList.setSelected(note, isSelected);
}
private void deleteNote(final List<Note> notes) {
private void deleteNote(List<Note> notes) {
Observable.from(notes)
.flatMap(new Func1<Note, rx.Observable<Note>>() {
@Override
public rx.Observable<Note> call(Note note) {
return NoteService.deleteNote(note);
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.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.onCompleted();
}
}
});
}
})
.subscribeOn(Schedulers.io())
@@ -169,8 +214,12 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
@Override
public void onError(Throwable e) {
ToastUtils.show(getActivity(), R.string.delete_note_failed);
mNoteList.invalidateAllSelected();
if (e instanceof NetworkUtils.NetworkUnavailableException) {
ToastUtils.show(Leamonax.getContext(), R.string.delete_network_error);
} else {
ToastUtils.show(Leamonax.getContext(), R.string.delete_note_failed);
}
refresh();
}
@Override
@@ -180,6 +229,9 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
});
}
private void refresh() {
setMode(mCurrentMode);
}
@Override
public boolean onAction(int actionId, List<Note> pendingItems) {
@@ -208,8 +260,6 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mActionModeHandler.dismiss();
mNoteList.invalidateAllSelected();
}
})
.show();
@@ -223,4 +273,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 + '\'' +
'}';
}
}
}

View File

@@ -15,7 +15,7 @@ import com.tencent.bugly.crashreport.CrashReport;
import org.houxg.leamonax.BuildConfig;
import org.houxg.leamonax.R;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.NoteDataStore;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.service.NoteService;
import org.houxg.leamonax.ui.edit.EditorFragment;
@@ -56,7 +56,7 @@ public class NotePreviewActivity extends BaseActivity implements EditorFragment.
ButterKnife.bind(this);
initToolBar((Toolbar) findViewById(R.id.toolbar), true);
long noteLocalId = getIntent().getLongExtra(EXT_NOTE_LOCAL_ID, -1);
mNote = AppDataBase.getNoteByLocalId(noteLocalId);
mNote = NoteDataStore.getByLocalId(noteLocalId);
if (mNote == null) {
ToastUtils.show(this, R.string.note_not_found);
CrashReport.postCatchedException(new IllegalStateException("Note not found while preview, localId=" + noteLocalId));
@@ -113,7 +113,7 @@ public class NotePreviewActivity extends BaseActivity implements EditorFragment.
if (requestCode == REQ_EDIT) {
switch (resultCode) {
case RESULT_OK:
mNote = AppDataBase.getNoteByLocalId(mNote.getId());
mNote = NoteDataStore.getByLocalId(mNote.getId());
if (mNote == null) {
finish();
} else {
@@ -163,7 +163,7 @@ public class NotePreviewActivity extends BaseActivity implements EditorFragment.
@Override
public void onNext(Long aLong) {
mNote = AppDataBase.getNoteByLocalId(mNote.getId());
mNote = NoteDataStore.getByLocalId(mNote.getId());
mNote.setIsDirty(false);
mNote.save();
refresh();
@@ -205,7 +205,7 @@ public class NotePreviewActivity extends BaseActivity implements EditorFragment.
@Override
public void call(Boolean isSucceed) {
if (isSucceed) {
mNote = AppDataBase.getNoteByServerId(mNote.getNoteId());
mNote = NoteDataStore.getByServerId(mNote.getNoteId());
refresh();
}
}

View File

@@ -1,11 +1,7 @@
package org.houxg.leamonax.ui;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
@@ -13,40 +9,18 @@ import android.view.View;
import android.widget.ImageView;
import org.houxg.leamonax.R;
import org.houxg.leamonax.adapter.NoteAdapter;
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.ButterKnife;
import rx.Observable;
import rx.Observer;
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)
Toolbar mToolbar;
@BindView(R.id.search)
SearchView mSearchView;
List<Note> mNotes = new ArrayList<>();
private NoteAdapter mAdapter;
private ActionModeHandler<Note> mActionModeHandler;
private float mScrollPosition;
private NoteFragment mNoteFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -55,27 +29,6 @@ public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdap
ButterKnife.bind(this);
initToolBar(mToolbar, true);
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() {
@Override
public boolean onQueryTextSubmit(String query) {
@@ -84,11 +37,18 @@ public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdap
@Override
public boolean onQueryTextChange(String newText) {
searchTitle(newText);
NoteFragment.Mode mode = NoteFragment.Mode.SEARCH;
mode.setKeywords(newText);
mNoteFragment.setMode(mode);
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);
searchCloseIcon.setImageResource(R.drawable.ic_clear);
final ImageView searchIcon = (ImageView) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
@@ -105,119 +65,4 @@ public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdap
mSearchView.setIconified(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 = NoteService.searchNoteWithTitle(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(Note note) {
return NoteService.deleteNote(note);
}
})
.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.getPendingItems().clear();
mActionModeHandler.dismiss();
deleteNote(waitToDelete);
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mActionModeHandler.dismiss();
mAdapter.invalidateAllSelected();
}
})
.show();
return true;
}
@Override
public void onDestroy(List<Note> pendingItems) {
if (CollectionUtils.isNotEmpty(pendingItems)) {
mAdapter.invalidateAllSelected();
}
}
}

View File

@@ -14,20 +14,18 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import org.houxg.leamonax.BuildConfig;
import org.houxg.leamonax.R;
import org.houxg.leamonax.database.NoteDataStore;
import org.houxg.leamonax.database.NoteTagDataStore;
import org.houxg.leamonax.database.NotebookDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.BaseResponse;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.model.RelationshipOfNoteTag;
import org.houxg.leamonax.model.Note_Table;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.model.Notebook_Table;
import org.houxg.leamonax.model.RelationshipOfNoteTag_Table;
import org.houxg.leamonax.model.RelationshipOfNoteTag;
import org.houxg.leamonax.model.Tag;
import org.houxg.leamonax.model.Tag_Table;
import org.houxg.leamonax.service.AccountService;
import org.houxg.leamonax.utils.ToastUtils;
@@ -76,11 +74,11 @@ public class SettingsActivity extends BaseActivity {
void selectEditor() {
new AlertDialog.Builder(this)
.setTitle(R.string.choose_editor)
.setSingleChoiceItems(mEditors, AccountService.getCurrent().getDefaultEditor(), new DialogInterface.OnClickListener() {
.setSingleChoiceItems(mEditors, Account.getCurrent().getDefaultEditor(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
account.setDefaultEditor(which);
account.update();
mEditorTv.setText(mEditors[which]);
@@ -128,7 +126,7 @@ public class SettingsActivity extends BaseActivity {
void clickedUserName() {
View view = LayoutInflater.from(this).inflate(R.layout.dialog_sigle_edittext, null);
final EditText mUserNameEt = (EditText) view.findViewById(R.id.edit);
mUserNameEt.setText(AccountService.getCurrent().getUserName());
mUserNameEt.setText(Account.getCurrent().getUserName());
new AlertDialog.Builder(this)
.setTitle(R.string.change_user_name)
.setView(view)
@@ -191,27 +189,15 @@ public class SettingsActivity extends BaseActivity {
@Override
public void call(Subscriber<? super Void> subscriber) {
if (!subscriber.isUnsubscribed()) {
Account currentUser = AccountService.getCurrent();
SQLite.delete()
.from(Note.class)
.where(Note_Table.userId.eq(currentUser.getUserId()))
.execute();
SQLite.delete()
.from(Notebook.class)
.where(Notebook_Table.userId.eq(currentUser.getUserId()))
.execute();
SQLite.delete()
.from(Tag.class)
.where(Tag_Table.userId.eq(currentUser.getUserId()))
.execute();
SQLite.delete()
.from(RelationshipOfNoteTag.class)
.where(RelationshipOfNoteTag_Table.userId.eq(currentUser.getUserId()))
.execute();
Account account = AccountService.getCurrent();
account.setNoteUsn(0);
account.setNotebookUsn(0);
account.update();
Account currentUser = Account.getCurrent();
String userId = currentUser.getUserId();
NoteDataStore.deleteAll(userId);
NotebookDataStore.deleteAll(userId);
Tag.deleteAll(userId);
NoteTagDataStore.deleteAll(userId);
currentUser.setNoteUsn(0);
currentUser.setNotebookUsn(0);
currentUser.update();
subscriber.onNext(null);
subscriber.onCompleted();
}
@@ -240,18 +226,18 @@ public class SettingsActivity extends BaseActivity {
@Override
public void onError(Throwable e) {
ToastUtils.showNetworkError(SettingsActivity.this);
mUserNameTv.setText(AccountService.getCurrent().getUserName());
mUserNameTv.setText(Account.getCurrent().getUserName());
}
@Override
public void onNext(BaseResponse baseResponse) {
if (baseResponse.isOk()) {
Account account = AccountService.getCurrent();
Account account = Account.getCurrent();
account.setUserName(username);
account.update();
ToastUtils.show(SettingsActivity.this, R.string.change_user_name_successful);
} else {
mUserNameTv.setText(AccountService.getCurrent().getUserName());
mUserNameTv.setText(Account.getCurrent().getUserName());
ToastUtils.show(SettingsActivity.this, R.string.change_user_name_failed);
}
}
@@ -285,7 +271,7 @@ public class SettingsActivity extends BaseActivity {
}
private void refresh() {
Account current = AccountService.getCurrent();
Account current = Account.getCurrent();
mEditorTv.setText(mEditors[current.getDefaultEditor()]);
mUserNameTv.setText(current.getUserName());
mEmailTv.setText(current.getEmail());

View File

@@ -41,7 +41,6 @@ import org.houxg.leamonax.utils.DialogUtils;
import org.houxg.leamonax.utils.OpenUtils;
import org.houxg.leamonax.widget.ToggleImageButton;
import java.io.File;
import java.util.List;
import java.util.Map;

View File

@@ -17,7 +17,7 @@ import com.elvishew.xlog.XLog;
import org.houxg.leamonax.Leamonax;
import org.houxg.leamonax.R;
import org.houxg.leamonax.ReadableException;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.NoteDataStore;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.model.Tag;
import org.houxg.leamonax.service.NoteFileService;
@@ -82,8 +82,8 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi
return;
}
mIsNewNote = getIntent().getBooleanExtra(EXT_IS_NEW_NOTE, false);
mOriginal = new Wrapper(AppDataBase.getNoteByLocalId(noteLocalId));
mModified = new Wrapper(AppDataBase.getNoteByLocalId(noteLocalId));
mOriginal = new Wrapper(NoteDataStore.getByLocalId(noteLocalId));
mModified = new Wrapper(NoteDataStore.getByLocalId(noteLocalId));
setResult(RESULT_CANCELED);
}
@@ -156,7 +156,7 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi
@Override
public void onNext(Long noteLocalId) {
Note localNote = AppDataBase.getNoteByLocalId(noteLocalId);
Note localNote = NoteDataStore.getByLocalId(noteLocalId);
localNote.setIsDirty(false);
localNote.save();
}
@@ -185,7 +185,7 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi
if (mIsNewNote && isTitleContentEmpty(wrapper.note)) {
XLog.i(TAG + "remove empty note, id=" + wrapper.note.getId());
AppDataBase.deleteNoteByLocalId(wrapper.note.getId());
wrapper.note.delete();
} else {
saveAsDraft(wrapper);
}
@@ -232,7 +232,7 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi
if (mIsNewNote && isTitleContentEmpty(wrapper.note)) {
XLog.i(TAG + "remove empty note, id=" + wrapper.note.getId());
AppDataBase.deleteNoteByLocalId(wrapper.note.getId());
wrapper.note.delete();
} else {
saveAsDraft(wrapper);
}
@@ -287,7 +287,7 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi
private void saveAsDraft(Wrapper wrapper) {
Note modifiedNote = wrapper.note;
XLog.i(TAG + "saveAsDraft(), local id=" + modifiedNote.getId());
Note noteFromDb = AppDataBase.getNoteByLocalId(modifiedNote.getId());
Note noteFromDb = NoteDataStore.getByLocalId(modifiedNote.getId());
noteFromDb.setContent(modifiedNote.getContent());
noteFromDb.setTitle(modifiedNote.getTitle());
noteFromDb.setNoteBookId(modifiedNote.getNoteBookId());
@@ -376,7 +376,7 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi
public Wrapper(Note note) {
this.note = note;
List<Tag> tags = AppDataBase.getTagByNoteLocalId(note.getId());
List<Tag> tags = Tag.getByNoteLocalId(note.getId());
this.tags = new ArrayList<>();
for (Tag tag : tags) {
this.tags.add(tag.getText());

View File

@@ -18,10 +18,10 @@ import android.widget.Switch;
import android.widget.TextView;
import org.houxg.leamonax.R;
import org.houxg.leamonax.database.AppDataBase;
import org.houxg.leamonax.database.NotebookDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Notebook;
import org.houxg.leamonax.model.Tag;
import org.houxg.leamonax.service.AccountService;
import org.houxg.leamonax.utils.CollectionUtils;
import org.houxg.leamonax.utils.DialogUtils;
import org.houxg.leamonax.utils.DisplayUtils;
@@ -63,7 +63,7 @@ public class SettingFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_settings, container, false);
ButterKnife.bind(this, view);
List<Tag> tags = AppDataBase.getAllTags(AccountService.getCurrent().getUserId());
List<Tag> tags = Tag.getAllTags(Account.getCurrent().getUserId());
String[] tagTexts = new String[tags.size()];
int i = 0;
for (Tag tag : tags) {
@@ -136,7 +136,7 @@ public class SettingFragment extends Fragment {
public void setNotebookId(String notebookId) {
mNoteBookId = notebookId;
if (!TextUtils.isEmpty(mNoteBookId)) {
Notebook notebook = AppDataBase.getNotebookByServerId(mNoteBookId);
Notebook notebook = NotebookDataStore.getByServerId(mNoteBookId);
if (notebook != null) {
mNotebookTv.setText(notebook.getTitle());
}

View File

@@ -48,11 +48,12 @@ public class ActionModeHandler<T> {
@Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mContext.getWindow().setStatusBarColor(mContext.getResources().getColor(R.color.colorPrimary));
}
mCallback.onDestroy(mPendingItems);
mActionMode = null;
mPendingItems = null;
}
};

View File

@@ -66,6 +66,10 @@ public class NoteList {
mAdapter.notifyDataSetChanged();
}
public void setHighlight(String keyword) {
mAdapter.setHighlight(keyword);
}
public void toggleType() {
int newType = mCurrentType == TYPE_SIMPLE ? TYPE_DETAIL : TYPE_SIMPLE;
setType(newType);

View File

@@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:background="@color/white"
android:orientation="vertical">
<include layout="@layout/toolbar" />

View File

@@ -18,7 +18,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#fff"
android:background="@color/white"
android:gravity="center_vertical|end"
android:paddingEnd="16dp"
android:paddingStart="16dp"

View File

@@ -21,9 +21,9 @@
</android.support.v7.widget.Toolbar>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"/>
</LinearLayout>

View File

@@ -87,7 +87,7 @@
android:paddingStart="4dp"
android:paddingTop="2dp"
android:text="@string/changed"
android:textColor="#fff"
android:textColor="@color/white"
android:textSize="12sp" />
<TextView

View File

@@ -81,7 +81,7 @@
android:paddingStart="4dp"
android:paddingTop="2dp"
android:text="@string/changed"
android:textColor="#fff"
android:textColor="@color/white"
android:textSize="12sp" />
<TextView

View File

@@ -49,7 +49,7 @@
android:paddingStart="4dp"
android:paddingTop="2dp"
android:text="@string/changed"
android:textColor="#fff"
android:textColor="@color/white"
android:textSize="12sp" />
<TextView

View File

@@ -112,4 +112,5 @@
<string name="update_notebook_title">修改笔记本的名称</string>
<string name="notebook_choose_notebook_hint">选择该笔记本所在的上一级笔记本目录</string>
<string name="notebook_default_root_notebook_title">空目录(最顶层目录)</string>
<string name="delete_network_error">网络不可用,将在下次同步时删除</string>
</resources>

View File

@@ -114,4 +114,5 @@
<string name="update_notebook_title">Update notebook title</string>
<string name="notebook_choose_notebook_hint">选择该笔记本所在的上一级笔记本目录 Choose current Notebook \'s parentNotebook directory</string>
<string name="notebook_default_root_notebook_title">Empty directory</string>
<string name="delete_network_error">Network is unavailable, these notes will be deleted in next sync</string>
</resources>