mirror of
https://github.com/leanote/leanote-android.git
synced 2025-10-17 16:07:48 +00:00
Merge branch 'develop'
This commit is contained in:
@@ -10,6 +10,7 @@ repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven { url "https://www.jitpack.io" }
|
||||
maven { url "http://dl.bintray.com/piasy/maven" }
|
||||
}
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'com.neenbedankt.android-apt'
|
||||
@@ -17,7 +18,7 @@ apply plugin: 'com.neenbedankt.android-apt'
|
||||
def dbflow_version = "4.0.0-beta2"
|
||||
def ciName = isEmpty(System.getenv("TRAVIS_TAG")) ? "Staging" : System.getenv("TRAVIS_TAG")
|
||||
def ciCode = isEmpty(System.getenv("TRAVIS_BUILD_NUMBER")) ? 1000 : Integer.valueOf(System.getenv("TRAVIS_BUILD_NUMBER"))
|
||||
|
||||
def buglyPrdKey = isEmpty(System.getenv('BUGLY_PRD')) ? "" : System.getenv('BUGLY_PRD')
|
||||
def isEmpty(String str) {
|
||||
return str == null || "".equals(str);
|
||||
}
|
||||
@@ -56,6 +57,7 @@ android {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.config
|
||||
buildConfigField "String", "BUGLY_KEY", String.format("\"%s\"", buglyPrdKey)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,11 +65,8 @@ android {
|
||||
def properties = new Properties();
|
||||
if (buildType.isDebuggable()) {
|
||||
properties.load(new FileInputStream(new File(projectDir.absolutePath + "/staging.properties")))
|
||||
} else {
|
||||
properties.load(new FileInputStream(new File(projectDir.absolutePath + "/production.properties")))
|
||||
buildType.buildConfigField "String", "BUGLY_KEY", properties['BUGLY_KEY']
|
||||
}
|
||||
buildType.buildConfigField "String", "FLURRY_KEY", properties['FLURRY_KEY']
|
||||
buildType.buildConfigField "String", "BUGLY_KEY", properties['BUGLY_KEY']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,5 +110,6 @@ dependencies {
|
||||
compile 'net.danlew:android.joda:2.9.5'
|
||||
compile group: 'com.tencent.bugly', name: 'crashreport_upgrade', version: '1.2.1'
|
||||
compile 'com.elvishew:xlog:1.3.0'
|
||||
|
||||
compile 'com.github.piasy:BigImageViewer:1.2.5'
|
||||
compile 'com.github.piasy:GlideImageLoader:1.2.5'
|
||||
}
|
||||
|
@@ -1,2 +0,0 @@
|
||||
FLURRY_KEY="M6HD6WJPT9Y274MG2FSF"
|
||||
BUGLY_KEY="cf1aa1ccff"
|
@@ -45,6 +45,8 @@
|
||||
<activity
|
||||
android:name=".ui.AboutActivity"
|
||||
android:label="@string/about" />
|
||||
<activity
|
||||
android:name=".ui.PictureViewerActivity" />
|
||||
|
||||
<service
|
||||
android:name=".background.NoteSyncService"
|
||||
|
@@ -32,6 +32,10 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -184,6 +188,10 @@
|
||||
var title = target.innerHTML;
|
||||
e.preventDefault();
|
||||
nativeCallbackHandler.linkTo(link);
|
||||
} else if (target.tagName === 'IMG') {
|
||||
var src = target.getAttribute('src');
|
||||
e.preventDefault();
|
||||
nativeCallbackHandler.onClickedImage(src);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,10 +4,13 @@ package org.houxg.leamonax;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.elvishew.xlog.LogLevel;
|
||||
import com.elvishew.xlog.XLog;
|
||||
import com.facebook.stetho.Stetho;
|
||||
import com.github.piasy.biv.BigImageViewer;
|
||||
import com.github.piasy.biv.loader.glide.GlideImageLoader;
|
||||
import com.raizlabs.android.dbflow.config.FlowConfig;
|
||||
import com.raizlabs.android.dbflow.config.FlowManager;
|
||||
import com.tencent.bugly.Bugly;
|
||||
@@ -31,16 +34,20 @@ public class Leamonax extends Application {
|
||||
super.onCreate();
|
||||
mContext = this;
|
||||
XLog.init(BuildConfig.DEBUG ? LogLevel.ALL : LogLevel.NONE);
|
||||
initBugly();
|
||||
|
||||
if (!TextUtils.isEmpty(BuildConfig.BUGLY_KEY)) {
|
||||
initBugly();
|
||||
}
|
||||
BigImageViewer.initialize(GlideImageLoader.with(this));
|
||||
EventBus.builder()
|
||||
.logNoSubscriberMessages(false)
|
||||
.sendNoSubscriberEvent(false)
|
||||
.throwSubscriberException(true)
|
||||
.installDefaultEventBus();
|
||||
FlowManager.init(new FlowConfig.Builder(this).build());
|
||||
Stetho.initializeWithDefaults(this);
|
||||
JodaTimeAndroid.init(this);
|
||||
if (BuildConfig.DEBUG) {
|
||||
Stetho.initializeWithDefaults(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void initBugly() {
|
||||
|
125
app/src/main/java/org/houxg/leamonax/adapter/AccountAdapter.java
Normal file
125
app/src/main/java/org/houxg/leamonax/adapter/AccountAdapter.java
Normal file
@@ -0,0 +1,125 @@
|
||||
package org.houxg.leamonax.adapter;
|
||||
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import org.houxg.leamonax.R;
|
||||
import org.houxg.leamonax.model.Account;
|
||||
import org.houxg.leamonax.model.Note;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import jp.wasabeef.glide.transformations.CropCircleTransformation;
|
||||
|
||||
public class AccountAdapter extends RecyclerView.Adapter<AccountAdapter.AccountHolder> {
|
||||
|
||||
private static final int TYPE_ADD = 345;
|
||||
private static final int TYPE_ACCOUNT = 592;
|
||||
private List<Account> mData;
|
||||
private AccountAdapterListener mListener;
|
||||
|
||||
public AccountAdapter(AccountAdapterListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
public void load(List<Account> source) {
|
||||
mData = source;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountAdapter.AccountHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
int layoutId = viewType == TYPE_ADD ? R.layout.item_add_account : R.layout.item_account;
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
|
||||
return new AccountHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return position != getItemCount() - 1 ? TYPE_ACCOUNT : TYPE_ADD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(AccountAdapter.AccountHolder holder, int position) {
|
||||
if (getItemViewType(position) == TYPE_ADD) {
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mListener != null) {
|
||||
mListener.onClickAddAccount();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
final Account account = mData.get(position);
|
||||
holder.emailTv.setText(account.getEmail());
|
||||
holder.hostTv.setText(account.getHost());
|
||||
if (!TextUtils.isEmpty(account.getAvatar())) {
|
||||
Glide.with(holder.avatarIv.getContext())
|
||||
.load(account.getAvatar())
|
||||
.centerCrop()
|
||||
.bitmapTransform(new CropCircleTransformation(holder.avatarIv.getContext()))
|
||||
.into(holder.avatarIv);
|
||||
}
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mListener != null ) {
|
||||
mListener.onClickAccount(v, account);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mData == null ? 1 : mData.size() + 1;
|
||||
}
|
||||
|
||||
public void delete(Note note) {
|
||||
int index = mData.indexOf(note);
|
||||
if (index >= 0) {
|
||||
mData.remove(index);
|
||||
notifyItemRemoved(index);
|
||||
}
|
||||
}
|
||||
|
||||
static class AccountHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
View itemView;
|
||||
|
||||
@Nullable
|
||||
@BindView(R.id.tv_email)
|
||||
TextView emailTv;
|
||||
@Nullable
|
||||
@BindView(R.id.tv_host)
|
||||
TextView hostTv;
|
||||
@Nullable
|
||||
@BindView(R.id.iv_avatar)
|
||||
ImageView avatarIv;
|
||||
|
||||
public AccountHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
this.itemView = itemView;
|
||||
}
|
||||
}
|
||||
|
||||
public interface AccountAdapterListener {
|
||||
void onClickAccount(View itemView, Account note);
|
||||
|
||||
void onClickAddAccount();
|
||||
}
|
||||
}
|
@@ -22,6 +22,7 @@ import org.houxg.leamonax.service.AccountService;
|
||||
import org.houxg.leamonax.utils.TimeUtils;
|
||||
import org.houxg.leamonax.widget.NoteList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -34,12 +35,12 @@ import butterknife.ButterKnife;
|
||||
public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder> {
|
||||
|
||||
|
||||
|
||||
private List<Note> mData;
|
||||
private Map<String, String> mNotebookId2TitleMaps;
|
||||
private NoteAdapterListener mListener;
|
||||
private Pattern mTitleHighlight;
|
||||
private int mCurrentType = NoteList.TYPE_SIMPLE;
|
||||
private List<Long> mSelectedNotes = new ArrayList<>();
|
||||
|
||||
public NoteAdapter(NoteAdapterListener listener) {
|
||||
mListener = listener;
|
||||
@@ -63,6 +64,21 @@ public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder> {
|
||||
mCurrentType = type;
|
||||
}
|
||||
|
||||
public void setSelected(Note note, boolean isSelected) {
|
||||
if (!isSelected ) {
|
||||
mSelectedNotes.remove(note.getId());
|
||||
notifyDataSetChanged();
|
||||
} else if (!mSelectedNotes.contains(note.getId())){
|
||||
mSelectedNotes.add(note.getId());
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidateAllSelected() {
|
||||
mSelectedNotes.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoteAdapter.NoteHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = null;
|
||||
@@ -95,6 +111,7 @@ public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder> {
|
||||
} else {
|
||||
renderSimple(holder, note);
|
||||
}
|
||||
holder.container.setSelected(mSelectedNotes.contains(note.getId()));
|
||||
}
|
||||
|
||||
private void renderDetail(NoteHolder holder, final Note note) {
|
||||
@@ -146,7 +163,7 @@ public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder> {
|
||||
});
|
||||
}
|
||||
|
||||
private void renderSimple(NoteHolder holder, final Note note) {
|
||||
private void renderSimple(final NoteHolder holder, final Note note) {
|
||||
if (TextUtils.isEmpty(note.getTitle())) {
|
||||
holder.titleTv.setText(R.string.untitled);
|
||||
} else {
|
||||
@@ -228,6 +245,8 @@ public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder> {
|
||||
TextView updateTimeTv;
|
||||
@BindView(R.id.tv_dirty)
|
||||
TextView dirtyTv;
|
||||
@BindView(R.id.container)
|
||||
View container;
|
||||
|
||||
public NoteHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
@@ -32,22 +32,6 @@ public class TagAdapter extends RecyclerView.Adapter<TagAdapter.TagHolder> {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void toggle() {
|
||||
int size = getItemCount();
|
||||
if (size == 0) {
|
||||
mData = AppDataBase.getAllTags(AccountService.getCurrent().getUserId());
|
||||
int newSize = getItemCount();
|
||||
if (newSize != 0) {
|
||||
notifyItemRangeInserted(0, newSize);
|
||||
} else {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
} else {
|
||||
mData = new ArrayList<>();
|
||||
notifyItemRangeRemoved(0, size);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view;
|
||||
|
@@ -32,7 +32,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Database(name = "leanote_db", version = 3)
|
||||
@Database(name = "leanote_db", version = 4)
|
||||
public class AppDataBase {
|
||||
|
||||
private static final String TAG = "AppDataBase:";
|
||||
@@ -127,6 +127,48 @@ public class AppDataBase {
|
||||
}
|
||||
}
|
||||
|
||||
@Migration(version = 4, priority = 1, database = AppDataBase.class)
|
||||
public static class AddColLastUseTime extends AlterTableMigration<Account> {
|
||||
|
||||
public AddColLastUseTime(Class<Account> table) {
|
||||
super(table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreMigrate() {
|
||||
super.onPreMigrate();
|
||||
addColumn(SQLiteType.INTEGER, "lastUseTime");
|
||||
}
|
||||
}
|
||||
|
||||
@Migration(version = 4, priority = 0, database = AppDataBase.class)
|
||||
public static class UpdateLastUseTime extends BaseMigration {
|
||||
|
||||
@Override
|
||||
public void migrate(DatabaseWrapper database) {
|
||||
Cursor cursor = SQLite.select()
|
||||
.from(Account.class)
|
||||
.where(Account_Table.token.notEq(""))
|
||||
.query(database);
|
||||
if (cursor == null) {
|
||||
return;
|
||||
}
|
||||
int idIndex = cursor.getColumnIndex("id");
|
||||
while (cursor.moveToNext()) {
|
||||
int id = cursor.getInt(idIndex);
|
||||
Account account = SQLite.select()
|
||||
.from(Account.class)
|
||||
.where(Account_Table.id.eq(id))
|
||||
.querySingle(database);
|
||||
if (account != null) {
|
||||
account.updateLastUseTime();
|
||||
account.update(database);
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteNoteByLocalId(long localId) {
|
||||
SQLite.delete().from(Note.class)
|
||||
.where(Note_Table.id.eq(localId))
|
||||
@@ -196,21 +238,19 @@ public class AppDataBase {
|
||||
}
|
||||
|
||||
public static Notebook getRecentNoteBook(String userId) {
|
||||
List<Note> recentNotes = SQLite.select()
|
||||
Note recentNotes = SQLite.select()
|
||||
.from(Note.class)
|
||||
.where(Note_Table.userId.eq(userId))
|
||||
.and(Note_Table.notebookId.notEq(""))
|
||||
.orderBy(Note_Table.updatedTime, false)
|
||||
.queryList();
|
||||
|
||||
if (CollectionUtils.isNotEmpty(recentNotes)) {
|
||||
for (Note note : recentNotes) {
|
||||
Notebook notebook = getNotebookByServerId(note.getNoteBookId());
|
||||
if (!notebook.isDeleted()) {
|
||||
return notebook;
|
||||
}
|
||||
.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))
|
||||
@@ -286,9 +326,18 @@ public class AppDataBase {
|
||||
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")
|
||||
|
@@ -80,6 +80,7 @@ public abstract class Editor {
|
||||
void onFormatChanged(Map<Format, Object> enabledFormats);
|
||||
void onCursorChanged(Map<Format, Object> enabledFormats);
|
||||
void linkTo(String url);
|
||||
void onClickedImage(String url);
|
||||
}
|
||||
|
||||
protected class EditorClient extends WebViewClient {
|
||||
|
@@ -156,6 +156,11 @@ public class RichTextEditor extends Editor implements TinnyMceCallback.TinnyMceL
|
||||
mListener.linkTo(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedImage(String url) {
|
||||
mListener.onClickedImage(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCursorChanged(Map<Format, Object> enabledFormats) {
|
||||
mListener.onCursorChanged(enabledFormats);
|
||||
|
@@ -25,6 +25,8 @@ public class TinnyMceCallback {
|
||||
|
||||
void linkTo(String url);
|
||||
|
||||
void onClickedImage(String url);
|
||||
|
||||
void onCursorChanged(Map<Editor.Format, Object> enabledFormats);
|
||||
}
|
||||
|
||||
@@ -43,6 +45,13 @@ public class TinnyMceCallback {
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public void onClickedImage(String url) {
|
||||
if (mListener != null) {
|
||||
mListener.onClickedImage(url);
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public void onCursorChanged(String data) {
|
||||
XLog.i(TAG + data);
|
||||
|
@@ -21,7 +21,6 @@ public class Account extends BaseModel {
|
||||
|
||||
@Column(name = "id")
|
||||
@PrimaryKey(autoincrement = true)
|
||||
@SerializedName("LocalUserId")
|
||||
long localUserId;
|
||||
@Column(name = "userId")
|
||||
@SerializedName("UserId")
|
||||
@@ -50,6 +49,8 @@ public class Account extends BaseModel {
|
||||
int noteUsn;
|
||||
@Column(name = "notebookUsn")
|
||||
int notebookUsn;
|
||||
@Column(name = "lastUseTime")
|
||||
long lastUseTime;
|
||||
|
||||
@Deprecated
|
||||
@Column(name = "lastUsn")
|
||||
@@ -161,6 +162,10 @@ public class Account extends BaseModel {
|
||||
this.notebookUsn = notebookUsn;
|
||||
}
|
||||
|
||||
public void updateLastUseTime() {
|
||||
lastUseTime = System.currentTimeMillis() / 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Account{" +
|
||||
|
@@ -63,7 +63,7 @@ public class ApiProvider {
|
||||
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
|
||||
@Override
|
||||
public void log(String message) {
|
||||
XLog.i(message);
|
||||
XLog.d(message);
|
||||
}
|
||||
});
|
||||
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
@@ -1,13 +1,18 @@
|
||||
package org.houxg.leamonax.service;
|
||||
|
||||
import com.raizlabs.android.dbflow.sql.language.Select;
|
||||
|
||||
import org.houxg.leamonax.database.AppDataBase;
|
||||
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;
|
||||
import org.houxg.leamonax.network.ApiProvider;
|
||||
import org.houxg.leamonax.utils.RetrofitUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
public class AccountService {
|
||||
@@ -24,7 +29,7 @@ public class AccountService {
|
||||
return RetrofitUtils.create(ApiProvider.getInstance().getUserApi().getInfo(userId));
|
||||
}
|
||||
|
||||
public static void saveToAccount(Authentication authentication, String host) {
|
||||
public static long saveToAccount(Authentication authentication, String host) {
|
||||
Account localAccount = AppDataBase.getAccount(authentication.getEmail(), host);
|
||||
if (localAccount == null) {
|
||||
localAccount = new Account();
|
||||
@@ -35,6 +40,7 @@ public class AccountService {
|
||||
localAccount.setUserId(authentication.getUserId());
|
||||
localAccount.setUserName(authentication.getUserName());
|
||||
localAccount.save();
|
||||
return localAccount.getLocalUserId();
|
||||
}
|
||||
|
||||
public static void saveToAccount(User user, String host) {
|
||||
@@ -69,6 +75,17 @@ public class AccountService {
|
||||
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();
|
||||
}
|
||||
|
||||
public static boolean isSignedIn() {
|
||||
return getCurrent() != null;
|
||||
}
|
||||
|
@@ -58,6 +58,20 @@ public class NoteFileService {
|
||||
return SCHEME.equals(uri.getScheme()) && IMAGE_PATH_WITH_SLASH.equals(uri.getPath());
|
||||
}
|
||||
|
||||
public static String getImagePath(Uri uri) {
|
||||
String localId = uri.getQueryParameter("id");
|
||||
NoteFile noteFile = AppDataBase.getNoteFileByLocalId(localId);
|
||||
if (noteFile == null) {
|
||||
return null;
|
||||
}
|
||||
if (!TextUtils.isEmpty(noteFile.getLocalPath())) {
|
||||
File file = new File(noteFile.getLocalPath());
|
||||
return file.isFile() ? noteFile.getLocalPath() : null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static InputStream getImage(String localId) {
|
||||
NoteFile noteFile = AppDataBase.getNoteFileByLocalId(localId);
|
||||
if (noteFile == null) {
|
||||
|
@@ -408,11 +408,11 @@ public class NoteService {
|
||||
return localIds;
|
||||
}
|
||||
|
||||
public static Observable<Void> deleteNote(final Note note) {
|
||||
public static Observable<Note> deleteNote(final Note note) {
|
||||
return Observable.create(
|
||||
new Observable.OnSubscribe<Void>() {
|
||||
new Observable.OnSubscribe<Note>() {
|
||||
@Override
|
||||
public void call(Subscriber<? super Void> subscriber) {
|
||||
public void call(Subscriber<? super Note> subscriber) {
|
||||
if (!subscriber.isUnsubscribed()) {
|
||||
if (TextUtils.isEmpty(note.getNoteId())) {
|
||||
AppDataBase.deleteNoteByLocalId(note.getId());
|
||||
@@ -426,7 +426,7 @@ public class NoteService {
|
||||
throw new IllegalStateException(response.getMsg());
|
||||
}
|
||||
}
|
||||
subscriber.onNext(null);
|
||||
subscriber.onNext(note);
|
||||
subscriber.onCompleted();
|
||||
}
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ public class NotebookService {
|
||||
|
||||
private static final String TAG = "NotebookService:";
|
||||
|
||||
public static void addNotebook(String title, String parentNotebookId) {
|
||||
public static Notebook addNotebook(String title, String parentNotebookId) {
|
||||
Notebook notebook = RetrofitUtils.excute(ApiProvider.getInstance().getNotebookApi().addNotebook(title, parentNotebookId));
|
||||
if (notebook == null) {
|
||||
throw new IllegalStateException("Network error");
|
||||
@@ -26,6 +26,7 @@ public class NotebookService {
|
||||
account.save();
|
||||
}
|
||||
notebook.insert();
|
||||
return notebook;
|
||||
} else {
|
||||
throw new IllegalStateException(notebook.getMsg());
|
||||
}
|
||||
|
@@ -2,81 +2,57 @@ package org.houxg.leamonax.ui;
|
||||
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityOptionsCompat;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.elvishew.xlog.XLog;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.houxg.leamonax.R;
|
||||
import org.houxg.leamonax.adapter.NotebookAdapter;
|
||||
import org.houxg.leamonax.adapter.TagAdapter;
|
||||
import org.houxg.leamonax.background.NoteSyncService;
|
||||
import org.houxg.leamonax.database.AppDataBase;
|
||||
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.model.Tag;
|
||||
import org.houxg.leamonax.model.User;
|
||||
import org.houxg.leamonax.service.AccountService;
|
||||
import org.houxg.leamonax.service.NotebookService;
|
||||
import org.houxg.leamonax.ui.edit.NoteEditActivity;
|
||||
import org.houxg.leamonax.utils.NetworkUtils;
|
||||
import org.houxg.leamonax.utils.ToastUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import jp.wasabeef.glide.transformations.CropCircleTransformation;
|
||||
import rx.Observable;
|
||||
import rx.Observer;
|
||||
import rx.Subscriber;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
|
||||
public class MainActivity extends BaseActivity implements NotebookAdapter.NotebookAdapterListener, TagAdapter.TagAdapterListener, NoteFragment.OnSyncFinishListener {
|
||||
public class MainActivity extends BaseActivity implements Navigation.Callback {
|
||||
|
||||
private static final String EXT_SHOULD_RELOAD = "ext_should_reload";
|
||||
private static final String TAG_NOTE_FRAGMENT = "tag_note_fragment";
|
||||
|
||||
NoteFragment mNoteFragment;
|
||||
NotebookAdapter mNotebookAdapter;
|
||||
|
||||
@BindView(R.id.rv_notebook)
|
||||
RecyclerView mNotebookRv;
|
||||
@BindView(R.id.drawer)
|
||||
DrawerLayout mDrawerLayout;
|
||||
@BindView(R.id.tv_email)
|
||||
TextView mEmailTv;
|
||||
@BindView(R.id.iv_avatar)
|
||||
ImageView mAvatarIv;
|
||||
@BindView(R.id.tv_user_name)
|
||||
TextView mUserNameTv;
|
||||
@BindView(R.id.iv_notebook_triangle)
|
||||
View mNotebookTriangle;
|
||||
@BindView(R.id.rl_notebook_list)
|
||||
View mNotebookPanel;
|
||||
@BindView(R.id.rv_tag)
|
||||
RecyclerView mTagRv;
|
||||
@BindView(R.id.iv_tag_triangle)
|
||||
View mTagTriangle;
|
||||
View mNavigationView;
|
||||
@BindView(R.id.swiperefresh)
|
||||
SwipeRefreshLayout mSwipeRefresh;
|
||||
|
||||
Navigation mNavigation;
|
||||
|
||||
public static Intent getOpenIntent(Context context, boolean shouldReload) {
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
@@ -93,42 +69,47 @@ public class MainActivity extends BaseActivity implements NotebookAdapter.Notebo
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_white);
|
||||
CrashReport.setUserId(AccountService.getCurrent().getUserId());
|
||||
|
||||
mNavigation = new Navigation(this);
|
||||
mNavigation.init(this, mNavigationView);
|
||||
|
||||
boolean shouldReload = false;
|
||||
if (savedInstanceState == null) {
|
||||
mNoteFragment = NoteFragment.newInstance(getIntent().getBooleanExtra(EXT_SHOULD_RELOAD, false));
|
||||
shouldReload = getIntent().getBooleanExtra(EXT_SHOULD_RELOAD, false);
|
||||
mNoteFragment = NoteFragment.newInstance();
|
||||
getSupportFragmentManager().beginTransaction().add(R.id.container, mNoteFragment, TAG_NOTE_FRAGMENT).commit();
|
||||
} else {
|
||||
mNoteFragment = (NoteFragment) getSupportFragmentManager().findFragmentByTag(TAG_NOTE_FRAGMENT);
|
||||
}
|
||||
mNoteFragment.setSyncFinishListener(this);
|
||||
mEmailTv.setText(AccountService.getCurrent().getEmail());
|
||||
initNotebookPanel();
|
||||
initTagPanel();
|
||||
|
||||
refreshInfo();
|
||||
fetchInfo();
|
||||
mSwipeRefresh.setOnRefreshListener(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);
|
||||
}
|
||||
}
|
||||
|
||||
private void initTagPanel() {
|
||||
mTagRv.setLayoutManager(new LinearLayoutManager(this));
|
||||
TagAdapter tagAdapter = new TagAdapter();
|
||||
tagAdapter.setListener(this);
|
||||
mTagRv.setAdapter(tagAdapter);
|
||||
mTagTriangle.setTag(false);
|
||||
}
|
||||
|
||||
private void initNotebookPanel() {
|
||||
mNotebookRv.setLayoutManager(new LinearLayoutManager(this));
|
||||
mNotebookAdapter = new NotebookAdapter();
|
||||
mNotebookAdapter.setListener(this);
|
||||
mNotebookRv.setAdapter(mNotebookAdapter);
|
||||
mNotebookAdapter.refresh();
|
||||
mNotebookTriangle.setTag(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
refreshNotebookAndNotes();
|
||||
private void syncNotes() {
|
||||
if (!NetworkUtils.isNetworkAvailable()) {
|
||||
ToastUtils.showNetworkUnavailable(MainActivity.this);
|
||||
mSwipeRefresh.setRefreshing(false);
|
||||
return;
|
||||
}
|
||||
NoteSyncService.startServiceForNote(MainActivity.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,14 +118,16 @@ public class MainActivity extends BaseActivity implements NotebookAdapter.Notebo
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mNavigation.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
mDrawerLayout.closeDrawer(GravityCompat.START, true);
|
||||
} else {
|
||||
mDrawerLayout.openDrawer(GravityCompat.START, true);
|
||||
}
|
||||
mNavigation.toggle();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_search) {
|
||||
Intent intent = new Intent(this, SearchActivity.class);
|
||||
@@ -153,106 +136,21 @@ public class MainActivity extends BaseActivity implements NotebookAdapter.Notebo
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
mNavigation.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
mDrawerLayout.closeDrawer(GravityCompat.START);
|
||||
if (mNavigation.isOpen()) {
|
||||
mNavigation.close();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchInfo() {
|
||||
AccountService.getInfo(AccountService.getCurrent().getUserId())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<User>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(User user) {
|
||||
AccountService.saveToAccount(user, AccountService.getCurrent().getHost());
|
||||
refreshInfo();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void refreshInfo() {
|
||||
Account account = AccountService.getCurrent();
|
||||
mUserNameTv.setText(account.getUserName());
|
||||
mEmailTv.setText(account.getEmail());
|
||||
if (!TextUtils.isEmpty(account.getAvatar())) {
|
||||
Glide.with(this)
|
||||
.load(account.getAvatar())
|
||||
.centerCrop()
|
||||
.bitmapTransform(new CropCircleTransformation(this))
|
||||
.into(mAvatarIv);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedNotebook(Notebook notebook) {
|
||||
mNoteFragment.loadFromNotebook(notebook.getId());
|
||||
mDrawerLayout.closeDrawer(GravityCompat.START, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedAddNotebook(final String parentNotebookId) {
|
||||
View view = LayoutInflater.from(this).inflate(R.layout.dialog_sigle_edittext, null);
|
||||
final EditText mEdit = (EditText) view.findViewById(R.id.edit);
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.add_notebook)
|
||||
.setView(view)
|
||||
.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
addNotebook(mEdit.getText().toString(), parentNotebookId);
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private void addNotebook(final String title, final String parentNotebookId) {
|
||||
Observable.create(
|
||||
new Observable.OnSubscribe<Void>() {
|
||||
@Override
|
||||
public void call(Subscriber<? super Void> subscriber) {
|
||||
if (!subscriber.isUnsubscribed()) {
|
||||
NotebookService.addNotebook(title, parentNotebookId);
|
||||
subscriber.onNext(null);
|
||||
subscriber.onCompleted();
|
||||
}
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Void>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(Void isSucceed) {
|
||||
mNotebookAdapter.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@OnClick(R.id.fab)
|
||||
void clickedFab() {
|
||||
Account account = AccountService.getCurrent();
|
||||
@@ -268,78 +166,62 @@ public class MainActivity extends BaseActivity implements NotebookAdapter.Notebo
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_recent_notes)
|
||||
void showRecentNote() {
|
||||
mNoteFragment.loadRecentNotes();
|
||||
mDrawerLayout.closeDrawer(GravityCompat.START, true);
|
||||
@Override
|
||||
public boolean onChangeAccount(Account account) {
|
||||
account.updateLastUseTime();
|
||||
account.update();
|
||||
mNavigation.refresh();
|
||||
mSwipeRefresh.setRefreshing(true);
|
||||
syncNotes();
|
||||
return true;
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_about)
|
||||
void clickedAbout() {
|
||||
Intent intent = new Intent(this, AboutActivity.class);
|
||||
startActivity(intent);
|
||||
@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);
|
||||
return true;
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_settings)
|
||||
void clickedSettings() {
|
||||
@Override
|
||||
public void onClickSetting() {
|
||||
Intent intent = new Intent(this, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_notebook)
|
||||
void toggleNotebook() {
|
||||
boolean shouldShowNotebook = (boolean) mNotebookTriangle.getTag();
|
||||
shouldShowNotebook = !shouldShowNotebook;
|
||||
animateTriangle(mNotebookTriangle, shouldShowNotebook);
|
||||
mNotebookPanel.setVisibility(shouldShowNotebook ? View.VISIBLE : View.GONE);
|
||||
mNotebookTriangle.setTag(shouldShowNotebook);
|
||||
@Override
|
||||
public void onClickAbout() {
|
||||
Intent intent = new Intent(this, AboutActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_tag)
|
||||
void toggleTag() {
|
||||
boolean shouldShowTag = (boolean) mTagTriangle.getTag();
|
||||
shouldShowTag = !shouldShowTag;
|
||||
animateTriangle(mTagTriangle, shouldShowTag);
|
||||
((TagAdapter) mTagRv.getAdapter()).toggle();
|
||||
mTagTriangle.setTag(shouldShowTag);
|
||||
}
|
||||
|
||||
private void animateTriangle(View triangle, boolean isOpen) {
|
||||
if (isOpen) {
|
||||
triangle.animate()
|
||||
.rotation(-180)
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateDecelerateInterpolator())
|
||||
.start();
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEvent(SyncEvent event) {
|
||||
XLog.i("RequestNotes rcv: isSucceed=" + event.isSucceed());
|
||||
mSwipeRefresh.setRefreshing(false);
|
||||
if (event.isSucceed()) {
|
||||
mNavigation.refresh();
|
||||
} else {
|
||||
triangle.animate()
|
||||
.rotation(0)
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateDecelerateInterpolator())
|
||||
.start();
|
||||
ToastUtils.show(this, R.string.sync_notes_failed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedTag(Tag tag) {
|
||||
mNoteFragment.loadFromTag(tag.getText());
|
||||
mDrawerLayout.closeDrawer(GravityCompat.START, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncFinish(SyncEvent event) {
|
||||
refreshNotebookAndNotes();
|
||||
}
|
||||
|
||||
private void refreshNotebookAndNotes() {
|
||||
mNotebookAdapter.refresh();
|
||||
if (mNoteFragment.getCurrentMode() == NoteFragment.Mode.NOTEBOOK) {
|
||||
if (TextUtils.isEmpty(mNotebookAdapter.getCurrentParentId())) {
|
||||
mNoteFragment.loadRecentNotes();
|
||||
} else {
|
||||
Notebook notebook = AppDataBase.getNotebookByServerId(mNotebookAdapter.getCurrentParentId());
|
||||
mNoteFragment.loadFromNotebook(notebook.getId());
|
||||
}
|
||||
}
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
}
|
||||
|
487
app/src/main/java/org/houxg/leamonax/ui/Navigation.java
Normal file
487
app/src/main/java/org/houxg/leamonax/ui/Navigation.java
Normal file
@@ -0,0 +1,487 @@
|
||||
package org.houxg.leamonax.ui;
|
||||
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.view.ViewGroupCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.elvishew.xlog.XLog;
|
||||
|
||||
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.model.Account;
|
||||
import org.houxg.leamonax.model.Notebook;
|
||||
import org.houxg.leamonax.model.Tag;
|
||||
import org.houxg.leamonax.model.User;
|
||||
import org.houxg.leamonax.service.AccountService;
|
||||
import org.houxg.leamonax.service.NotebookService;
|
||||
import org.houxg.leamonax.utils.DisplayUtils;
|
||||
import org.houxg.leamonax.widget.TriangleView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import jp.wasabeef.glide.transformations.CropCircleTransformation;
|
||||
import rx.Observable;
|
||||
import rx.Observer;
|
||||
import rx.Subscriber;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
public class Navigation {
|
||||
public static final int REQ_ADD_ACCOUNT = 55;
|
||||
@BindView(R.id.drawer)
|
||||
DrawerLayout mDrawerLayout;
|
||||
|
||||
@BindView(R.id.rl_info)
|
||||
View mInfoPanel;
|
||||
@BindView(R.id.tv_email)
|
||||
TextView mEmailTv;
|
||||
@BindView(R.id.iv_avatar)
|
||||
ImageView mAvatarIv;
|
||||
@BindView(R.id.tv_user_name)
|
||||
TextView mUserNameTv;
|
||||
@BindView(R.id.tr_account)
|
||||
TriangleView mAccountTr;
|
||||
@BindView(R.id.rv_account)
|
||||
RecyclerView mAccountRv;
|
||||
|
||||
@BindView(R.id.rv_notebook)
|
||||
RecyclerView mNotebookRv;
|
||||
@BindView(R.id.tr_notebook)
|
||||
TriangleView mNotebookTr;
|
||||
|
||||
@BindView(R.id.rv_tag)
|
||||
RecyclerView mTagRv;
|
||||
@BindView(R.id.tr_tag)
|
||||
TriangleView mTagTr;
|
||||
|
||||
Drawable mAccountRipple;
|
||||
|
||||
private Callback mCallback;
|
||||
private Activity mActivity;
|
||||
private NotebookAdapter mNotebookAdapter;
|
||||
private AccountAdapter mAccountAdapter;
|
||||
private TagAdapter mTagAdapter;
|
||||
|
||||
private Mode mCurrentMode = Mode.RECENT_NOTES;
|
||||
|
||||
public Navigation(Callback callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
public void init(Activity activity, View view) {
|
||||
ButterKnife.bind(this, view);
|
||||
mActivity = activity;
|
||||
initAccountPanel();
|
||||
initNotebookPanel();
|
||||
initTagPanel();
|
||||
fetchInfo();
|
||||
}
|
||||
|
||||
private void fetchInfo() {
|
||||
AccountService.getInfo(AccountService.getCurrent().getUserId())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<User>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(User user) {
|
||||
AccountService.saveToAccount(user, AccountService.getCurrent().getHost());
|
||||
refreshUserInfo(AccountService.getCurrent());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initAccountPanel() {
|
||||
mAccountRipple = mInfoPanel.getBackground();
|
||||
mAccountRipple.mutate();
|
||||
mInfoPanel.setBackground(null);
|
||||
mAccountRv.setLayoutManager(new LinearLayoutManager(mActivity));
|
||||
mAccountAdapter = new AccountAdapter(new AccountAdapter.AccountAdapterListener() {
|
||||
@Override
|
||||
public void onClickAccount(View v, final Account account) {
|
||||
animateChangeAccount(v, account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickAddAccount() {
|
||||
Intent intent = new Intent(mActivity, SignInActivity.class);
|
||||
mActivity.startActivityForResult(intent, REQ_ADD_ACCOUNT);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
mAccountRv.setAdapter(mAccountAdapter);
|
||||
mAccountTr.setOnToggleListener(
|
||||
new TriangleView.OnToggleListener() {
|
||||
@Override
|
||||
public void onToggle(boolean isChecked) {
|
||||
mAccountRv.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
);
|
||||
mAccountAdapter.load(AccountService.getAccountList());
|
||||
}
|
||||
|
||||
private void animateChangeAccount(View v, final Account account) {
|
||||
ImageView itemAvatar = (ImageView) v.findViewById(R.id.iv_avatar);
|
||||
final ViewGroup rootView = (ViewGroup) mActivity.getWindow().getDecorView().getRootView();
|
||||
|
||||
float preSize = DisplayUtils.dp2px(30);
|
||||
float postSize = DisplayUtils.dp2px(40);
|
||||
int[] position = new int[2];
|
||||
itemAvatar.getLocationInWindow(position);
|
||||
int preLeft = position[0];
|
||||
int preTop = position[1];
|
||||
mAvatarIv.getLocationInWindow(position);
|
||||
int postLeft = position[0];
|
||||
int postTop = position[1];
|
||||
|
||||
final ImageView animateView = new ImageView(mActivity);
|
||||
Drawable drawable = itemAvatar.getDrawable();
|
||||
drawable.mutate();
|
||||
animateView.setImageDrawable(drawable);
|
||||
animateView.setLayoutParams(new ViewGroup.LayoutParams((int) preSize, (int) preSize));
|
||||
animateView.setX(preLeft);
|
||||
animateView.setY(preTop);
|
||||
animateView.setPivotX(0);
|
||||
animateView.setPivotY(0);
|
||||
animateView.setAlpha(0.7f);
|
||||
rootView.addView(animateView);
|
||||
|
||||
animateView.animate()
|
||||
.scaleX(postSize / preSize)
|
||||
.scaleY(postSize / preSize)
|
||||
.translationX(postLeft)
|
||||
.translationY(postTop)
|
||||
.setDuration(350)
|
||||
.setInterpolator(new AccelerateDecelerateInterpolator())
|
||||
.setListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
//trigger quick ripple effect
|
||||
mInfoPanel.setBackground(mAccountRipple);
|
||||
mAccountRipple.setHotspot(mAvatarIv.getLeft() + mAvatarIv.getWidth() / 2, mAvatarIv.getTop() + mAvatarIv.getHeight() / 2);
|
||||
mAccountRipple.setHotspotBounds(0, 0, mInfoPanel.getWidth(), mInfoPanel.getHeight());
|
||||
mInfoPanel.setPressed(true);
|
||||
mInfoPanel.setPressed(false);
|
||||
|
||||
refreshUserInfo(account);
|
||||
rootView.removeView(animateView);
|
||||
mInfoPanel.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mInfoPanel.setBackground(null);
|
||||
changeAccount(account);
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
)
|
||||
.start();
|
||||
}
|
||||
|
||||
private void changeAccount(Account account) {
|
||||
if (mCallback != null) {
|
||||
if (mCallback.onChangeAccount(account)) {
|
||||
mAccountTr.setChecked(false);
|
||||
mTagTr.setChecked(false);
|
||||
mNotebookTr.setChecked(false);
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initTagPanel() {
|
||||
mTagRv.setLayoutManager(new LinearLayoutManager(mActivity));
|
||||
mTagAdapter = new TagAdapter();
|
||||
mTagAdapter.setListener(new TagAdapter.TagAdapterListener() {
|
||||
@Override
|
||||
public void onClickedTag(Tag tag) {
|
||||
mCurrentMode = Mode.TAG;
|
||||
mCurrentMode.setTagText(tag.getText());
|
||||
if (mCallback != null) {
|
||||
if (mCallback.onShowNotes(mCurrentMode)) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
mTagRv.setAdapter(mTagAdapter);
|
||||
mTagTr.setOnToggleListener(new TriangleView.OnToggleListener() {
|
||||
@Override
|
||||
public void onToggle(boolean isChecked) {
|
||||
mTagRv.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initNotebookPanel() {
|
||||
mNotebookRv.setLayoutManager(new LinearLayoutManager(mActivity));
|
||||
mNotebookAdapter = new NotebookAdapter();
|
||||
mNotebookAdapter.setListener(new NotebookAdapter.NotebookAdapterListener() {
|
||||
@Override
|
||||
public void onClickedNotebook(Notebook notebook) {
|
||||
mCurrentMode = Mode.NOTEBOOK;
|
||||
mCurrentMode.setNotebookId(notebook.getId());
|
||||
if (mCallback != null) {
|
||||
if (mCallback.onShowNotes(mCurrentMode)) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedAddNotebook(final String parentNotebookId) {
|
||||
View view = LayoutInflater.from(mActivity).inflate(R.layout.dialog_sigle_edittext, null);
|
||||
final EditText mEdit = (EditText) view.findViewById(R.id.edit);
|
||||
new AlertDialog.Builder(mActivity)
|
||||
.setTitle(R.string.add_notebook)
|
||||
.setView(view)
|
||||
.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
addNotebook(mEdit.getText().toString(), parentNotebookId);
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
});
|
||||
mNotebookRv.setAdapter(mNotebookAdapter);
|
||||
mNotebookAdapter.refresh();
|
||||
mNotebookTr.setOnToggleListener(new TriangleView.OnToggleListener() {
|
||||
@Override
|
||||
public void onToggle(boolean isChecked) {
|
||||
mNotebookRv.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addNotebook(final String title, final String parentNotebookId) {
|
||||
Observable.create(
|
||||
new Observable.OnSubscribe<Notebook>() {
|
||||
@Override
|
||||
public void call(Subscriber<? super Notebook> subscriber) {
|
||||
if (!subscriber.isUnsubscribed()) {
|
||||
subscriber.onNext(NotebookService.addNotebook(title, parentNotebookId));
|
||||
subscriber.onCompleted();
|
||||
}
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Notebook>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(Notebook isSucceed) {
|
||||
mNotebookAdapter.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void refreshUserInfo(Account account) {
|
||||
mUserNameTv.setText(account.getUserName());
|
||||
mEmailTv.setText(account.getEmail());
|
||||
if (!TextUtils.isEmpty(account.getAvatar())) {
|
||||
Glide.with(mActivity)
|
||||
.load(account.getAvatar())
|
||||
.centerCrop()
|
||||
.bitmapTransform(new CropCircleTransformation(mActivity))
|
||||
.into(mAvatarIv);
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
refreshUserInfo(AccountService.getCurrent());
|
||||
mAccountAdapter.load(AccountService.getAccountList());
|
||||
mTagAdapter.refresh();
|
||||
mNotebookAdapter.refresh();
|
||||
if (mCurrentMode == Mode.NOTEBOOK && TextUtils.isEmpty(mNotebookAdapter.getCurrentParentId())) {
|
||||
mCurrentMode = Mode.RECENT_NOTES;
|
||||
}
|
||||
if (mCallback != null) {
|
||||
if (mCallback.onShowNotes(mCurrentMode)) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void toggle() {
|
||||
if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
mDrawerLayout.closeDrawer(GravityCompat.START, true);
|
||||
} else {
|
||||
mDrawerLayout.openDrawer(GravityCompat.START, true);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return mDrawerLayout.isDrawerOpen(GravityCompat.START);
|
||||
}
|
||||
|
||||
public void open() {
|
||||
if (!isOpen()) {
|
||||
mDrawerLayout.openDrawer(GravityCompat.START, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (isOpen()) {
|
||||
mDrawerLayout.closeDrawer(GravityCompat.START, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
refresh();
|
||||
}
|
||||
|
||||
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));
|
||||
if (account != null) {
|
||||
changeAccount(account);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_notebook)
|
||||
void clickedNotebook() {
|
||||
mNotebookTr.toggle();
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_tag)
|
||||
void clickedTag() {
|
||||
mTagTr.toggle();
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_settings)
|
||||
void clickedSettings() {
|
||||
if (mCallback != null) {
|
||||
mCallback.onClickSetting();
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.iv_avatar)
|
||||
void clickedAvatar() {
|
||||
mAccountTr.toggle();
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_about)
|
||||
void clickedAbout() {
|
||||
if (mCallback != null) {
|
||||
mCallback.onClickAbout();
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.rl_recent_notes)
|
||||
void clickedRecent() {
|
||||
mCurrentMode = Mode.RECENT_NOTES;
|
||||
if (mCallback != null) {
|
||||
if (mCallback.onShowNotes(mCurrentMode)) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
boolean onChangeAccount(Account account);
|
||||
|
||||
/**
|
||||
* @param mode
|
||||
* @return true if processed
|
||||
*/
|
||||
boolean onShowNotes(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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,10 +7,9 @@ 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.DefaultItemAnimator;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
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;
|
||||
@@ -31,55 +30,46 @@ 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.DisplayUtils;
|
||||
import org.houxg.leamonax.utils.ActionModeHandler;
|
||||
import org.houxg.leamonax.utils.CollectionUtils;
|
||||
import org.houxg.leamonax.utils.NetworkUtils;
|
||||
import org.houxg.leamonax.utils.ToastUtils;
|
||||
import org.houxg.leamonax.widget.DividerDecoration;
|
||||
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.android.schedulers.AndroidSchedulers;
|
||||
import rx.functions.Func1;
|
||||
import rx.schedulers.Schedulers;
|
||||
|
||||
public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterListener {
|
||||
import static org.houxg.leamonax.R.menu.note;
|
||||
|
||||
public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterListener, ActionModeHandler.Callback<Note> {
|
||||
|
||||
private static final String TAG = "NoteFragment:";
|
||||
private static final String EXT_SCROLL_POSITION = "ext_scroll_position";
|
||||
private static final String EXT_SHOULD_FETCH_NOTES = "ext_should_fetch_notes";
|
||||
|
||||
private Mode mCurrentMode = Mode.RECENT_NOTES;
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView mNoteListView;
|
||||
@BindView(R.id.swiperefresh)
|
||||
SwipeRefreshLayout mSwipeRefresh;
|
||||
|
||||
NoteList mNoteList;
|
||||
|
||||
List<Note> mNotes;
|
||||
private OnSyncFinishListener mSyncFinishListener;
|
||||
ActionModeHandler<Note> mActionModeHandler;
|
||||
NoteList mNoteList;
|
||||
|
||||
public NoteFragment() {
|
||||
}
|
||||
|
||||
public static NoteFragment newInstance(boolean shouldFetchNotes) {
|
||||
public static NoteFragment newInstance() {
|
||||
NoteFragment fragment = new NoteFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(EXT_SHOULD_FETCH_NOTES, shouldFetchNotes);
|
||||
fragment.setArguments(bundle);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public void setSyncFinishListener(OnSyncFinishListener listener) {
|
||||
mSyncFinishListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -89,7 +79,7 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.note, menu);
|
||||
inflater.inflate(note, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,43 +96,16 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
||||
View view = inflater.inflate(R.layout.fragment_note, container, false);
|
||||
ButterKnife.bind(this, view);
|
||||
mNoteList = new NoteList(container.getContext(), view, this);
|
||||
mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
syncNotes();
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
|
||||
private void syncNotes() {
|
||||
if (!NetworkUtils.isNetworkAvailable(getActivity())) {
|
||||
ToastUtils.showNetworkUnavailable(getActivity());
|
||||
mSwipeRefresh.setRefreshing(false);
|
||||
return;
|
||||
}
|
||||
NoteSyncService.startServiceForNote(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
EventBus.getDefault().register(this);
|
||||
refreshNotes();
|
||||
if (savedInstanceState == null) {
|
||||
if (getArguments().getBoolean(EXT_SHOULD_FETCH_NOTES, false)) {
|
||||
mSwipeRefresh.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
XLog.i(TAG + "fetch notes");
|
||||
mSwipeRefresh.setRefreshing(true);
|
||||
syncNotes();
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
} else {
|
||||
if (savedInstanceState != null) {
|
||||
mNoteList.setScrollPosition(savedInstanceState.getInt(EXT_SCROLL_POSITION, 0));
|
||||
}
|
||||
mActionModeHandler = new ActionModeHandler<>(getActivity(), this, R.menu.delete);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,81 +114,50 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
||||
outState.putInt(EXT_SCROLL_POSITION, mNoteList.getScrollPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
|
||||
public void loadRecentNotes() {
|
||||
mCurrentMode = Mode.RECENT_NOTES;
|
||||
refreshNotes();
|
||||
}
|
||||
|
||||
public void loadFromNotebook(long notebookId) {
|
||||
mCurrentMode = Mode.NOTEBOOK;
|
||||
mCurrentMode.notebookId = notebookId;
|
||||
refreshNotes();
|
||||
}
|
||||
|
||||
public void loadFromTag(String tagText) {
|
||||
mCurrentMode = Mode.TAG;
|
||||
mCurrentMode.tagText = tagText;
|
||||
refreshNotes();
|
||||
}
|
||||
|
||||
public Mode getCurrentMode() {
|
||||
return mCurrentMode;
|
||||
}
|
||||
|
||||
private void refreshNotes() {
|
||||
XLog.i(TAG + "refresh:" + mCurrentMode);
|
||||
switch (mCurrentMode) {
|
||||
case RECENT_NOTES:
|
||||
mNotes = AppDataBase.getAllNotes(AccountService.getCurrent().getUserId());
|
||||
break;
|
||||
case NOTEBOOK:
|
||||
mNotes = AppDataBase.getNotesFromNotebook(AccountService.getCurrent().getUserId(), mCurrentMode.notebookId);
|
||||
break;
|
||||
case TAG:
|
||||
mNotes = AppDataBase.getNotesByTagText(mCurrentMode.tagText, AccountService.getCurrent().getUserId());
|
||||
}
|
||||
public void setNotes(List<Note> notes) {
|
||||
mNotes = notes;
|
||||
Collections.sort(mNotes, new Note.UpdateTimeComparetor());
|
||||
mNoteList.render(mNotes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickNote(Note note) {
|
||||
startActivity(NotePreviewActivity.getOpenIntent(getActivity(), note.getId()));
|
||||
if (mActionModeHandler.isActionMode()) {
|
||||
boolean isSelected = mActionModeHandler.chooseItem(note);
|
||||
mNoteList.setSelected(note, isSelected);
|
||||
} else {
|
||||
startActivity(NotePreviewActivity.getOpenIntent(getActivity(), note.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClickNote(final Note note) {
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.delete_note)
|
||||
.setMessage(String.format(Locale.US, getString(R.string.are_you_sure_to_delete_note), TextUtils.isEmpty(note.getTitle()) ? "this note" : note.getTitle()))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
deleteNote(note);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
boolean isSelected = mActionModeHandler.chooseItem(note);
|
||||
mNoteList.setSelected(note, isSelected);
|
||||
}
|
||||
|
||||
private void deleteNote(final Note note) {
|
||||
NoteService.deleteNote(note)
|
||||
private void deleteNote(final 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);
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Void>() {
|
||||
.subscribe(new Observer<Note>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
|
||||
@@ -234,56 +166,56 @@ public class NoteFragment extends Fragment implements NoteAdapter.NoteAdapterLis
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
ToastUtils.show(getActivity(), R.string.delete_note_failed);
|
||||
mNoteList.invalidateAllSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(Void aVoid) {
|
||||
public void onNext(Note note) {
|
||||
mNoteList.remove(note);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEvent(SyncEvent event) {
|
||||
XLog.i(TAG + "RequestNotes rcv: isSucceed=" + event.isSucceed());
|
||||
if (isAdded()) {
|
||||
mSwipeRefresh.setRefreshing(false);
|
||||
if (mSyncFinishListener != null) {
|
||||
mSyncFinishListener.onSyncFinish(event);
|
||||
}
|
||||
refreshNotes();
|
||||
if (!event.isSucceed()) {
|
||||
ToastUtils.show(getActivity(), R.string.sync_notes_failed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAction(int actionId, List<Note> pendingItems) {
|
||||
if (CollectionUtils.isEmpty(pendingItems)) {
|
||||
ToastUtils.show(getActivity(), 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(getActivity())
|
||||
.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();
|
||||
mActionModeHandler.dismiss();
|
||||
mNoteList.invalidateAllSelected();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(List<Note> pendingItems) {
|
||||
if (CollectionUtils.isNotEmpty(pendingItems)) {
|
||||
mNoteList.invalidateAllSelected();
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnSyncFinishListener {
|
||||
void onSyncFinish(SyncEvent event);
|
||||
}
|
||||
|
||||
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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -166,7 +166,7 @@ public class NotePreviewActivity extends BaseActivity implements EditorFragment.
|
||||
|
||||
@OnClick(R.id.tv_revert)
|
||||
void revert() {
|
||||
if (!NetworkUtils.isNetworkAvailable(this)) {
|
||||
if (!NetworkUtils.isNetworkAvailable()) {
|
||||
ToastUtils.showNetworkUnavailable(this);
|
||||
return;
|
||||
}
|
||||
|
@@ -0,0 +1,52 @@
|
||||
package org.houxg.leamonax.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.piasy.biv.view.BigImageView;
|
||||
|
||||
import org.houxg.leamonax.R;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class PictureViewerActivity extends BaseActivity {
|
||||
|
||||
private static final String EXTRA_FILE_PATH = "extra.filePath";
|
||||
|
||||
@BindView(R.id.big_image)
|
||||
BigImageView mBigImageView;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_picture_viewer);
|
||||
ButterKnife.bind(this);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setStatusBarColor(getResources().getColor(R.color.black));
|
||||
}
|
||||
|
||||
String path = getIntent().getStringExtra(EXTRA_FILE_PATH);
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
Uri uri = Uri.fromFile(new File(path));
|
||||
mBigImageView.showImage(uri);
|
||||
}
|
||||
|
||||
public static Intent getOpenIntent(Context context, String path) {
|
||||
Intent intent = new Intent(context, PictureViewerActivity.class);
|
||||
intent.putExtra(EXTRA_FILE_PATH, path);
|
||||
return intent;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -14,6 +14,7 @@ import android.transition.Slide;
|
||||
import android.transition.Transition;
|
||||
import android.transition.TransitionInflater;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.widget.ImageView;
|
||||
|
||||
@@ -21,6 +22,8 @@ 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.DisplayUtils;
|
||||
import org.houxg.leamonax.utils.ToastUtils;
|
||||
import org.houxg.leamonax.widget.DividerDecoration;
|
||||
@@ -32,11 +35,13 @@ import java.util.Locale;
|
||||
|
||||
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 {
|
||||
public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdapterListener, ActionModeHandler.Callback<Note> {
|
||||
|
||||
private static final String EXT_SCROLL_POSITION = "ext_scroll_position";
|
||||
|
||||
@@ -49,7 +54,7 @@ public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdap
|
||||
|
||||
List<Note> mNotes = new ArrayList<>();
|
||||
private NoteAdapter mAdapter;
|
||||
|
||||
private ActionModeHandler<Note> mActionModeHandler;
|
||||
private float mScrollPosition;
|
||||
|
||||
@Override
|
||||
@@ -62,12 +67,12 @@ 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());
|
||||
|
||||
mNoteListView.addItemDecoration(new DividerDecoration(DisplayUtils.dp2px(8)));
|
||||
|
||||
mAdapter = new NoteAdapter(this);
|
||||
mNoteListView.setAdapter(mAdapter);
|
||||
mNoteListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@@ -139,36 +144,31 @@ public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdap
|
||||
|
||||
@Override
|
||||
public void onClickNote(Note note) {
|
||||
startActivity(NotePreviewActivity.getOpenIntent(this, note.getId()));
|
||||
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) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.delete_note)
|
||||
.setMessage(String.format(Locale.US, getString(R.string.are_you_sure_to_delete_note), TextUtils.isEmpty(note.getTitle()) ? "this note" : note.getTitle()))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
deleteNote(note);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
boolean isSelected = mActionModeHandler.chooseItem(note);
|
||||
mAdapter.setSelected(note, isSelected);
|
||||
}
|
||||
|
||||
private void deleteNote(final Note note) {
|
||||
NoteService.deleteNote(note)
|
||||
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<Void>() {
|
||||
.subscribe(new Observer<Note>() {
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
|
||||
@@ -180,10 +180,50 @@ public class SearchActivity extends BaseActivity implements NoteAdapter.NoteAdap
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(Void aVoid) {
|
||||
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();
|
||||
mActionModeHandler.dismiss();
|
||||
mAdapter.invalidateAllSelected();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(List<Note> pendingItems) {
|
||||
if (CollectionUtils.isNotEmpty(pendingItems)) {
|
||||
mAdapter.invalidateAllSelected();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,6 +31,8 @@ import org.houxg.leamonax.model.Tag_Table;
|
||||
import org.houxg.leamonax.service.AccountService;
|
||||
import org.houxg.leamonax.utils.ToastUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
@@ -99,9 +101,12 @@ public class SettingsActivity extends BaseActivity {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
AccountService.logout();
|
||||
Intent intent = new Intent(SettingsActivity.this, SignInActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
List<Account> remainingAccount = AccountService.getAccountList();
|
||||
if (remainingAccount.size() == 0) {
|
||||
Intent intent = new Intent(SettingsActivity.this, SignInActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
})
|
||||
|
@@ -37,6 +37,8 @@ import rx.schedulers.Schedulers;
|
||||
|
||||
public class SignInActivity extends BaseActivity implements TextWatcher {
|
||||
|
||||
public static final String ACTION_ADD_ACCOUNT = "action.addAccount:";
|
||||
private static final String EXTRA_ACCOUNT_LOCAL_ID = "extra.account.LocalId";
|
||||
private static final String TAG = "SignInActivity:";
|
||||
|
||||
private static final String LEANOTE_HOST = "https://leanote.com";
|
||||
@@ -66,12 +68,13 @@ public class SignInActivity extends BaseActivity implements TextWatcher {
|
||||
@BindView(R.id.rl_sign_up)
|
||||
View mSignUpPanel;
|
||||
@BindView(R.id.tv_example)
|
||||
TextView mEampleTv;
|
||||
TextView mExampleTv;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_signin);
|
||||
setResult(RESULT_CANCELED);
|
||||
ButterKnife.bind(this);
|
||||
mEmailEt.addTextChangedListener(this);
|
||||
mPasswordEt.addTextChangedListener(this);
|
||||
@@ -103,7 +106,7 @@ public class SignInActivity extends BaseActivity implements TextWatcher {
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
mEampleTv.setText(String.format(Locale.US, "For example, login api will be:\n%s/api/login", s.toString()));
|
||||
mExampleTv.setText(String.format(Locale.US, "For example, login api will be:\n%s/api/login", s.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -126,7 +129,7 @@ public class SignInActivity extends BaseActivity implements TextWatcher {
|
||||
void switchHost() {
|
||||
boolean isCustomHost = !(boolean) mCustomHostBtn.getTag();
|
||||
mCustomHostBtn.setTag(isCustomHost);
|
||||
mEampleTv.setVisibility(isCustomHost ? View.VISIBLE : View.GONE);
|
||||
mExampleTv.setVisibility(isCustomHost ? View.VISIBLE : View.GONE);
|
||||
if (isCustomHost) {
|
||||
mCustomHostBtn.setText(R.string.use_leanote_host);
|
||||
mHostEt.animate()
|
||||
@@ -215,11 +218,17 @@ public class SignInActivity extends BaseActivity implements TextWatcher {
|
||||
@Override
|
||||
public void onNext(Authentication authentication) {
|
||||
if (authentication.isOk()) {
|
||||
AccountService.saveToAccount(authentication, host);
|
||||
Intent intent = MainActivity.getOpenIntent(SignInActivity.this, true);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
long localId = AccountService.saveToAccount(authentication, host);
|
||||
if (ACTION_ADD_ACCOUNT.equals(getIntent().getAction())) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_ACCOUNT_LOCAL_ID, localId);
|
||||
setResult(RESULT_OK, intent);
|
||||
} else {
|
||||
Intent intent = MainActivity.getOpenIntent(SignInActivity.this, true);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
} else {
|
||||
ToastUtils.show(SignInActivity.this, R.string.email_or_password_incorrect);
|
||||
}
|
||||
@@ -294,6 +303,19 @@ public class SignInActivity extends BaseActivity implements TextWatcher {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
* @return account local id or -1
|
||||
*/
|
||||
public static long getAccountIdFromData(Intent data) {
|
||||
if (data == null) {
|
||||
return -1;
|
||||
} else {
|
||||
return data.getLongExtra(EXTRA_ACCOUNT_LOCAL_ID, -1);
|
||||
}
|
||||
}
|
||||
|
||||
private Observable<String> initHost() {
|
||||
return Observable.create(new Observable.OnSubscribe<String>() {
|
||||
@Override
|
||||
|
@@ -34,11 +34,14 @@ import org.houxg.leamonax.R;
|
||||
import org.houxg.leamonax.editor.Editor;
|
||||
import org.houxg.leamonax.editor.MarkdownEditor;
|
||||
import org.houxg.leamonax.editor.RichTextEditor;
|
||||
import org.houxg.leamonax.service.NoteFileService;
|
||||
import org.houxg.leamonax.ui.PictureViewerActivity;
|
||||
import org.houxg.leamonax.utils.CollectionUtils;
|
||||
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;
|
||||
|
||||
@@ -459,6 +462,14 @@ public class EditorFragment extends Fragment implements Editor.EditorListener {
|
||||
OpenUtils.openUrl(getActivity(), url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedImage(String url) {
|
||||
String path = NoteFileService.getImagePath(Uri.parse(url));
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
startActivity(PictureViewerActivity.getOpenIntent(getActivity(), path));
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshFormatStatus(Map<Editor.Format, Object> formatStatus) {
|
||||
for (Map.Entry<Editor.Format, Object> entry : formatStatus.entrySet()) {
|
||||
switch (entry.getKey()) {
|
||||
|
@@ -0,0 +1,106 @@
|
||||
package org.houxg.leamonax.utils;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.MenuRes;
|
||||
import android.view.ActionMode;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.houxg.leamonax.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ActionModeHandler<T> {
|
||||
private List<T> mPendingItems;
|
||||
private int mMenuId;
|
||||
private Callback<T> mCallback;
|
||||
private ActionMode mActionMode;
|
||||
private Activity mContext;
|
||||
private ActionMode.Callback mActionCallback = new ActionMode.Callback() {
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||
mode.getMenuInflater().inflate(mMenuId, menu);
|
||||
Drawable drawable = menu.findItem(R.id.action_delete).getIcon();
|
||||
if (drawable != null) {
|
||||
// If we don't mutate the drawable, then all drawable's with this id will have a color
|
||||
// filter applied to it.
|
||||
drawable.mutate();
|
||||
drawable.setColorFilter(mContext.getResources().getColor(R.color.colorPrimaryDark), PorterDuff.Mode.SRC_ATOP);
|
||||
drawable.setAlpha(255);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
boolean isProceed = mCallback.onAction(item.getItemId(), mPendingItems);
|
||||
if (isProceed) {
|
||||
mPendingItems.clear();
|
||||
}
|
||||
return isProceed;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
};
|
||||
|
||||
public ActionModeHandler(Activity activity, Callback<T> callback, @MenuRes int menuId) {
|
||||
mContext = activity;
|
||||
mMenuId = menuId;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param item
|
||||
* @return true if the item is in pending list, false for others.
|
||||
*/
|
||||
public boolean chooseItem(T item) {
|
||||
if (isActionMode()) {
|
||||
if (mPendingItems.contains(item)) {
|
||||
mPendingItems.remove(item);
|
||||
return false;
|
||||
} else {
|
||||
mPendingItems.add(item);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
mContext.getWindow().setStatusBarColor(mContext.getResources().getColor(R.color.colorPrimaryDark));
|
||||
}
|
||||
mActionMode = mContext.startActionMode(mActionCallback);
|
||||
mPendingItems = new ArrayList<>();
|
||||
mPendingItems.add(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
mActionMode.finish();
|
||||
}
|
||||
|
||||
public boolean isActionMode() {
|
||||
return mActionMode != null;
|
||||
}
|
||||
|
||||
public interface Callback<T> {
|
||||
boolean onAction(int actionId, List<T> pendingItems);
|
||||
void onDestroy(List<T> pendingItems);
|
||||
}
|
||||
}
|
@@ -22,13 +22,13 @@ public class NetworkUtils {
|
||||
return cm.getActiveNetworkInfo();
|
||||
}
|
||||
|
||||
public static boolean isNetworkAvailable(Context context) {
|
||||
NetworkInfo info = getActiveNetworkInfo(context);
|
||||
public static boolean isNetworkAvailable() {
|
||||
NetworkInfo info = getActiveNetworkInfo(Leamonax.getContext());
|
||||
return (info != null && info.isConnected());
|
||||
}
|
||||
|
||||
public static void checkNetwork() throws NetworkUnavailableException {
|
||||
if (!isNetworkAvailable(Leamonax.getContext())) {
|
||||
if (!isNetworkAvailable()) {
|
||||
throw new NetworkUnavailableException();
|
||||
}
|
||||
}
|
||||
|
@@ -74,10 +74,18 @@ public class NoteList {
|
||||
mAdapter.delete(note);
|
||||
}
|
||||
|
||||
public void setSelected(Note note, boolean isSelected) {
|
||||
mAdapter.setSelected(note, isSelected);
|
||||
}
|
||||
|
||||
public int getScrollPosition() {
|
||||
return mScrollPosition;
|
||||
}
|
||||
|
||||
public void invalidateAllSelected() {
|
||||
mAdapter.invalidateAllSelected();
|
||||
}
|
||||
|
||||
public void setScrollPosition(int position) {
|
||||
mScrollPosition = position;
|
||||
mNoteListView.scrollTo(0, position);
|
||||
|
@@ -0,0 +1,65 @@
|
||||
package org.houxg.leamonax.widget;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.houxg.leamonax.R;
|
||||
|
||||
public class TriangleView extends ImageView {
|
||||
private static final int DURATION = 200;
|
||||
private boolean mIsChecked = false;
|
||||
OnToggleListener mListener;
|
||||
|
||||
public TriangleView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setImageResource(R.drawable.ic_triangle);
|
||||
setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mIsChecked = !mIsChecked;
|
||||
if (mIsChecked) {
|
||||
animate().rotation(-180)
|
||||
.setDuration(DURATION)
|
||||
.setInterpolator(new AccelerateDecelerateInterpolator())
|
||||
.start();
|
||||
} else {
|
||||
animate().rotation(0)
|
||||
.setDuration(DURATION)
|
||||
.setInterpolator(new AccelerateDecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
if (mListener != null) {
|
||||
mListener.onToggle(mIsChecked);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setOnToggleListener(OnToggleListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
public void toggle() {
|
||||
performClick();
|
||||
}
|
||||
|
||||
public void setChecked(boolean isChecked) {
|
||||
if (mIsChecked == isChecked) {
|
||||
return;
|
||||
}
|
||||
int rotate = isChecked ? -180 : 0;
|
||||
setRotation(rotate);
|
||||
mIsChecked = isChecked;
|
||||
if (mListener != null) {
|
||||
mListener.onToggle(mIsChecked);
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnToggleListener {
|
||||
void onToggle(boolean isChecked);
|
||||
}
|
||||
}
|
BIN
app/src/main/res/drawable-xxhdpi/ic_delete.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_delete.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 342 B |
5
app/src/main/res/drawable/note_selector.xml
Normal file
5
app/src/main/res/drawable/note_selector.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="true" android:drawable="@color/divider_light"/>
|
||||
<item android:drawable="@color/transparent"/>
|
||||
</selector>
|
@@ -73,7 +73,7 @@
|
||||
style="@style/SettingsStatus"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="GNU GENERAL PUBLIC LICENSE V3" />
|
||||
android:text="@string/gnu_general_public_license_v3" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -93,13 +93,13 @@
|
||||
style="@style/SettingsStatus"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Leanote" />
|
||||
android:text="@string/leanote" />
|
||||
|
||||
<TextView
|
||||
style="@style/SettingsStatus"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="https://material.io/icons/" />
|
||||
android:text="@string/https_material_io_icons" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
style="@style/SettingsSecondaryText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Github" />
|
||||
android:text="@string/github" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
style="@style/SettingsSecondaryText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Generate random note" />
|
||||
android:text="@string/generate_random_note" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@@ -17,10 +17,16 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
<android.support.v4.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swiperefresh"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
|
14
app/src/main/res/layout/activity_picture_viewer.xml
Normal file
14
app/src/main/res/layout/activity_picture_viewer.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_about"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
tools:context="org.houxg.leamonax.ui.AboutActivity">
|
||||
|
||||
<com.github.piasy.biv.view.BigImageView
|
||||
android:id="@+id/big_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
@@ -5,16 +5,9 @@
|
||||
android:orientation="vertical"
|
||||
android:background="#EEEEEE">
|
||||
|
||||
<android.support.v4.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swiperefresh"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
|
||||
</RelativeLayout>
|
38
app/src/main/res/layout/item_account.xml
Normal file
38
app/src/main/res/layout/item_account.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_avatar"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginStart="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_email"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
tools:text="test@leanote.com"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_host"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/hint_text_light"
|
||||
tools:text="https://leanote.com"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
22
app/src/main/res/layout/item_add_account.xml
Normal file
22
app/src/main/res/layout/item_add_account.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_add_note_book"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_add_account"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="@string/add_account"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
@@ -5,9 +5,11 @@
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:background="@drawable/note_selector"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
|
@@ -1,9 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:background="@drawable/note_selector"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
|
@@ -9,6 +9,8 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_info"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
@@ -18,22 +20,29 @@
|
||||
android:id="@+id/iv_avatar"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_other_account"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignTop="@id/iv_avatar"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_account_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/iv_avatar"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_toEndOf="@id/iv_avatar"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_user_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:textColor="@color/secondary_text_light"
|
||||
android:textSize="14sp"
|
||||
tools:text="exercitation" />
|
||||
@@ -48,16 +57,30 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.houxg.leamonax.widget.TriangleView
|
||||
android:id="@+id/tr_account"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@id/ll_account_info"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:padding="8dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<include layout="@layout/divider" />
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/rv_account"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_recent_notes"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:background="?android:attr/selectableItemBackground">
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
@@ -105,29 +128,21 @@
|
||||
android:textColor="@color/hint_text_light"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_notebook_triangle"
|
||||
<org.houxg.leamonax.widget.TriangleView
|
||||
android:id="@+id/tr_notebook"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_triangle" />
|
||||
android:padding="8dp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_notebook_list"
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/rv_notebook"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/rv_notebook"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</RelativeLayout>
|
||||
android:visibility="gone" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_tag"
|
||||
@@ -155,20 +170,20 @@
|
||||
android:textColor="@color/hint_text_light"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_tag_triangle"
|
||||
<org.houxg.leamonax.widget.TriangleView
|
||||
android:id="@+id/tr_tag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_triangle" />
|
||||
android:padding="8dp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/rv_tag"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone" />
|
||||
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
@@ -181,8 +196,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:padding="16dp"
|
||||
android:background="?android:attr/selectableItemBackground">
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
@@ -207,8 +222,8 @@
|
||||
android:id="@+id/rl_about"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:background="?android:attr/selectableItemBackground">
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
|
10
app/src/main/res/menu/delete.xml
Normal file
10
app/src/main/res/menu/delete.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_delete"
|
||||
android:icon="@drawable/ic_delete"
|
||||
android:title="@string/delete"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
@@ -4,7 +4,7 @@
|
||||
<string name="add_notebook">添加笔记本</string>
|
||||
<string name="apply">应用</string>
|
||||
<string name="are_you_sure_to_delete_all_data_in_this_account">你确定要删除该账户所有的数据吗?</string>
|
||||
<string name="are_you_sure_to_delete_note">你确定要删除%s?</string>
|
||||
<string name="are_you_sure_to_delete_note">你确定要删除这些笔记吗?</string>
|
||||
<string name="are_your_sure_to_log_out">你确定要登出吗?</string>
|
||||
<string name="avatar">头像</string>
|
||||
<string name="cancel">取消</string>
|
||||
@@ -98,4 +98,10 @@
|
||||
<string name="continue_text">继续</string>
|
||||
<string name="next_time">下次再说</string>
|
||||
<string name="cant_open_url">无法打开该链接</string>
|
||||
<string name="delete">删除</string>
|
||||
<string name="no_note_was_selected">请选择笔记</string>
|
||||
<string name="view_type">视图类型</string>
|
||||
<string name="add_account">添加账户</string>
|
||||
<string name="generate_random_note">生成随机笔记</string>
|
||||
<string name="leanote">蚂蚁笔记</string>
|
||||
</resources>
|
@@ -14,4 +14,7 @@
|
||||
<color name="hint_text_light">#61000000</color>
|
||||
<color name="divider_light">#1f000000</color>
|
||||
<color name="navigation">#F5F5F5</color>
|
||||
<color name="transparent">#00000000</color>
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="black">#000</color>
|
||||
</resources>
|
||||
|
@@ -11,7 +11,7 @@
|
||||
<string name="link">Link</string>
|
||||
<string name="confirm">Confirm</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="are_you_sure_to_delete_note">Are you sure to delete %s?</string>
|
||||
<string name="are_you_sure_to_delete_note">Are you sure to delete these notes?</string>
|
||||
<string name="delete_note">Delete note</string>
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
@@ -83,8 +83,8 @@
|
||||
<string name="continue_download">Continue download</string>
|
||||
<string name="continue_text">Continue</string>
|
||||
<string name="download_error">Download failed</string>
|
||||
<string name="download_successful">Dowload finished</string>
|
||||
<string name="downloading">Dowloading</string>
|
||||
<string name="download_successful">Download finished</string>
|
||||
<string name="downloading">Downloading</string>
|
||||
<string name="what_s_new">What\'s new</string>
|
||||
<string name="file_size">File size</string>
|
||||
<string name="have_new_version">Have new version</string>
|
||||
@@ -98,5 +98,13 @@
|
||||
<string name="your_are_the_latest_version">You are using latest version</string>
|
||||
<string name="cant_open_url">Can\'t open this url</string>
|
||||
<string name="view_type">View type</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="no_note_was_selected">No note was selected</string>
|
||||
<string name="add_account">Add account</string>
|
||||
<string name="leanote">Leanote</string>
|
||||
<string name="https_material_io_icons" translatable="false">https://material.io/icons/</string>
|
||||
<string name="gnu_general_public_license_v3" translatable="false">GNU GENERAL PUBLIC LICENSE V3</string>
|
||||
<string name="github" translatable="false">Github</string>
|
||||
<string name="generate_random_note">Generate random note</string>
|
||||
|
||||
</resources>
|
||||
|
@@ -7,8 +7,15 @@
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:actionMenuTextColor">@color/menu_text</item>
|
||||
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="windowActionBarOverlay">true</item>
|
||||
<item name="android:homeAsUpIndicator">@drawable/ic_arrow_back_white</item>
|
||||
<item name="actionModeStyle">@style/CustomActionMode</item>
|
||||
</style>
|
||||
|
||||
<style name="CustomActionMode" parent="@style/Widget.AppCompat.ActionMode">
|
||||
<item name="background">@color/white</item>
|
||||
<item name="height">?attr/actionBarSize</item>
|
||||
</style>
|
||||
|
||||
<style name="SettingsStatus">
|
||||
|
Reference in New Issue
Block a user