diff --git a/app/src/main/assets/updatelog.fy b/app/src/main/assets/updatelog.fy index 435d80d..60536d3 100644 --- a/app/src/main/assets/updatelog.fy +++ b/app/src/main/assets/updatelog.fy @@ -1,3 +1,11 @@ +2022.03.03 +风月读书v2.3.9 +更新内容: +1、新增书源订阅功能,移除内置书源,原内置书源界面改为订阅书源(注:订阅书源全部搜集自网络,每月更新) +2、新增去除广告功能 +3、设置新增我的界面显示方式 +4、修复已知bug + 2022.02.23 风月读书v2.3.8 更新内容: diff --git a/app/src/main/java/xyz/fycz/myreader/application/App.java b/app/src/main/java/xyz/fycz/myreader/application/App.java index 62ee7ef..59bb823 100644 --- a/app/src/main/java/xyz/fycz/myreader/application/App.java +++ b/app/src/main/java/xyz/fycz/myreader/application/App.java @@ -33,16 +33,23 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import java.io.File; +import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import io.reactivex.internal.functions.Functions; import io.reactivex.plugins.RxJavaPlugins; +import kotlin.Unit; +import kotlin.coroutines.Continuation; +import kotlin.jvm.functions.Function3; +import kotlinx.coroutines.CoroutineScope; import xyz.fycz.myreader.R; import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.common.URLCONST; import xyz.fycz.myreader.entity.Setting; +import xyz.fycz.myreader.entity.lanzou.LanZouFile; import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager; +import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.dialog.UpdateDialog; import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.ToastUtils; @@ -51,6 +58,7 @@ import xyz.fycz.myreader.util.help.StringHelper; import xyz.fycz.myreader.util.utils.AdUtils; import xyz.fycz.myreader.util.utils.NetworkUtils; import xyz.fycz.myreader.util.utils.OkHttpUtils; +import xyz.fycz.myreader.webapi.LanZouApi; public class App extends Application { @@ -68,7 +76,6 @@ public class App extends Application { application = this; debug = isApkInDebug(this); CrashHandler.register(this); - firstInit(); SSLSocketClient.trustAllHosts();//信任所有证书 RxJavaPlugins.setErrorHandler(Functions.emptyConsumer()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { @@ -92,14 +99,6 @@ public class App extends Application { } - private void firstInit() { - SharedPreUtils sru = SharedPreUtils.getInstance(); - if (!sru.getBoolean("firstInit")) { - BookSourceManager.initDefaultSources(); - sru.putBoolean("firstInit", true); - } - } - private void initDialogX() { DialogX.init(this); DialogX.DEBUGMODE = debug; diff --git a/app/src/main/java/xyz/fycz/myreader/application/SysManager.java b/app/src/main/java/xyz/fycz/myreader/application/SysManager.java index d6ea789..d7877bd 100644 --- a/app/src/main/java/xyz/fycz/myreader/application/SysManager.java +++ b/app/src/main/java/xyz/fycz/myreader/application/SysManager.java @@ -7,13 +7,17 @@ import xyz.fycz.myreader.common.APPCONST; import xyz.fycz.myreader.entity.Setting; import xyz.fycz.myreader.enums.BookcaseStyle; import xyz.fycz.myreader.enums.LocalBookSource; +import xyz.fycz.myreader.greendao.entity.rule.BookSource; import xyz.fycz.myreader.greendao.service.BookGroupService; +import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager; import xyz.fycz.myreader.util.CacheHelper; import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil; import static xyz.fycz.myreader.application.App.getVersionCode; +import java.util.List; + public class SysManager { @@ -137,7 +141,12 @@ public class SysManager { case 6: SharedPreUtils.getInstance().putString(App.getmContext().getString(R.string.searchSource), ""); Log.d("SourceVersion", "" + 5); - break; + case 7: + List sources = BookSourceManager.getAllLocalSource(); + for (BookSource source : sources){ + source.setEnable(false); + } + BookSourceManager.addBookSource(sources); } setting.setSourceVersion(APPCONST.SOURCE_VERSION); saveSetting(setting); diff --git a/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java b/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java index e87497e..9edbd16 100644 --- a/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java +++ b/app/src/main/java/xyz/fycz/myreader/common/APPCONST.java @@ -103,6 +103,7 @@ public class APPCONST { public static final int REQUEST_SEARCH_WORD = 1015; public static final int REQUEST_AUTH_EMAIL = 1016; public static final int REQUEST_SETTING = 1017; + public static final int REQUEST_SUBSCRIBE = 1018; public static final int REQUEST_READ = 1; @@ -113,7 +114,7 @@ public class APPCONST { //设置版本号 public static final int SETTING_VERSION = 11; - public static final int SOURCE_VERSION = 7; + public static final int SOURCE_VERSION = 8; public static final String FORMAT_FILE_DATE = "yyyy-MM-dd"; diff --git a/app/src/main/java/xyz/fycz/myreader/entity/ad/AdConfig.java b/app/src/main/java/xyz/fycz/myreader/entity/ad/AdConfig.java index 9fe7cb8..8ace2e4 100644 --- a/app/src/main/java/xyz/fycz/myreader/entity/ad/AdConfig.java +++ b/app/src/main/java/xyz/fycz/myreader/entity/ad/AdConfig.java @@ -25,6 +25,8 @@ public class AdConfig { private int maxRemove; //累计最高去除时间(单位:小时) private int totalRemove; + //获取订阅书源是否需要看广告 + private boolean subSource; //详情页广告配置 private AdBean detail; //搜索页广告配置 @@ -33,7 +35,7 @@ public class AdConfig { public AdConfig() { } - public AdConfig(boolean hasAd, int expireTime, int backAdTime, int intervalAdTime, int removeAdTime, int maxRemove, int totalRemove) { + public AdConfig(boolean hasAd, int expireTime, int backAdTime, int intervalAdTime, int removeAdTime, int maxRemove, int totalRemove, boolean subSource) { this.hasAd = hasAd; this.expireTime = expireTime; this.backAdTime = backAdTime; @@ -41,6 +43,7 @@ public class AdConfig { this.removeAdTime = removeAdTime; this.maxRemove = maxRemove; this.totalRemove = totalRemove; + this.subSource = subSource; } public boolean isCloud() { @@ -129,6 +132,14 @@ public class AdConfig { this.search = search; } + public boolean isSubSource() { + return subSource; + } + + public void setSubSource(boolean subSource) { + this.subSource = subSource; + } + @NonNull @Override public String toString() { diff --git a/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java b/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java index 9bff369..b1762ed 100644 --- a/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java +++ b/app/src/main/java/xyz/fycz/myreader/model/sourceAnalyzer/BookSourceManager.java @@ -23,6 +23,7 @@ import xyz.fycz.myreader.entity.thirdsource.source3.Source3; import xyz.fycz.myreader.entity.thirdsource.source3.Third3SourceUtil; import xyz.fycz.myreader.enums.LocalBookSource; import xyz.fycz.myreader.greendao.DbManager; +import xyz.fycz.myreader.greendao.entity.SubscribeFile; import xyz.fycz.myreader.greendao.entity.rule.BookSource; import xyz.fycz.myreader.greendao.gen.BookSourceDao; import xyz.fycz.myreader.model.third3.SourceAnalyzer; @@ -167,6 +168,15 @@ public class BookSourceManager { .list(); } + + public static List getAllSubSource() { + return DbManager.getDaoSession().getBookSourceDao().queryBuilder() + .where(BookSourceDao.Properties.SourceEName.isNotNull()) + .where(BookSourceDao.Properties.SourceType.isNotNull()) + .orderAsc(BookSourceDao.Properties.OrderNum) + .list(); + } + /** * 获取所有导入书源 * @@ -179,6 +189,19 @@ public class BookSourceManager { .list(); } + public static void removeSourceBySubscribe(SubscribeFile file) { + DbManager.getDaoSession().getBookSourceDao().queryBuilder() + .where(BookSourceDao.Properties.SourceEName.eq("订阅书源:" + file.getId())) + .buildDelete().executeDeleteWithoutDetachingEntities(); + } + + public static List getSourceBySubscribe(SubscribeFile file) { + return DbManager.getDaoSession().getBookSourceDao().queryBuilder() + .where(BookSourceDao.Properties.SourceEName.eq("订阅书源:" + file.getId())) + .orderAsc(BookSourceDao.Properties.OrderNum) + .list(); + } + /** * 删除书源 * @@ -301,7 +324,7 @@ public class BookSourceManager { if (TextUtils.isEmpty(group) || TextUtils.isEmpty(group.trim())) continue; for (String item : group.split("\\s*[,;,;]\\s*")) { if (isSubscribe) { - if (TextUtils.isEmpty(eName) || TextUtils.isEmpty(item) || groupList.contains(item)) + if (TextUtils.isEmpty(eName) || TextUtils.isEmpty(item) || groupList.contains(item) || item.equals("内置书源")) continue; } else { if (!TextUtils.isEmpty(eName) || TextUtils.isEmpty(item) || groupList.contains(item) || item.equals("内置书源")) @@ -314,44 +337,50 @@ public class BookSourceManager { return groupList; } - public static Observable> importSource(String string) { + public static Observable> importSource(String string, String subscribeId) { if (StringHelper.isEmpty(string)) return null; string = string.trim(); if (NetworkUtils.isIPv4Address(string)) { string = String.format("http://%s:65501", string); } if (StringUtils.isJsonType(string)) { - return importBookSourceFromJson(string.trim()) + return importBookSourceFromJson(string.trim(), subscribeId) .compose(RxUtils::toSimpleSingle); } else if (StringUtils.isCompressJsonType(string)) { - return importBookSourceFromJson(StringUtils.unCompressJson(string)) + return importBookSourceFromJson(StringUtils.unCompressJson(string), subscribeId) .compose(RxUtils::toSimpleSingle); } else if (new File(string).isFile()) { - return importSource(FileUtils.readText(string)); + return importSource(FileUtils.readText(string), subscribeId); } if (string.matches("https://.+\\.lanzou[a-z]\\.com/[\\s\\S]*")) { return LanZouApi.INSTANCE.getFileUrl(string) .flatMap((Function>) s -> Observable.create(emitter -> { emitter.onNext(OkHttpUtils.getHtml(s)); emitter.onComplete(); - })).flatMap(BookSourceManager::importBookSourceFromJson) + })).flatMap(json -> importBookSourceFromJson(json, subscribeId)) .compose(RxUtils::toSimpleSingle); } if (NetworkUtils.isUrl(string)) { String finalString = string; return Observable.create((ObservableEmitter e) -> e.onNext(OkHttpUtils.getHtml(finalString))) - .flatMap(BookSourceManager::importBookSourceFromJson) + .flatMap(json -> importBookSourceFromJson(json, subscribeId)) .compose(RxUtils::toSimpleSingle); } return Observable.error(new Exception("不是Json或Url格式或文件路径")); } private static Observable> importBookSourceFromJson(String json) { + return importBookSourceFromJson(json, ""); + } + + private static Observable> importBookSourceFromJson(String json, String subscribeId) { return Observable.create(emitter -> { List successImportSources = new ArrayList<>(); List bookSources = importSources(json); if (bookSources != null) { for (BookSource bookSource : bookSources) { + if (!TextUtils.isEmpty(subscribeId)) + bookSource.setSourceEName("订阅书源:" + subscribeId); if (bookSource.containsGroup("删除")) { DbManager.getDaoSession().getBookSourceDao().queryBuilder() .where(BookSourceDao.Properties.SourceUrl.eq(bookSource.getSourceUrl())) 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 4765a04..9b12af8 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 @@ -261,16 +261,14 @@ public class BookDetailedActivity extends BaseActivity { mSourceDialog.setABooks(aBooks); mSourceDialog.setSourceIndex(sourceIndex); adBean = AdUtils.getAdConfig().getDetail(); - if (AdUtils.getAdConfig().isHasAd() && AdUtils.adTime("detail", adBean)) { - initAd(); - } + initAd(); } private void initAd() { AdUtils.checkHasAd().subscribe(new MySingleObserver() { @Override public void onSuccess(@NonNull Boolean aBoolean) { - if (aBoolean) { + if (aBoolean && AdUtils.adTime("detail", adBean)) { if (adBean.getStatus() == 1) { AdUtils.getFlowAd(BookDetailedActivity.this, 1, view -> binding.ic.getRoot().addView(view, 2), "detail"); diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java b/app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java index 8bc9f1c..f44213b 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java @@ -49,6 +49,7 @@ import xyz.fycz.myreader.util.help.StringHelper; import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.utils.AdUtils; import xyz.fycz.myreader.util.utils.GsonExtensionsKt; +import xyz.fycz.myreader.webapi.LanZouApi; import xyz.fycz.myreader.widget.NoScrollViewPager; import static androidx.fragment.app.FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT; @@ -229,9 +230,23 @@ public class MainActivity extends BaseActivity { ToastUtils.showError(e.getLocalizedMessage()); e.printStackTrace(); } + firstInit(); + LanZouApi.INSTANCE.checkSubscribeUpdate(this); AdUtils.adRecord("Usage", "usTimes"); } + private void firstInit() { + SharedPreUtils sru = SharedPreUtils.getInstance(); + if (!sru.getBoolean("firstInit")) { + DialogCreator.createCommonDialog(this, "首次使用书源订阅提醒", + "感谢您选择风月读书,当前应用没有任何书源," + + "建议前往书源订阅界面获取书源(也可自行前往书源管理导入书源),是否前往订阅书源?", + false, (dialog, which) -> startActivity(new Intent(this, SourceSubscribeActivity.class)), + null); + sru.putBoolean("firstInit", true); + } + } + private void reLoadFragment() { List fragments = getSupportFragmentManager().getFragments(); mBookcaseFragment = (BookcaseFragment) fragments.get(0); 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 2be22e0..88404fe 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 @@ -280,17 +280,16 @@ public class SearchBookActivity extends BaseActivity { }); initHistoryList(); adBean = AdUtils.getAdConfig().getSearch(); - if (AdUtils.getAdConfig().isHasAd() && AdUtils.adTime("search", adBean)) { - initAd(); - } + initAd(); } + private void initAd() { AdUtils.checkHasAd().subscribe(new MySingleObserver() { @Override public void onSuccess(@NonNull Boolean aBoolean) { - if (aBoolean) { + if (aBoolean && AdUtils.adTime("search", adBean)) { if (adBean.getStatus() == 1) { - AdUtils.getFlowAd(SearchBookActivity.this, 1, view ->{ + AdUtils.getFlowAd(SearchBookActivity.this, 1, view -> { binding.getRoot().addView(view, 6); }, "search"); } else if (adBean.getStatus() == 2) { diff --git a/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceSubscribeActivity.kt b/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceSubscribeActivity.kt index 1c1cb7d..c5c34ff 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceSubscribeActivity.kt +++ b/app/src/main/java/xyz/fycz/myreader/ui/activity/SourceSubscribeActivity.kt @@ -1,18 +1,33 @@ package xyz.fycz.myreader.ui.activity +import android.app.Activity import android.os.Bundle +import android.view.View import androidx.appcompat.widget.Toolbar import androidx.recyclerview.widget.LinearLayoutManager +import com.kongzue.dialogx.dialogs.BottomMenu +import io.reactivex.disposables.Disposable import xyz.fycz.myreader.R import xyz.fycz.myreader.base.BaseActivity import xyz.fycz.myreader.base.adapter.BaseListAdapter import xyz.fycz.myreader.base.adapter.IViewHolder +import xyz.fycz.myreader.base.observer.MyObserver +import xyz.fycz.myreader.base.observer.MySingleObserver import xyz.fycz.myreader.common.URLCONST import xyz.fycz.myreader.databinding.ActivitySourceSubscribeBinding import xyz.fycz.myreader.entity.lanzou.LanZouFile +import xyz.fycz.myreader.greendao.DbManager import xyz.fycz.myreader.greendao.entity.SubscribeFile +import xyz.fycz.myreader.greendao.entity.rule.BookSource +import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager import xyz.fycz.myreader.ui.adapter.holder.SourceFileHolder +import xyz.fycz.myreader.ui.dialog.DialogCreator +import xyz.fycz.myreader.ui.dialog.LoadingDialog +import xyz.fycz.myreader.util.SharedPreUtils import xyz.fycz.myreader.util.ToastUtils +import xyz.fycz.myreader.util.utils.AdUtils +import xyz.fycz.myreader.util.utils.AdUtils.FlowAd +import xyz.fycz.myreader.util.utils.RxUtils import xyz.fycz.myreader.webapi.LanZouApi /** @@ -23,6 +38,7 @@ class SourceSubscribeActivity : BaseActivity() { private lateinit var binding: ActivitySourceSubscribeBinding private lateinit var fileAdapter: BaseListAdapter private var page = 1 + private var subscribeDis: Disposable? = null override fun bindView() { binding = ActivitySourceSubscribeBinding.inflate(layoutInflater) @@ -95,22 +111,144 @@ class SourceSubscribeActivity : BaseActivity() { override fun initClick() { super.initClick() + fileAdapter.setOnItemClickListener { _, pos -> + val file = fileAdapter.getItem(pos) + val menu = mutableListOf() + val subscribed = DbManager.getDaoSession().subscribeFileDao.load(file.id) + if (subscribed != null) { + menu.add("更新订阅") + menu.add("取消订阅") + } else { + menu.add("订阅该书源") + } + val checkSubscribeUpdate = + SharedPreUtils.getInstance().getBoolean("checkSubscribeUpdate", true) + if (checkSubscribeUpdate) { + menu.add("自动检查订阅更新:已开启") + } else { + menu.add("自动检查订阅更新:已关闭") + } + BottomMenu.show(file.name, menu) + .setOnMenuItemClickListener { _, text, _ -> + when (text) { + "更新订阅", "订阅该书源" -> preSubscribe(file, pos) + "取消订阅" -> { + DbManager.getDaoSession().subscribeFileDao.deleteByKey(file.id) + fileAdapter.notifyItemChanged(pos) + DialogCreator.createCommonDialog( + this, "取消订阅成功", + "是否同时删除此订阅获取的书源?", false, { _, _ -> + BookSourceManager.removeSourceBySubscribe(file) + ToastUtils.showSuccess("书源删除成功") + setResult(Activity.RESULT_OK) + }, null + ) + } + "自动检查订阅更新:已开启" -> { + SharedPreUtils.getInstance().putBoolean("checkSubscribeUpdate", false) + ToastUtils.showSuccess("自动检查订阅更新已关闭") + } + "自动检查订阅更新:已关闭" -> { + SharedPreUtils.getInstance().putBoolean("checkSubscribeUpdate", true) + ToastUtils.showSuccess("自动检查订阅更新已开启") + } + } + false + }.setCancelButton(R.string.cancel) + } + } + + private fun preSubscribe(file: SubscribeFile, pos: Int) { + AdUtils.checkHasAd().subscribe(object : MySingleObserver() { + override fun onSuccess(aBoolean: Boolean) { + if (aBoolean && AdUtils.getAdConfig().isSubSource) { + DialogCreator.createCommonDialog( + this@SourceSubscribeActivity, "订阅书源", + "确定要订阅该书源吗?\n点击确定观看一段视频后即可完成订阅", true, { _, _ -> + AdUtils.showRewardVideoAd(this@SourceSubscribeActivity) { + ToastUtils.showSuccess("视频观看完成,正在为您订阅书源") + subscribe(file, pos) + } + }, null + ) + } else { + DialogCreator.createCommonDialog( + this@SourceSubscribeActivity, "订阅书源", + "确定要订阅该书源吗?\n点击确定即可完成订阅", true, { _, _ -> + subscribe(file, pos) + }, null + ) + } + } + }) } - private fun lanZouFile2SubscribeFile(lanZouFile: List): ArrayList { - val files = ArrayList() + private fun subscribe(file: SubscribeFile, pos: Int) { + val dialog = LoadingDialog(this, "正在订阅") { + subscribeDis?.dispose() + } + dialog.show() + val oldSources = BookSourceManager.getSourceBySubscribe(file) + BookSourceManager.removeBookSources(oldSources) + BookSourceManager.importSource(file.url, file.id) + .compose { RxUtils.toSimpleSingle(it) } + .subscribe(object : MyObserver>() { + override fun onSubscribe(d: Disposable) { + super.onSubscribe(d) + addDisposable(d) + subscribeDis = d + } + + override fun onNext(sources: List) { + val size: Int = sources.size + if (sources.isNotEmpty()) { + DbManager.getDaoSession().subscribeFileDao.insertOrReplace(file) + fileAdapter.notifyItemChanged(pos) + ToastUtils.showSuccess(String.format("书源订阅成功,成功获取到%s个书源", size)) + setResult(Activity.RESULT_OK) + } else { + ToastUtils.showError("订阅失败,请联系作者反馈\nsources.size==0") + BookSourceManager.addBookSource(oldSources) + } + dialog.dismiss() + } + + override fun onError(e: Throwable) { + super.onError(e) + e.printStackTrace() + BookSourceManager.addBookSource(oldSources) + ToastUtils.showError("订阅失败,请联系作者反馈\n" + e.localizedMessage) + dialog.dismiss() + } + }) + } + + private fun lanZouFile2SubscribeFile(lanZouFile: List): MutableList { + val fileMap = LinkedHashMap() lanZouFile.forEach { val param = it.name_all.removeSuffix(".txt").split("#") - files.add( - SubscribeFile( - param[0], - param[1], - URLCONST.LAN_ZOU_URL + "/${it.id}", - param[2], - it.size - ) - ) + if (fileMap.containsKey(param[0])) { + if (fileMap[param[0]]!!.date < param[2]) { + fileMap[param[0]] = + SubscribeFile( + param[0], + param[1].replace("nv", "女"), + URLCONST.LAN_ZOU_URL + "/${it.id}", + param[2], + it.size + ) + } + } else { + fileMap[param[0]] = + SubscribeFile( + param[0], + param[1].replace("nv", "女"), + URLCONST.LAN_ZOU_URL + "/${it.id}", + param[2], + it.size + ) + } } - return files + return fileMap.values.toMutableList() } } \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SourceFileHolder.kt b/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SourceFileHolder.kt index 6888891..6447b8b 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SourceFileHolder.kt +++ b/app/src/main/java/xyz/fycz/myreader/ui/adapter/holder/SourceFileHolder.kt @@ -1,11 +1,15 @@ package xyz.fycz.myreader.ui.adapter.holder import android.annotation.SuppressLint +import android.text.SpannableString +import android.text.Spanned +import android.text.style.ForegroundColorSpan import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import xyz.fycz.myreader.R import xyz.fycz.myreader.base.adapter.ViewHolderImpl import xyz.fycz.myreader.entity.lanzou.LanZouFile +import xyz.fycz.myreader.greendao.DbManager import xyz.fycz.myreader.greendao.entity.SubscribeFile /** @@ -27,10 +31,36 @@ class SourceFileHolder : ViewHolderImpl() { } @SuppressLint("SetTextI18n") - override fun onBind(holder: RecyclerView.ViewHolder?, data: SubscribeFile?, pos: Int) { - data?.let { - name.text = data.name - sizeTime.text = "${data.size} ${data.date}" + override fun onBind(holder: RecyclerView.ViewHolder, data: SubscribeFile, pos: Int) { + val subscribed = DbManager.getDaoSession().subscribeFileDao.load(data.id) + var nameStr = data.name + var isSubscribed = false + var hasUpdate = false + if (subscribed != null) { + isSubscribed = true + nameStr = "[已订阅]$nameStr" + if (subscribed.date < data.date) { + hasUpdate = true + nameStr = "$nameStr(有更新)" + } } + val spannableString = SpannableString(nameStr) + + if (isSubscribed) { + spannableString.setSpan( + ForegroundColorSpan(context.resources.getColor(R.color.toast_blue)), + 0, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE + ) + } + if (hasUpdate) { + spannableString.setSpan( + ForegroundColorSpan(context.resources.getColor(R.color.toast_red)), + nameStr.length - 5, nameStr.length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE + ) + } + + name.text = spannableString + + sizeTime.text = "${data.size} ${data.date}" } } \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java b/app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java index 5bf7791..7612354 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java +++ b/app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java @@ -223,7 +223,7 @@ public class DIYSourceFragment extends BaseFragment { } }); dialog.show(); - Observable> observable = BookSourceManager.importSource(text); + Observable> observable = BookSourceManager.importSource(text, ""); if (observable != null) { observable.subscribe(new MyObserver>() { @Override diff --git a/app/src/main/java/xyz/fycz/myreader/ui/fragment/SubscribeSourceFragment.kt b/app/src/main/java/xyz/fycz/myreader/ui/fragment/SubscribeSourceFragment.kt index 0aeb580..defd55f 100644 --- a/app/src/main/java/xyz/fycz/myreader/ui/fragment/SubscribeSourceFragment.kt +++ b/app/src/main/java/xyz/fycz/myreader/ui/fragment/SubscribeSourceFragment.kt @@ -1,5 +1,6 @@ package xyz.fycz.myreader.ui.fragment +import android.app.Activity import android.content.DialogInterface import android.content.Intent import android.os.Bundle @@ -12,6 +13,7 @@ import xyz.fycz.myreader.R import xyz.fycz.myreader.base.BaseFragment import xyz.fycz.myreader.base.adapter2.onClick import xyz.fycz.myreader.base.observer.MySingleObserver +import xyz.fycz.myreader.common.APPCONST import xyz.fycz.myreader.databinding.FragmentSubscribeSourceBinding import xyz.fycz.myreader.greendao.DbManager import xyz.fycz.myreader.greendao.entity.rule.BookSource @@ -20,6 +22,7 @@ import xyz.fycz.myreader.ui.activity.BookSourceActivity import xyz.fycz.myreader.ui.activity.SourceSubscribeActivity import xyz.fycz.myreader.ui.adapter.SubscribeSourceAdapter import xyz.fycz.myreader.ui.dialog.DialogCreator +import xyz.fycz.myreader.ui.dialog.MyAlertDialog import xyz.fycz.myreader.util.ToastUtils import xyz.fycz.myreader.util.utils.RxUtils import xyz.fycz.myreader.widget.DividerItemDecoration @@ -41,8 +44,12 @@ class SubscribeSourceFragment(private val sourceActivity: BookSourceActivity) : override fun initData(savedInstanceState: Bundle?) { super.initData(savedInstanceState) + getSources() + } + + private fun getSources(){ Single.create { emitter: SingleEmitter> -> - emitter.onSuccess(BookSourceManager.getAllLocalSource()) + emitter.onSuccess(BookSourceManager.getAllSubSource()) }.compose { RxUtils.toSimpleSingle(it) } .subscribe(object : MySingleObserver>() { override fun onSuccess(sources: List) { @@ -81,7 +88,8 @@ class SubscribeSourceFragment(private val sourceActivity: BookSourceActivity) : override fun initClick() { super.initClick() binding.tvSubscribeSource.onClick { - startActivity(Intent(context, SourceSubscribeActivity::class.java)) + startActivityForResult(Intent(context, SourceSubscribeActivity::class.java), + APPCONST.REQUEST_SUBSCRIBE) } binding.ivGroup.setOnClickListener { view: View? -> showSourceGroupMenu(view) @@ -92,6 +100,9 @@ class SubscribeSourceFragment(private val sourceActivity: BookSourceActivity) : } featuresMenu?.show() } + binding.tvSubscribeSourceTip.onClick { + MyAlertDialog.showTipDialogWithLink(context, getString(R.string.subscribe_source_tip), R.string.subscribe_source_detail_tip) + } } /** @@ -199,4 +210,13 @@ class SubscribeSourceFragment(private val sourceActivity: BookSourceActivity) : fun startSearch(newText: String?) { mAdapter?.filter?.filter(newText) } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + if (resultCode == Activity.RESULT_OK) { + if (requestCode == APPCONST.REQUEST_SUBSCRIBE) { + getSources() + } + } + super.onActivityResult(requestCode, resultCode, data) + } } \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java b/app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java index ba45616..a27d1bc 100644 --- a/app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java +++ b/app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java @@ -50,7 +50,8 @@ public class AdUtils { adConfig = GsonExtensionsKt.getGSON().fromJson(config, AdConfig.class); if (adConfig == null || adConfig.getBackAdTime() == 0) { adConfig = new AdConfig(false, 60, 20, - 60, 6, 3, 48); + 60, 6, 3, 48, + true); } } diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt b/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt index 42b241b..0faf7f6 100644 --- a/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt +++ b/app/src/main/java/xyz/fycz/myreader/webapi/LanZouApi.kt @@ -1,5 +1,7 @@ package xyz.fycz.myreader.webapi +import android.content.Context +import android.content.Intent import android.util.Log import com.google.gson.JsonParser import io.reactivex.Observable @@ -10,11 +12,15 @@ import org.jsoup.Jsoup import xyz.fycz.myreader.common.URLCONST import xyz.fycz.myreader.entity.lanzou.LanZouFile import xyz.fycz.myreader.entity.lanzou.LanZouParseBean +import xyz.fycz.myreader.greendao.DbManager import xyz.fycz.myreader.model.third3.Coroutine import xyz.fycz.myreader.model.third3.http.getProxyClient import xyz.fycz.myreader.model.third3.http.newCallResponseBody import xyz.fycz.myreader.model.third3.http.postForm import xyz.fycz.myreader.model.third3.http.text +import xyz.fycz.myreader.ui.activity.SourceSubscribeActivity +import xyz.fycz.myreader.ui.dialog.DialogCreator +import xyz.fycz.myreader.util.SharedPreUtils import xyz.fycz.myreader.util.ToastUtils import xyz.fycz.myreader.util.help.StringHelper import xyz.fycz.myreader.util.utils.* @@ -31,6 +37,41 @@ import kotlin.collections.HashMap object LanZouApi { private val paramCathe = mutableMapOf>() + fun checkSubscribeUpdate(context: Context) { + if (!SharedPreUtils.getInstance().getBoolean("checkSubscribeUpdate", true)) return + if (DbManager.getDaoSession().subscribeFileDao.count() == 0L) return + getFoldFiles(URLCONST.SUB_SOURCE_URL, 1, "fm9a") + .onSuccess { + it?.let { + for (file in it) { + val param = file.name_all.removeSuffix(".txt").split("#") + val subscribed = DbManager.getDaoSession().subscribeFileDao.load(param[0]) + subscribed?.let { sub -> + if (sub.date < param[2]) { + DialogCreator.createThreeButtonDialog(context, + "书源订阅更新", "发现有更新的订阅书源,是否前往更新?", + true, "关闭订阅更新提醒", "取消", + "确定", { _, _ -> + SharedPreUtils.getInstance() + .putBoolean("checkSubscribeUpdate", false) + ToastUtils.showSuccess("自动检查订阅更新已关闭") + }, null, { _, _ -> + context.startActivity( + Intent( + context, + SourceSubscribeActivity::class.java + ) + ) + } + ) + return@onSuccess + } + } + } + } + } + } + fun getFoldFiles( foldUrl: String, page: Int, diff --git a/app/src/main/res/layout/item_lan_zou_file.xml b/app/src/main/res/layout/item_lan_zou_file.xml index 58af23a..b7019a2 100644 --- a/app/src/main/res/layout/item_lan_zou_file.xml +++ b/app/src/main/res/layout/item_lan_zou_file.xml @@ -11,7 +11,7 @@ android:layout_height="wrap_content" android:orientation="vertical" android:paddingVertical="10dp" - android:paddingHorizontal="5dp"> + android:paddingHorizontal="10dp"> 仅显示云服务 显示用户及云服务 隐藏用户及云服务 + 1、由于作者没时间维护内置书源导致大部分内置书源已经没法使用,故推出订阅书源 + \n\n2、订阅书源全部搜集自网络,将会每月更新一次\n\n3、订阅书源目前处于测试阶段,如出现bug,请前往QQ频道或QQ群(1085028304)进行反馈 diff --git a/app/version_code.properties b/app/version_code.properties index 2b9fdba..5eb6ec4 100644 --- a/app/version_code.properties +++ b/app/version_code.properties @@ -1,3 +1,3 @@ #Fri Jun 18 21:45:31 CST 2021 -VERSION_CODE=238 +VERSION_CODE=239 NEED_CREATE_RELEASE=true