diff --git a/app/src/main/assets/updatelog.fy b/app/src/main/assets/updatelog.fy index 0bdce35..d65ad54 100644 --- a/app/src/main/assets/updatelog.fy +++ b/app/src/main/assets/updatelog.fy @@ -1,8 +1,11 @@ -2021.06.14 +2021.06.15 风月读书v2.1.3 更新内容: 1、优化阅读文字选择 -2、修复已知bug +2、优化第三方书源加载 +3、优化换源对话框 +4、换源对话框新增书源搜索 +5、修复已知bug 2021.06.13 风月读书v2.1.2 diff --git a/app/src/main/java/xyz/fycz/myreader/model/SearchEngine.java b/app/src/main/java/xyz/fycz/myreader/model/SearchEngine.java index 7de5a10..62c808c 100644 --- a/app/src/main/java/xyz/fycz/myreader/model/SearchEngine.java +++ b/app/src/main/java/xyz/fycz/myreader/model/SearchEngine.java @@ -46,19 +46,12 @@ public class SearchEngine { private int searchSuccessNum; private int searchFinishNum; - private boolean isRead = false;//是否在阅读界面换源 - private OnSearchListener searchListener; public SearchEngine() { threadsNum = SharedPreUtils.getInstance().getInt(App.getmContext().getString(R.string.threadNum), 8); } - public SearchEngine(boolean isRead) { - this(); - this.isRead = isRead; - } - public void setOnSearchListener(OnSearchListener searchListener) { this.searchListener = searchListener; } @@ -193,7 +186,6 @@ public class SearchEngine { ReadCrawler crawler = mSourceList.get(searchSiteIndex); String searchKey = title; BookApi.search(searchKey, crawler) - .flatMap(bookMap -> getBookInfo(bookMap, crawler)) .subscribeOn(scheduler) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer>() { @@ -266,20 +258,6 @@ public class SearchEngine { }); } - public Observable> getBookInfo(ConMVMap bookMap, ReadCrawler rc) { - return Observable.create(emitter -> { - if (isRead && rc instanceof ThirdCrawler) { - List books = bookMap.values(); - for (Book book : books) { - BookApi.getBookInfo(book, (BookInfoCrawler) rc).subscribe(); - } - } - emitter.onNext(bookMap); - emitter.onComplete(); - }); - } - - /************************************************************************/ public interface OnSearchListener { diff --git a/app/src/main/java/xyz/fycz/myreader/model/third2/content/BookChapterList.java b/app/src/main/java/xyz/fycz/myreader/model/third2/content/BookChapterList.java index 5b3a4aa..08bfb0f 100644 --- a/app/src/main/java/xyz/fycz/myreader/model/third2/content/BookChapterList.java +++ b/app/src/main/java/xyz/fycz/myreader/model/third2/content/BookChapterList.java @@ -158,6 +158,10 @@ public class BookChapterList { chapterList = new ArrayList<>(lh); Collections.reverse(chapterList); Log.d(tag, "-目录解析完成" + analyzeNextUrl); + if (chapterList.isEmpty()) { + emitter.onError(new Throwable("目录列表为空")); + return; + } emitter.onNext(chapterList); emitter.onComplete(); } diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java index c342fce..97cf2b5 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java @@ -119,9 +119,7 @@ public class BookDetailedActivity extends BaseActivity { initBookInfo(); mChapters.clear(); mNewestChapters.clear(); - if (!isThirdSource()) { - initChapters(true); - } + initChapters(true); mCatalogAdapter.clear(); } break; @@ -225,7 +223,7 @@ public class BookDetailedActivity extends BaseActivity { binding.ic.bookDetailRvCatalog.setLayoutManager(new LinearLayoutManager(this)); binding.ic.bookDetailRvCatalog.setAdapter(mCatalogAdapter); - if (!isThirdSource()) initChapters(false); + initChapters(false); mCatalogAdapter.setOnItemClickListener((view, pos) -> { mBook.setHisttoryChapterNum(mChapters.size() - pos - 1); @@ -435,7 +433,7 @@ public class BookDetailedActivity extends BaseActivity { BookSource source = BookSourceManager.getBookSourceByStr(mBook.getSource()); binding.ih.bookDetailSource.setText(String.format("书源:%s", source.getSourceName())); ReadCrawler rc = ReadCrawlerUtil.getReadCrawler(source); - if ((rc instanceof BookInfoCrawler && StringHelper.isEmpty(mBook.getImgUrl())) || isThirdSource()) { + if ((rc instanceof BookInfoCrawler && StringHelper.isEmpty(mBook.getImgUrl()))) { binding.pbLoading.setVisibility(View.VISIBLE); BookInfoCrawler bic = (BookInfoCrawler) rc; BookApi.getBookInfo(mBook, bic).compose(RxUtils::toSimpleSingle).subscribe(new MyObserver() { @@ -443,9 +441,6 @@ public class BookDetailedActivity extends BaseActivity { public void onNext(@NotNull Book book) { if (!App.isDestroy(BookDetailedActivity.this)) { mHandler.sendMessage(mHandler.obtainMessage(4)); - if (isThirdSource()) { - initChapters(false); - } } } @@ -454,9 +449,6 @@ public class BookDetailedActivity extends BaseActivity { public void onError(Throwable e) { if (!App.isDestroy(BookDetailedActivity.this)) { ToastUtils.showError("书籍详情加载失败!"); - if (isThirdSource()) { - initChapters(false); - } binding.pbLoading.setVisibility(View.GONE); } if (App.isDebug()) e.printStackTrace(); @@ -569,15 +561,15 @@ public class BookDetailedActivity extends BaseActivity { mBookService.addBook(mBook); } Intent intent = new Intent(this, ReadActivity.class); - /*aBooks = mSourceDialog.getaBooks(); + aBooks = mSourceDialog.getaBooks(); if (aBooks != null) { aBooks.set(mSourceDialog.getSourceIndex(), mBook); BitIntentDataManager.getInstance().putData(intent, aBooks); intent.putExtra(APPCONST.SOURCE_INDEX, mSourceDialog.getSourceIndex()); } else { BitIntentDataManager.getInstance().putData(intent, mBook); - }*/ - BitIntentDataManager.getInstance().putData(intent, mBook); + } +// BitIntentDataManager.getInstance().putData(intent, mBook); intent.putExtra("isCollected", isCollected); startActivityForResult(intent, APPCONST.REQUEST_READ); } @@ -729,9 +721,4 @@ public class BookDetailedActivity extends BaseActivity { } } - - private boolean isThirdSource() { - return mReadCrawler instanceof ThirdCrawler; - } - } diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java index 7f047cd..3911266 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java @@ -307,7 +307,7 @@ public class ReadActivity extends BaseActivity implements ColorPickerDialogListe mPageLoader = binding.readPvContent.getPageLoader(mBook, mReadCrawler, mSetting); //Dialog - mSourceDialog = new SourceExchangeDialog(this, mBook, true); + mSourceDialog = new SourceExchangeDialog(this, mBook); if (aBooks != null) { mSourceDialog.setABooks(aBooks); } @@ -472,6 +472,7 @@ public class ReadActivity extends BaseActivity implements ColorPickerDialogListe mSourceDialog.setOnSourceChangeListener((bean, pos) -> { Book bookTem = (Book) mBook.clone(); + bookTem.setInfoUrl(bean.getInfoUrl()); bookTem.setChapterUrl(bean.getChapterUrl()); bookTem.setSource(bean.getSource()); if (!StringHelper.isEmpty(bean.getImgUrl())) { @@ -722,10 +723,11 @@ public class ReadActivity extends BaseActivity implements ColorPickerDialogListe mSourceDialog.show(); } else if (itemId == R.id.action_reload) { mPageLoader.setPrev(false); - if (!"本地书籍".equals(mBook.getType())) { + if (!"本地书籍".equals(mBook.getType()) && !mChapters.isEmpty()) { mChapterService.deleteChapterCacheFile(mChapters.get(mPageLoader.getChapterPos())); } - mPageLoader.refreshChapter(mChapters.get(mPageLoader.getChapterPos())); + if (!mChapters.isEmpty()) + mPageLoader.refreshChapter(mChapters.get(mPageLoader.getChapterPos())); } else if (itemId == R.id.action_add_bookmark) { if (mChapters == null || mChapters.size() == 0) { if ("本地书籍".equals(mBook.getType())) { diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java index 7d79f08..42f3a8c 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java @@ -243,7 +243,11 @@ public class SearchBookActivity extends BaseActivity { mHandler.sendMessage(mHandler.obtainMessage(1)); }); initHistoryList(); - mHandler.postDelayed(() -> binding.etSearchKey.requestFocus(), 200); + mHandler.postDelayed(() -> { + binding.etSearchKey.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED); + }, 400); } @Override diff --git a/app/src/main/java/xyz/fycz/myreader/ui/adapter/SourceExchangeAdapter.java b/app/src/main/java/xyz/fycz/myreader/ui/adapter/SourceExchangeAdapter.java index d16b914..ebccd48 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/adapter/SourceExchangeAdapter.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/adapter/SourceExchangeAdapter.java @@ -1,26 +1,75 @@ package xyz.fycz.myreader.ui.adapter; +import android.widget.Filter; +import android.widget.Filterable; + import xyz.fycz.myreader.base.adapter.BaseListAdapter; import xyz.fycz.myreader.base.adapter.IViewHolder; import xyz.fycz.myreader.greendao.entity.Book; +import xyz.fycz.myreader.greendao.entity.ReplaceRuleBean; +import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager; import xyz.fycz.myreader.ui.adapter.holder.SourceExchangeHolder; import xyz.fycz.myreader.ui.dialog.SourceExchangeDialog; +import xyz.fycz.myreader.util.help.StringHelper; +import java.util.ArrayList; import java.util.List; /** * @author fengyue * @date 2020/9/30 18:42 */ -public class SourceExchangeAdapter extends BaseListAdapter { +public class SourceExchangeAdapter extends BaseListAdapter implements Filterable { private SourceExchangeDialog dialog; + private List beans; - public SourceExchangeAdapter(SourceExchangeDialog dialog) { + public SourceExchangeAdapter(SourceExchangeDialog dialog, List beans) { this.dialog = dialog; + this.beans = beans; } @Override protected IViewHolder createViewHolder(int viewType) { return new SourceExchangeHolder(dialog); } + + /** + * 过滤器,实现搜索 + * + * @return + */ + @Override + public Filter getFilter() { + return new Filter() { + @Override + protected FilterResults performFiltering(CharSequence constraint) { + String charString = constraint.toString(); + List mFilterList = new ArrayList<>(); + if (charString.isEmpty()) { + //没有过滤的内容,则使用源数据 + mFilterList = beans; + } else { + for (Book bean : beans) { + //这里根据需求,添加匹配规则 + if (BookSourceManager.getSourceNameByStr(bean.getSource()) + .contains(charString)) { + mFilterList.add(bean); + } + } + } + FilterResults filterResults = new FilterResults(); + filterResults.values = mFilterList; + return filterResults; + } + + //把过滤后的值返回出来 + @Override + protected void publishResults(CharSequence constraint, FilterResults results) { + if (results.values != null) + refreshItems((List) results.values); + else + refreshItems(beans); + } + }; + } } diff --git a/app/src/main/java/xyz/fycz/myreader/ui/dialog/SourceExchangeDialog.java b/app/src/main/java/xyz/fycz/myreader/ui/dialog/SourceExchangeDialog.java index 5a7ea25..910a641 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/dialog/SourceExchangeDialog.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/dialog/SourceExchangeDialog.java @@ -3,6 +3,7 @@ package xyz.fycz.myreader.ui.dialog; import android.app.Activity; import android.app.Dialog; import android.os.Bundle; +import android.text.TextUtils; import android.view.Gravity; import android.view.View; import android.view.Window; @@ -10,6 +11,7 @@ import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.SearchView; import androidx.recyclerview.widget.LinearLayoutManager; import java.util.ArrayList; @@ -20,6 +22,7 @@ import xyz.fycz.myreader.entity.SearchBookBean; import xyz.fycz.myreader.greendao.entity.Book; import xyz.fycz.myreader.model.SearchEngine; import xyz.fycz.myreader.model.mulvalmap.ConMVMap; +import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager; import xyz.fycz.myreader.ui.adapter.SourceExchangeAdapter; import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil; import xyz.fycz.myreader.widget.RefreshProgressBar; @@ -47,7 +50,7 @@ public class SourceExchangeDialog extends Dialog { private int sourceIndex = -1; - private boolean isRead;//是否在阅读界面换源 + private String sourceSearchStr; /***************************************************************************/ public SourceExchangeDialog(@NonNull Activity activity, Book bookBean) { @@ -56,11 +59,6 @@ public class SourceExchangeDialog extends Dialog { mShelfBook = bookBean; } - public SourceExchangeDialog(@NonNull Activity activity, Book bookBean, boolean isRead) { - this(activity, bookBean); - this.isRead = isRead; - } - public void setShelfBook(Book mShelfBook) { this.mShelfBook = mShelfBook; } @@ -99,7 +97,6 @@ public class SourceExchangeDialog extends Dialog { @Override protected void onStart() { super.onStart(); - //执行业务逻辑 if (aBooks.size() == 0) { searchEngine.search(mShelfBook.getName(), mShelfBook.getAuthor()); binding.ivStopSearch.setVisibility(View.VISIBLE); @@ -108,6 +105,7 @@ public class SourceExchangeDialog extends Dialog { if (mAdapter.getItemCount() == 0) { mAdapter.addItems(aBooks); } + binding.ivStopSearch.setVisibility(View.GONE); } } @@ -135,11 +133,11 @@ public class SourceExchangeDialog extends Dialog { aBooks = new ArrayList<>(); } - mAdapter = new SourceExchangeAdapter(this); + mAdapter = new SourceExchangeAdapter(this, aBooks); binding.dialogRvContent.setLayoutManager(new LinearLayoutManager(mActivity)); binding.dialogRvContent.setAdapter(mAdapter); - searchEngine = new SearchEngine(isRead); + searchEngine = new SearchEngine(); searchEngine.initSearchEngine(ReadCrawlerUtil.getEnableReadCrawlers()); } @@ -167,7 +165,13 @@ public class SourceExchangeDialog extends Dialog { bean.setNewestChapterId("true"); sourceIndex = mAdapter.getItemSize(); } - mAdapter.addItem(items.get(0)); + if (TextUtils.isEmpty(sourceSearchStr)) { + mAdapter.addItem(bean); + } else { + if (BookSourceManager.getSourceNameByStr(bean.getSource()).contains(sourceSearchStr)){ + mAdapter.addItem(bean); + } + } aBooks.add(bean); } } @@ -201,12 +205,29 @@ public class SourceExchangeDialog extends Dialog { binding.ivStopSearch.setOnClickListener(v -> searchEngine.stopSearch()); binding.ivRefreshSearch.setOnClickListener(v -> { searchEngine.stopSearch(); + binding.rpb.setIsAutoLoading(true); binding.ivStopSearch.setVisibility(View.VISIBLE); mAdapter.clear(); aBooks.clear(); mAdapter.notifyDataSetChanged(); searchEngine.search(mShelfBook.getName(), mShelfBook.getAuthor()); }); + + binding.searchView.onActionViewExpanded(); + binding.searchView.clearFocus(); + binding.searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + sourceSearchStr = newText; + mAdapter.getFilter().filter(newText); + return false; + } + }); } diff --git a/app/src/main/java/xyz/fycz/myreader/util/help/JsExtensions.java b/app/src/main/java/xyz/fycz/myreader/util/help/JsExtensions.java index f7dea3e..5ce1fbe 100644 --- a/app/src/main/java/xyz/fycz/myreader/util/help/JsExtensions.java +++ b/app/src/main/java/xyz/fycz/myreader/util/help/JsExtensions.java @@ -33,6 +33,8 @@ import xyz.fycz.myreader.util.utils.OkHttpUtils; import xyz.fycz.myreader.util.utils.StringUtils; @Keep + + @SuppressWarnings({"unused"}) public interface JsExtensions { String TAG = JsExtensions.class.getSimpleName(); diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/BookApi.java b/app/src/main/java/xyz/fycz/myreader/webapi/BookApi.java index f6a457d..c87efde 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/BookApi.java +++ b/app/src/main/java/xyz/fycz/myreader/webapi/BookApi.java @@ -1,5 +1,7 @@ package xyz.fycz.myreader.webapi; +import android.util.Log; + import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.List; @@ -101,7 +103,12 @@ public class BookApi { */ public static Observable> getBookChapters(Book book, final ReadCrawler rc) { if (rc instanceof ThirdCrawler) { - return ThirdSourceApi.getBookChaptersByTC(book, (ThirdCrawler) rc); + if (StringHelper.isEmpty(book.getChapterUrl())) { + return ThirdSourceApi.getBookInfoByTC(book, (ThirdCrawler) rc) + .flatMap(book1 -> ThirdSourceApi.getBookChaptersByTC(book, (ThirdCrawler) rc)); + } else { + return ThirdSourceApi.getBookChaptersByTC(book, (ThirdCrawler) rc); + } } String url = book.getChapterUrl(); if (StringHelper.isEmpty(url)) url = book.getInfoUrl(); diff --git a/app/src/main/res/layout/activity_search_book.xml b/app/src/main/res/layout/activity_search_book.xml index 58692d2..5c5dd2b 100644 --- a/app/src/main/res/layout/activity_search_book.xml +++ b/app/src/main/res/layout/activity_search_book.xml @@ -1,6 +1,4 @@ - - + + - + android:layout_height="match_parent"> + + +