pull/21/head
fengyuecanzhu 3 years ago
parent 72dcbfa1d2
commit 1d4d03e590
  1. 2
      .idea/misc.xml
  2. 2
      app/build.gradle
  3. 1
      app/src/main/AndroidManifest.xml
  4. 11
      app/src/main/assets/updatelog.fy
  5. 2
      app/src/main/java/xyz/fycz/myreader/application/App.java
  6. 5
      app/src/main/java/xyz/fycz/myreader/base/BaseActivity.java
  7. 2
      app/src/main/java/xyz/fycz/myreader/base/BaseTabActivity.java
  8. 2
      app/src/main/java/xyz/fycz/myreader/common/APPCONST.java
  9. 4
      app/src/main/java/xyz/fycz/myreader/common/URLCONST.java
  10. 18
      app/src/main/java/xyz/fycz/myreader/entity/ad/AdConfig.java
  11. 46
      app/src/main/java/xyz/fycz/myreader/model/user/User.java
  12. 52
      app/src/main/java/xyz/fycz/myreader/model/user/UserService.kt
  13. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java
  14. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/AdSettingActivity.java
  15. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/AuthEmailActivity.kt
  16. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/BookDetailedActivity.java
  17. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/BookInfoEditActivity.java
  18. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/BookSourceActivity.java
  19. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/BookstoreActivity.java
  20. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/CatalogActivity.java
  21. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/CrashActivity.java
  22. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/DonateActivity.java
  23. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/FeedbackActivity.java
  24. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/FileSystemActivity.java
  25. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/FindBookActivity.java
  26. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/FontsActivity.java
  27. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/GroupManagerActivity.kt
  28. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/LoginActivity.java
  29. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java
  30. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/MoreSettingActivity.java
  31. 5
      app/src/main/java/xyz/fycz/myreader/ui/activity/QRCodeScanActivity.java
  32. 5
      app/src/main/java/xyz/fycz/myreader/ui/activity/ReadActivity.java
  33. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/ReadRecordActivity.java
  34. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/RegisterActivity.java
  35. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/RemoveAdActivity.kt
  36. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/ReplaceRuleActivity.java
  37. 2
      app/src/main/java/xyz/fycz/myreader/ui/activity/RestartActivity.kt
  38. 9
      app/src/main/java/xyz/fycz/myreader/ui/activity/SearchBookActivity.java
  39. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/SearchWordActivity.kt
  40. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/SourceDebugActivity.java
  41. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/SourceEditActivity.java
  42. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/SourceLoginActivity.java
  43. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/SourceSubscribeActivity.kt
  44. 3
      app/src/main/java/xyz/fycz/myreader/ui/activity/SplashActivity.java
  45. 227
      app/src/main/java/xyz/fycz/myreader/ui/activity/UserInfoActivity.kt
  46. 45
      app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java
  47. 26
      app/src/main/java/xyz/fycz/myreader/ui/fragment/SubscribeSourceFragment.kt
  48. 21
      app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java
  49. 3
      app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java
  50. 51
      app/src/main/java/xyz/fycz/myreader/util/utils/StringUtils.java
  51. 2
      app/src/main/res/layout/activity_source_subscribe.xml
  52. 265
      app/src/main/res/layout/activity_user_info.xml
  53. 29
      app/src/main/res/layout/fragment_subscribe_source.xml
  54. 13
      app/src/main/res/values/strings.xml
  55. 2
      app/version_code.properties

@ -34,10 +34,12 @@
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_search_word.xml" value="0.144" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/activity_search_word.xml" value="0.144" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_source_debug.xml" value="0.2391304347826087" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/activity_source_debug.xml" value="0.2391304347826087" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_source_subscribe.xml" value="0.21557971014492755" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/activity_source_subscribe.xml" value="0.21557971014492755" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/activity_user_info.xml" value="0.28027681660899656" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/dialog_book_source.xml" value="0.20969202898550723" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/dialog_book_source.xml" value="0.20969202898550723" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/dialog_loading.xml" value="0.1" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/dialog_loading.xml" value="0.1" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/dialog_textview.xml" value="0.1947463768115942" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/dialog_textview.xml" value="0.1947463768115942" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fingerprint_dialog.xml" value="0.20425724637681159" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fingerprint_dialog.xml" value="0.20425724637681159" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_book_list.xml" value="0.12132725430597771" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_file_category.xml" value="0.2318840579710145" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_file_category.xml" value="0.2318840579710145" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_find_book_2.xml" value="0.12132725430597771" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_find_book_2.xml" value="0.12132725430597771" />
<entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_import_source.xml" value="0.12132725430597771" /> <entry key="..\:/android/FYReader/app/src/main/res/layout/fragment_import_source.xml" value="0.12132725430597771" />

@ -44,7 +44,7 @@ def getVersionName(){
def hun = (version / 100).toInteger() def hun = (version / 100).toInteger()
def ten = (version / 10).toInteger() % 10 def ten = (version / 10).toInteger() % 10
def one = version % 10 def one = version % 10
return hun + "." + ten + "." + one return hun + "." + ten + "." + one + "-beta"
} }
def versionN = getVersionName() def versionN = getVersionName()

@ -131,6 +131,7 @@
<activity android:name=".ui.activity.CrashActivity" /> <activity android:name=".ui.activity.CrashActivity" />
<activity android:name=".ui.activity.SourceSubscribeActivity" /> <activity android:name=".ui.activity.SourceSubscribeActivity" />
<activity android:name=".ui.activity.RemoveAdActivity" /> <activity android:name=".ui.activity.RemoveAdActivity" />
<activity android:name=".ui.activity.UserInfoActivity" />
<receiver android:name=".util.notification.NotificationClickReceiver" /> <receiver android:name=".util.notification.NotificationClickReceiver" />
<receiver android:name=".ui.presenter.BookcasePresenter$cancelDownloadReceiver" /> <receiver android:name=".ui.presenter.BookcasePresenter$cancelDownloadReceiver" />

@ -1,10 +1,17 @@
2022.03.04
风月读书v2.4.0
更新内容:
1、新增用户中心
2、修复v2.3.9版本搜索界面书源分组显示错位的问题
2022.03.03 2022.03.03
风月读书v2.3.9 风月读书v2.3.9-beta
更新内容: 更新内容:
1、新增书源订阅功能,移除内置书源,原内置书源界面改为订阅书源(注:订阅书源全部搜集自网络,每月更新) 1、新增书源订阅功能,移除内置书源,原内置书源界面改为订阅书源(订阅书源全部搜集自网络,每月更新)
2、新增去除广告功能 2、新增去除广告功能
3、设置新增我的界面显示方式 3、设置新增我的界面显示方式
4、修复已知bug 4、修复已知bug
注:此为beta版本,可能存在未知bug
2022.02.23 2022.02.23
风月读书v2.3.8 风月读书v2.3.8

@ -95,7 +95,7 @@ public class App extends Application {
initNightTheme(); initNightTheme();
// LLog.init(APPCONST.LOG_DIR); // LLog.init(APPCONST.LOG_DIR);
initDialogX(); initDialogX();
AdUtils.initAd(); //AdUtils.initAd();
} }

@ -35,15 +35,18 @@ import xyz.fycz.myreader.util.utils.AdUtils;
* @author fengyue * @author fengyue
* @date 2020/8/12 20:02 * @date 2020/8/12 20:02
*/ */
public abstract class BaseActivity extends SwipeBackActivity { public abstract class BaseActivity<VB> extends SwipeBackActivity {
private static final int INVALID_VAL = -1; private static final int INVALID_VAL = -1;
protected VB binding;
protected static final String INTENT = "intent"; protected static final String INTENT = "intent";
protected CompositeDisposable mDisposable; protected CompositeDisposable mDisposable;
protected Toolbar mToolbar; protected Toolbar mToolbar;
/****************************abstract area*************************************/ /****************************abstract area*************************************/
/** /**
* 绑定视图 * 绑定视图

@ -17,7 +17,7 @@ import xyz.fycz.myreader.R;
* @date 2020/8/12 20:02 * @date 2020/8/12 20:02
*/ */
public abstract class BaseTabActivity extends BaseActivity { public abstract class BaseTabActivity<VB> extends BaseActivity<VB> {
/**************View***************/ /**************View***************/
protected TabLayout mTlIndicator; protected TabLayout mTlIndicator;
protected ViewPager mVp; protected ViewPager mVp;

@ -104,6 +104,8 @@ public class APPCONST {
public static final int REQUEST_AUTH_EMAIL = 1016; public static final int REQUEST_AUTH_EMAIL = 1016;
public static final int REQUEST_SETTING = 1017; public static final int REQUEST_SETTING = 1017;
public static final int REQUEST_SUBSCRIBE = 1018; public static final int REQUEST_SUBSCRIBE = 1018;
public static final int REQUEST_LOGOUT = 1019;
public static final int REQUEST_RESET_PWD = 1020;
public static final int REQUEST_READ = 1; public static final int REQUEST_READ = 1;

@ -26,9 +26,9 @@ public class URLCONST {
public static final String FY_READER_URL = "https://fyreader." + getDefaultDomain(); public static final String FY_READER_URL = "https://fyreader." + getDefaultDomain();
public static final String LOG_UPLOAD_URL = FY_READER_URL + "/logUpload";
public static final String THANKS_URL = FY_READER_URL + "/thanks/";
public static final String USER_URL = "http://101.43.83.105:12123"; public static final String USER_URL = "http://101.43.83.105:12123";
public static final String LOG_UPLOAD_URL = USER_URL + "/do/logUpload";
public static final String THANKS_URL = FY_READER_URL + "/thanks/";
public static final String AD_URL = USER_URL + "/do/ad"; public static final String AD_URL = USER_URL + "/do/ad";
public static final String DONATE = "https://gitee.com/fengyuecanzhu/Donate/raw/master"; public static final String DONATE = "https://gitee.com/fengyuecanzhu/Donate/raw/master";

@ -2,6 +2,8 @@ package xyz.fycz.myreader.entity.ad;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.gson.Gson;
import xyz.fycz.myreader.util.utils.GsonExtensionsKt; import xyz.fycz.myreader.util.utils.GsonExtensionsKt;
/** /**
@ -11,8 +13,10 @@ import xyz.fycz.myreader.util.utils.GsonExtensionsKt;
public class AdConfig { public class AdConfig {
//是否云控 //是否云控
private boolean isCloud; private boolean isCloud;
//是否有广告 //是否有广告(总开关)
private boolean hasAd; private boolean hasAd;
//是否有广告(用户)
private boolean userHasAd;
//配置过期时间 //配置过期时间
private int expireTime; private int expireTime;
//应用处于后台一段时间展示开屏广告(单位:分钟) //应用处于后台一段时间展示开屏广告(单位:分钟)
@ -35,8 +39,10 @@ public class AdConfig {
public AdConfig() { public AdConfig() {
} }
public AdConfig(boolean hasAd, int expireTime, int backAdTime, int intervalAdTime, int removeAdTime, int maxRemove, int totalRemove, boolean subSource) { public AdConfig(boolean isCloud, boolean hasAd, boolean userHasAd, int expireTime, int backAdTime, int intervalAdTime, int removeAdTime, int maxRemove, int totalRemove, boolean subSource) {
this.isCloud = isCloud;
this.hasAd = hasAd; this.hasAd = hasAd;
this.userHasAd = userHasAd;
this.expireTime = expireTime; this.expireTime = expireTime;
this.backAdTime = backAdTime; this.backAdTime = backAdTime;
this.intervalAdTime = intervalAdTime; this.intervalAdTime = intervalAdTime;
@ -140,6 +146,14 @@ public class AdConfig {
this.subSource = subSource; this.subSource = subSource;
} }
public boolean isUserHasAd() {
return userHasAd;
}
public void setUserHasAd(boolean userHasAd) {
this.userHasAd = userHasAd;
}
@NonNull @NonNull
@Override @Override
public String toString() { public String toString() {

@ -1,5 +1,9 @@
package xyz.fycz.myreader.model.user; package xyz.fycz.myreader.model.user;
import androidx.annotation.NonNull;
import xyz.fycz.myreader.util.utils.GsonExtensionsKt;
/** /**
* @author fengyue * @author fengyue
* @date 2020/7/12 17:35 * @date 2020/7/12 17:35
@ -9,6 +13,9 @@ public class User {
private String userName; private String userName;
private String password; private String password;
private String email; private String email;
private String backupTime;
private String noAdTime;
private String noAdId;
public User() { public User() {
} }
@ -35,6 +42,15 @@ public class User {
this.email = email; this.email = email;
} }
public User(Integer userId, String userName, String password, String email, String backupTime, String noAdTime, String noAdId) {
this.userId = userId;
this.userName = userName;
this.password = password;
this.email = email;
this.backupTime = backupTime;
this.noAdTime = noAdTime;
this.noAdId = noAdId;
}
public Integer getUserId() { public Integer getUserId() {
return userId; return userId;
@ -67,4 +83,34 @@ public class User {
public void setEmail(String email) { public void setEmail(String email) {
this.email = email; this.email = email;
} }
public String getBackupTime() {
return backupTime;
}
public void setBackupTime(String backupTime) {
this.backupTime = backupTime;
}
public String getNoAdTime() {
return noAdTime;
}
public void setNoAdTime(String noAdTime) {
this.noAdTime = noAdTime;
}
public String getNoAdId() {
return noAdId;
}
public void setNoAdId(String noAdId) {
this.noAdId = noAdId;
}
@NonNull
@Override
public String toString() {
return GsonExtensionsKt.getGSON().toJson(this);
}
} }

@ -21,6 +21,7 @@ import xyz.fycz.myreader.util.utils.GSON
import xyz.fycz.myreader.util.utils.OkHttpUtils import xyz.fycz.myreader.util.utils.OkHttpUtils
import xyz.fycz.myreader.util.utils.RxUtils import xyz.fycz.myreader.util.utils.RxUtils
import java.io.File import java.io.File
import java.util.*
/** /**
* @author fengyue * @author fengyue
@ -97,6 +98,42 @@ object UserService {
}).compose { RxUtils.toSimpleSingle(it) } }).compose { RxUtils.toSimpleSingle(it) }
} }
fun getInfo(user: User): Single<Result> {
return Single.create(SingleOnSubscribe<Result> {
val mediaType = "application/x-www-form-urlencoded".toMediaTypeOrNull()
val body = "username=${user.userName}" +
"&password=${user.password}" +
makeAuth()
val requestBody = body.toRequestBody(mediaType)
val ret = OkHttpUtils.getHtml(URLCONST.USER_URL + "/do/getInfo", requestBody, "UTF-8")
it.onSuccess(GSON.fromJson(ret, Result::class.java))
}).compose { RxUtils.toSimpleSingle(it) }
}
fun bindId(username: String): Single<Result> {
return Single.create(SingleOnSubscribe<Result> {
val mediaType = "application/x-www-form-urlencoded".toMediaTypeOrNull()
val body = "username=${username}" +
"&deviceId=${getUUID()}" +
makeAuth()
val requestBody = body.toRequestBody(mediaType)
val ret = OkHttpUtils.getHtml(URLCONST.USER_URL + "/do/bindId", requestBody, "UTF-8")
it.onSuccess(GSON.fromJson(ret, Result::class.java))
}).compose { RxUtils.toSimpleSingle(it) }
}
fun bindCammy(username: String, cammy: String): Single<Result> {
return Single.create(SingleOnSubscribe<Result> {
val mediaType = "application/x-www-form-urlencoded".toMediaTypeOrNull()
val body = "username=${username}" +
"&cammy=$cammy" +
makeAuth()
val requestBody = body.toRequestBody(mediaType)
val ret = OkHttpUtils.getHtml(URLCONST.USER_URL + "/do/bindCammy", requestBody, "UTF-8")
it.onSuccess(GSON.fromJson(ret, Result::class.java))
}).compose { RxUtils.toSimpleSingle(it) }
}
fun webBackup(user: User): Single<Result> { fun webBackup(user: User): Single<Result> {
return Backup.backup(App.getmContext(), APPCONST.FILE_DIR + "webBackup/") return Backup.backup(App.getmContext(), APPCONST.FILE_DIR + "webBackup/")
.flatMap(Function<Boolean, SingleSource<Result>> { .flatMap(Function<Boolean, SingleSource<Result>> {
@ -195,11 +232,22 @@ object UserService {
return readConfig() != null return readConfig() != null
} }
public fun makeAuth(): String { fun getUUID(): String {
val file = FileUtils.getFile(APPCONST.QQ_DATA_DIR + "monId")
var uuid = file.readText()
if (uuid.isEmpty()) {
uuid = UUID.randomUUID().toString()
file.writeText(uuid)
}
return uuid
}
fun makeAuth(): String {
return "&signal=" + AppInfoUtils.getSingInfo( return "&signal=" + AppInfoUtils.getSingInfo(
App.getmContext(), App.getmContext(),
App.getApplication().packageName, App.getApplication().packageName,
AppInfoUtils.SHA1 AppInfoUtils.SHA1
) + "&appVersion=" + App.getVersionCode() + "&isDebug=" + App.isDebug() ) + "&appVersion=" + App.getVersionCode() +
"&deviceId=" + getUUID() + "&isDebug=" + App.isDebug()
} }
} }

@ -40,8 +40,7 @@ import xyz.fycz.myreader.webapi.LanZouApi;
* @author fengyue * @author fengyue
* @date 2020/9/18 22:21 * @date 2020/9/18 22:21
*/ */
public class AboutActivity extends BaseActivity { public class AboutActivity extends BaseActivity<ActivityAboutBinding> {
private ActivityAboutBinding binding;
@Override @Override
protected void bindView() { protected void bindView() {

@ -27,9 +27,8 @@ import xyz.fycz.myreader.util.utils.FileUtils;
* @author fengyue * @author fengyue
* @date 2021/4/23 12:51 * @date 2021/4/23 12:51
*/ */
public class AdSettingActivity extends BaseActivity { public class AdSettingActivity extends BaseActivity<ActivityAdSettingBinding> {
private ActivityAdSettingBinding binding;
private LoadingDialog loadingDialog; private LoadingDialog loadingDialog;
private SharedPreUtils spu; private SharedPreUtils spu;
private int curAdTimes; private int curAdTimes;

@ -30,9 +30,8 @@ import java.util.*
* @author fengyue * @author fengyue
* @date 2021/12/9 15:20 * @date 2021/12/9 15:20
*/ */
class AuthEmailActivity : BaseActivity(), SingleObserver<Result> { class AuthEmailActivity : BaseActivity<ActivityAuthEmailBinding>(), SingleObserver<Result> {
private lateinit var binding: ActivityAuthEmailBinding
private var email = "" private var email = ""
private var password = "" private var password = ""
private var emailCode = "" private var emailCode = ""

@ -73,9 +73,8 @@ import xyz.fycz.myreader.webapi.crawler.base.ReadCrawler;
* @author fengyue * @author fengyue
* @date 2020/8/17 11:39 * @date 2020/8/17 11:39
*/ */
public class BookDetailedActivity extends BaseActivity { public class BookDetailedActivity extends BaseActivity<ActivityBookDetailBinding> {
private ActivityBookDetailBinding binding;
private static final String TAG = BookDetailedActivity.class.getSimpleName(); private static final String TAG = BookDetailedActivity.class.getSimpleName();
private Book mBook; private Book mBook;

@ -28,8 +28,7 @@ import xyz.fycz.myreader.webapi.crawler.ReadCrawlerUtil;
* @author fengyue * @author fengyue
* @date 2021/4/24 15:05 * @date 2021/4/24 15:05
*/ */
public class BookInfoEditActivity extends BaseActivity { public class BookInfoEditActivity extends BaseActivity<ActivityBookInfoEditBinding> {
private ActivityBookInfoEditBinding binding;
private Book mBook; private Book mBook;
private String imgUrl; private String imgUrl;
private String bookName; private String bookName;

@ -29,9 +29,8 @@ import xyz.fycz.myreader.ui.fragment.SubscribeSourceFragment;
* @author fengyue * @author fengyue
* @date 2021/2/10 9:14 * @date 2021/2/10 9:14
*/ */
public class BookSourceActivity extends BaseTabActivity { public class BookSourceActivity extends BaseTabActivity<ActivityBooksourceBinding> {
private ActivityBooksourceBinding binding;
private SearchView searchView; private SearchView searchView;
@Override @Override

@ -43,8 +43,7 @@ import xyz.fycz.myreader.webapi.crawler.find.QiDianMobileRank;
* @author fengyue * @author fengyue
* @date 2020/9/13 21:11 * @date 2020/9/13 21:11
*/ */
public class BookstoreActivity extends BaseActivity { public class BookstoreActivity extends BaseActivity<ActiityBookstoreBinding> {
private ActiityBookstoreBinding binding;
private FindCrawler3 findCrawler3; private FindCrawler3 findCrawler3;
private LinearLayoutManager mLinearLayoutManager; private LinearLayoutManager mLinearLayoutManager;

@ -21,10 +21,8 @@ import xyz.fycz.myreader.ui.fragment.CatalogFragment;
/** /**
* 书籍目录activity * 书籍目录activity
*/ */
public class CatalogActivity extends BaseActivity { public class CatalogActivity extends BaseActivity<ActivityCatalogBinding> {
private ActivityCatalogBinding binding;
private SearchView searchView; private SearchView searchView;
private Book mBook; private Book mBook;

@ -39,9 +39,7 @@ import xyz.fycz.myreader.util.ToastUtils;
* @author fengyue * @author fengyue
* @date 2022/1/22 9:15 * @date 2022/1/22 9:15
*/ */
public class CrashActivity extends BaseActivity { public class CrashActivity extends BaseActivity<ActivityCrashBinding> {
private ActivityCrashBinding binding;
/** /**
* 报错代码行数正则表达式 * 报错代码行数正则表达式
*/ */

@ -29,9 +29,8 @@ import xyz.fycz.myreader.util.utils.AdUtils;
* @author fengyue * @author fengyue
* @date 2021/4/23 21:23 * @date 2021/4/23 21:23
*/ */
public class DonateActivity extends BaseActivity { public class DonateActivity extends BaseActivity<ActivityDonateBinding> {
private ActivityDonateBinding binding;
private static final String TAG = DonateActivity.class.getSimpleName(); private static final String TAG = DonateActivity.class.getSimpleName();
@Override @Override

@ -20,9 +20,7 @@ import xyz.fycz.myreader.ui.dialog.DialogCreator;
* @author fengyue * @author fengyue
* @date 2020/12/24 20:48 * @date 2020/12/24 20:48
*/ */
public class FeedbackActivity extends BaseActivity { public class FeedbackActivity extends BaseActivity<ActivityFeedbackBinding> {
private ActivityFeedbackBinding binding;
@Override @Override
protected void bindView() { protected void bindView() {

@ -29,11 +29,9 @@ import xyz.fycz.myreader.util.utils.FileUtils;
* @date 2020/8/12 20:02 * @date 2020/8/12 20:02
*/ */
public class FileSystemActivity extends BaseTabActivity { public class FileSystemActivity extends BaseTabActivity<ActivityFileSystemBinding> {
private static final String TAG = "FileSystemActivity"; private static final String TAG = "FileSystemActivity";
private ActivityFileSystemBinding binding;
private LocalBookFragment mLocalFragment; private LocalBookFragment mLocalFragment;
private FileCategoryFragment mCategoryFragment; private FileCategoryFragment mCategoryFragment;
private BaseFileFragment mCurFragment; private BaseFileFragment mCurFragment;

@ -35,8 +35,7 @@ import xyz.fycz.myreader.webapi.crawler.source.find.ThirdFindCrawler;
* @author fengyue * @author fengyue
* @date 2021/7/21 20:10 * @date 2021/7/21 20:10
*/ */
public class FindBookActivity extends BaseActivity { public class FindBookActivity extends BaseActivity<ActivityFindBookBinding> {
private ActivityFindBookBinding binding;
private BookSource source; private BookSource source;
private FindCrawler findCrawler; private FindCrawler findCrawler;
private List<String> groups; private List<String> groups;

@ -34,8 +34,7 @@ import static xyz.fycz.myreader.util.UriFileUtil.getPath;
* @author fengyue * @author fengyue
* @date 2020/9/19 12:04 * @date 2020/9/19 12:04
*/ */
public class FontsActivity extends BaseActivity { public class FontsActivity extends BaseActivity<ActivityFontsBinding> {
private ActivityFontsBinding binding;
private ArrayList<Font> mFonts; private ArrayList<Font> mFonts;
private FontsAdapter mFontsAdapter; private FontsAdapter mFontsAdapter;

@ -25,8 +25,7 @@ import xyz.fycz.myreader.util.SharedPreUtils
* @author fengyue * @author fengyue
* @date 2021/8/30 12:48 * @date 2021/8/30 12:48
*/ */
class GroupManagerActivity : BaseActivity() { class GroupManagerActivity : BaseActivity<ActivityGroupManagerBinding>() {
private lateinit var binding: ActivityGroupManagerBinding
private lateinit var adapter: BookGroupAdapter private lateinit var adapter: BookGroupAdapter

@ -38,9 +38,8 @@ import xyz.fycz.myreader.util.utils.StringUtils;
* @author fengyue * @author fengyue
* @date 2020/9/18 22:27 * @date 2020/9/18 22:27
*/ */
public class LoginActivity extends BaseActivity implements TextWatcher { public class LoginActivity extends BaseActivity<ActivityLoginBinding> implements TextWatcher {
private ActivityLoginBinding binding;
private String code; private String code;
private Disposable loginDisp; private Disposable loginDisp;
private LoadingDialog dialog; private LoadingDialog dialog;

@ -58,11 +58,9 @@ import static androidx.fragment.app.FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CU
* @author fengyue * @author fengyue
* @date 2020/9/13 13:03 * @date 2020/9/13 13:03
*/ */
public class MainActivity extends BaseActivity { public class MainActivity extends BaseActivity<ActivityMainBinding> {
public static final String TAG = MainActivity.class.getSimpleName(); public static final String TAG = MainActivity.class.getSimpleName();
private ActivityMainBinding binding;
private List<Fragment> mFragments = new ArrayList<>(); private List<Fragment> mFragments = new ArrayList<>();
private String[] titles; private String[] titles;
private String groupName; private String groupName;

@ -63,9 +63,7 @@ import static xyz.fycz.myreader.common.APPCONST.BOOK_CACHE_PATH;
* 阅读界面的更多设置 * 阅读界面的更多设置
*/ */
public class MoreSettingActivity extends BaseActivity implements SharedPreferences.OnSharedPreferenceChangeListener { public class MoreSettingActivity extends BaseActivity<ActivityMoreSettingBinding> implements SharedPreferences.OnSharedPreferenceChangeListener {
private ActivityMoreSettingBinding binding;
private boolean needRefresh; private boolean needRefresh;
private boolean upMenu; private boolean upMenu;

@ -37,10 +37,7 @@ import static xyz.fycz.myreader.util.UriFileUtil.getPath;
* @date 2020/11/30 8:31 * @date 2020/11/30 8:31
*/ */
public class QRCodeScanActivity extends BaseActivity implements QRCodeView.Delegate { public class QRCodeScanActivity extends BaseActivity<ActivityQrcodeCaptureBinding> implements QRCodeView.Delegate {
private ActivityQrcodeCaptureBinding binding;
private final int REQUEST_QR_IMAGE = 202; private final int REQUEST_QR_IMAGE = 202;
private boolean flashlightIsOpen; private boolean flashlightIsOpen;

@ -124,12 +124,9 @@ import static xyz.fycz.myreader.util.UriFileUtil.getPath;
* @author fengyue * @author fengyue
* @date 2020/10/21 16:46 * @date 2020/10/21 16:46
*/ */
public class ReadActivity extends BaseActivity implements ColorPickerDialogListener, View.OnTouchListener { public class ReadActivity extends BaseActivity<ActivityReadBinding> implements ColorPickerDialogListener, View.OnTouchListener {
private static final String TAG = ReadActivity.class.getSimpleName(); private static final String TAG = ReadActivity.class.getSimpleName();
/*****************************View***********************************/
private ActivityReadBinding binding;
/***************************variable*****************************/ /***************************variable*****************************/
private Book mBook; private Book mBook;
private List<Book> aBooks; private List<Book> aBooks;

@ -41,8 +41,7 @@ import xyz.fycz.myreader.widget.DividerItemDecoration;
* @author fengyue * @author fengyue
* @date 2021/6/1 19:07 * @date 2021/6/1 19:07
*/ */
public class ReadRecordActivity extends BaseActivity { public class ReadRecordActivity extends BaseActivity<ActivityReadRecordBinding> {
private ActivityReadRecordBinding binding;
private List<ReadRecord> records; private List<ReadRecord> records;
private long allTime; private long allTime;
private BaseListAdapter<ReadRecord> mAdapter; private BaseListAdapter<ReadRecord> mAdapter;

@ -31,9 +31,7 @@ import xyz.fycz.myreader.util.utils.StringUtils;
* @author fengyue * @author fengyue
* @date 2020/9/18 22:37 * @date 2020/9/18 22:37
*/ */
public class RegisterActivity extends BaseActivity { public class RegisterActivity extends BaseActivity<ActivityRegisterBinding> {
private ActivityRegisterBinding binding;
private String code; private String code;
private String username = ""; private String username = "";

@ -15,8 +15,7 @@ import xyz.fycz.myreader.util.utils.AdUtils
* @author fengyue * @author fengyue
* @date 2022/3/3 17:04 * @date 2022/3/3 17:04
*/ */
class RemoveAdActivity : BaseActivity() { class RemoveAdActivity : BaseActivity<ActivityRemoveAdBinding>() {
private lateinit var binding: ActivityRemoveAdBinding
private var rewardLastTime = 0L private var rewardLastTime = 0L
override fun bindView() { override fun bindView() {

@ -59,9 +59,7 @@ import static xyz.fycz.myreader.util.UriFileUtil.getPath;
* @author fengyue * @author fengyue
* @date 2021/1/19 10:02 * @date 2021/1/19 10:02
*/ */
public class ReplaceRuleActivity extends BaseActivity { public class ReplaceRuleActivity extends BaseActivity<ActivityReplaceRuleBinding> {
private ActivityReplaceRuleBinding binding;
private SearchView searchView; private SearchView searchView;
private List<ReplaceRuleBean> mReplaceRules; private List<ReplaceRuleBean> mReplaceRules;

@ -13,7 +13,7 @@ import xyz.fycz.myreader.util.ToastUtils
* @author fengyue * @author fengyue
* @date 2022/1/22 8:57 * @date 2022/1/22 8:57
*/ */
class RestartActivity : BaseActivity() { class RestartActivity<VB> : BaseActivity<VB>() {
override fun bindView() {} override fun bindView() {}
companion object { companion object {

@ -72,9 +72,7 @@ import xyz.fycz.myreader.widget.TagGroup;
* @author fengyue * @author fengyue
* @date 2020/9/18 21:58 * @date 2020/9/18 21:58
*/ */
public class SearchBookActivity extends BaseActivity { public class SearchBookActivity extends BaseActivity<ActivitySearchBookBinding> {
private ActivitySearchBookBinding binding;
private SearchAdapter mSearchBookAdapter; private SearchAdapter mSearchBookAdapter;
private String searchKey;//搜索关键字 private String searchKey;//搜索关键字
@ -416,9 +414,10 @@ public class SearchBookActivity extends BaseActivity {
if (menu == null) return; if (menu == null) return;
String searchGroup = SharedPreUtils.getInstance().getString("searchGroup"); String searchGroup = SharedPreUtils.getInstance().getString("searchGroup");
menu.removeGroup(R.id.source_group); menu.removeGroup(R.id.source_group);
MenuItem item = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, R.string.all_source); MenuItem first = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, R.string.all_source);
boolean hasChecked = false; boolean hasChecked = false;
List<String> groupList = BookSourceManager.getEnableGroupList(); List<String> groupList = BookSourceManager.getEnableGroupList();
MenuItem item;
for (String groupName : groupList) { for (String groupName : groupList) {
item = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, groupName); item = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, groupName);
if (groupName.equals(searchGroup)) { if (groupName.equals(searchGroup)) {
@ -427,7 +426,7 @@ public class SearchBookActivity extends BaseActivity {
} }
} }
if (!hasChecked || "".equals(searchGroup)) { if (!hasChecked || "".equals(searchGroup)) {
item.setChecked(true); first.setChecked(true);
} }
menu.setGroupCheckable(R.id.source_group, true, true); menu.setGroupCheckable(R.id.source_group, true, true);
} }

@ -31,9 +31,7 @@ import xyz.fycz.myreader.widget.page.PageLoader
* @author fengyue * @author fengyue
* @date 2021/12/5 19:57 * @date 2021/12/5 19:57
*/ */
class SearchWordActivity : BaseActivity() { class SearchWordActivity : BaseActivity<ActivitySearchWordBinding>() {
private lateinit var binding: ActivitySearchWordBinding
private lateinit var book: Book private lateinit var book: Book
private lateinit var chapters: List<Chapter> private lateinit var chapters: List<Chapter>
private lateinit var pageLoader: PageLoader private lateinit var pageLoader: PageLoader

@ -60,9 +60,7 @@ import static xyz.fycz.myreader.util.utils.OkHttpUtils.getCookies;
* @author fengyue * @author fengyue
* @date 2021/2/12 18:55 * @date 2021/2/12 18:55
*/ */
public class SourceDebugActivity extends BaseActivity { public class SourceDebugActivity extends BaseActivity<ActivitySourceDebugBinding> {
private ActivitySourceDebugBinding binding;
private DebugEntity debugEntity; private DebugEntity debugEntity;
private ReadCrawler rc; private ReadCrawler rc;
private Disposable disposable; private Disposable disposable;

@ -40,9 +40,7 @@ import xyz.fycz.myreader.webapi.crawler.source.MatcherCrawler;
* @author fengyue * @author fengyue
* @date 2021/2/9 10:54 * @date 2021/2/9 10:54
*/ */
public class SourceEditActivity extends BaseActivity { public class SourceEditActivity extends BaseActivity<ActivitySourceEditBinding> {
private ActivitySourceEditBinding binding;
private BookSource source; private BookSource source;
private List<EditEntity> sourceEntities; private List<EditEntity> sourceEntities;
private List<EditEntity> searchEntities; private List<EditEntity> searchEntities;

@ -24,8 +24,7 @@ import xyz.fycz.myreader.util.ToastUtils;
* @author fengyue * @author fengyue
* @date 2021/5/15 10:43 * @date 2021/5/15 10:43
*/ */
public class SourceLoginActivity extends BaseActivity { public class SourceLoginActivity extends BaseActivity<ActivitySourceLoginBinding> {
private ActivitySourceLoginBinding binding;
private BookSource bookSource; private BookSource bookSource;
private boolean checking = false; private boolean checking = false;

@ -34,8 +34,7 @@ import xyz.fycz.myreader.webapi.LanZouApi
* @author fengyue * @author fengyue
* @date 2022/3/3 9:56 * @date 2022/3/3 9:56
*/ */
class SourceSubscribeActivity : BaseActivity() { class SourceSubscribeActivity : BaseActivity<ActivitySourceSubscribeBinding>() {
private lateinit var binding: ActivitySourceSubscribeBinding
private lateinit var fileAdapter: BaseListAdapter<SubscribeFile> private lateinit var fileAdapter: BaseListAdapter<SubscribeFile>
private var page = 1 private var page = 1
private var subscribeDis: Disposable? = null private var subscribeDis: Disposable? = null

@ -43,12 +43,11 @@ import xyz.fycz.myreader.util.utils.MD5Utils;
import xyz.fycz.myreader.util.utils.OkHttpUtils; import xyz.fycz.myreader.util.utils.OkHttpUtils;
import xyz.fycz.myreader.util.utils.SystemBarUtils; import xyz.fycz.myreader.util.utils.SystemBarUtils;
public class SplashActivity extends BaseActivity { public class SplashActivity extends BaseActivity<ActivitySplashBinding> {
/*************Constant**********/ /*************Constant**********/
public static final String TAG = SplashActivity.class.getSimpleName(); public static final String TAG = SplashActivity.class.getSimpleName();
public static int WAIT_INTERVAL = 0; public static int WAIT_INTERVAL = 0;
private ActivitySplashBinding binding;
private SharedPreUtils spu; private SharedPreUtils spu;
private int todayAdCount; private int todayAdCount;
private int adTimes; private int adTimes;

@ -0,0 +1,227 @@
package xyz.fycz.myreader.ui.activity
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.widget.Toolbar
import io.reactivex.Single
import io.reactivex.SingleEmitter
import io.reactivex.disposables.Disposable
import org.jetbrains.anko.startActivityForResult
import xyz.fycz.myreader.R
import xyz.fycz.myreader.application.App
import xyz.fycz.myreader.base.BaseActivity
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.ActivityUserInfoBinding
import xyz.fycz.myreader.greendao.entity.rule.BookSource
import xyz.fycz.myreader.model.user.Result
import xyz.fycz.myreader.model.user.User
import xyz.fycz.myreader.model.user.UserService
import xyz.fycz.myreader.ui.dialog.LoadingDialog
import xyz.fycz.myreader.ui.dialog.MyAlertDialog
import xyz.fycz.myreader.util.ToastUtils
import xyz.fycz.myreader.util.utils.*
/**
* @author fengyue
* @date 2022/3/4 18:38
*/
class UserInfoActivity : BaseActivity<ActivityUserInfoBinding>() {
private var user: User? = null
private lateinit var dialog: LoadingDialog
private var dis: Disposable? = null
override fun bindView() {
binding = ActivityUserInfoBinding.inflate(layoutInflater)
setContentView(binding.root)
}
override fun setUpToolbar(toolbar: Toolbar?) {
super.setUpToolbar(toolbar)
setStatusBarColor(R.color.colorPrimary, true)
supportActionBar?.title = getString(R.string.userinfo)
}
override fun initData(savedInstanceState: Bundle?) {
dialog = LoadingDialog(this, "正在请求") {
dis?.dispose()
if (user == null || user?.email.isNullOrEmpty())
finish()
}
initData()
}
private fun initData() {
dialog.show()
user = UserService.readConfig()
if (user == null) {
ToastUtils.showWarring("用户未登录")
dialog.dismiss()
finish()
return
}
UserService.getInfo(user!!).subscribe(object : MySingleObserver<Result>() {
override fun onSubscribe(d: Disposable) {
addDisposable(d)
dis = d
}
override fun onSuccess(t: Result) {
if (t.code < 200) {
user = GSON.fromJsonObject<User>(GSON.toJson(t.result))
dialog.dismiss()
initInfo()
} else {
ToastUtils.showError(t.result.toString())
dialog.dismiss()
finish()
}
}
override fun onError(e: Throwable) {
ToastUtils.showError("用户信息获取失败\n" + e.localizedMessage)
dialog.dismiss()
finish()
}
})
}
private fun initInfo() {
binding.tvUsername.text = user?.userName
binding.tvEmail.text =
StringUtils.getStarString2(
user?.email, 3,
user?.email!!.length - user?.email!!.indexOf("@")
)
if (user?.backupTime.isNullOrEmpty()) {
binding.tvLastWebBackTime.text = "未同步"
} else {
binding.tvLastWebBackTime.text = user?.backupTime
}
if (user?.noAdTime.isNullOrEmpty()) {
binding.tvNoAdTime.text = "无记录"
} else {
binding.tvNoAdTime.text = user?.noAdTime
}
if (UserService.getUUID() == user?.noAdId) {
binding.tvNoAdDevice.text = "已绑定此设备"
} else {
binding.tvNoAdDevice.text = "点击绑定"
}
}
override fun initWidget() {
AdUtils.checkHasAd(true, false)
.subscribe(object : MySingleObserver<Boolean>() {
override fun onSubscribe(d: Disposable) {
addDisposable(d)
}
override fun onSuccess(t: Boolean) {
if (t) {
binding.llNoAdService.visibility = View.VISIBLE
} else {
binding.llNoAdService.visibility = View.GONE
}
}
override fun onError(e: Throwable) {
binding.llNoAdService.visibility = View.GONE
}
})
}
override fun initClick() {
binding.rlResetPwd.onClick {
val intent = Intent(this, AuthEmailActivity::class.java)
startActivityForResult(intent, APPCONST.REQUEST_RESET_PWD)
}
binding.rlNoAdDevice.onClick {
if (UserService.getUUID() != user?.noAdId) {
dialog.show()
UserService.bindId(user!!.userName)
.subscribe(object : MySingleObserver<Result>() {
override fun onSubscribe(d: Disposable) {
addDisposable(d)
dis = d
}
override fun onSuccess(t: Result) {
if (t.code < 200) {
user?.noAdId = UserService.getUUID()
ToastUtils.showSuccess("设备绑定成功")
binding.tvNoAdDevice.text = "已绑定此设备"
} else {
ToastUtils.showError(t.result.toString())
}
dialog.dismiss()
}
override fun onError(e: Throwable) {
ToastUtils.showError("设备绑定失败\n" + e.localizedMessage)
dialog.dismiss()
}
})
}
}
binding.rlCammyEnter.onClick {
var cammy = ""
MyAlertDialog.createInputDia(this, getString(R.string.cammy_enter),
"请输入卡密", "", true, 25, {
cammy = it
}, { _, _ ->
dialog.show()
UserService.bindCammy(user?.userName!!, cammy)
.subscribe(object : MySingleObserver<Result>() {
override fun onSubscribe(d: Disposable) {
addDisposable(d)
dis = d
}
override fun onSuccess(t: Result) {
if (t.code < 200) {
ToastUtils.showSuccess("卡密绑定成功,免广告服务重启后生效")
dialog.dismiss()
initData()
} else {
dialog.dismiss()
ToastUtils.showError(t.result.toString())
}
}
override fun onError(e: Throwable) {
ToastUtils.showError("卡密绑定成功\n" + e.localizedMessage)
dialog.dismiss()
}
})
})
}
binding.tvLogout.onClick {
val file = App.getApplication().getFileStreamPath("userConfig.fy")
if (file.delete()) {
ToastUtils.showSuccess("退出成功")
setResult(Activity.RESULT_OK)
finish()
} else {
ToastUtils.showError("退出失败(Error:file.delete())")
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK){
if (requestCode == APPCONST.REQUEST_RESET_PWD){
binding.tvLogout.performClick()
}
}
}
}

@ -58,11 +58,14 @@ import xyz.fycz.myreader.ui.activity.MainActivity;
import xyz.fycz.myreader.ui.activity.MoreSettingActivity; import xyz.fycz.myreader.ui.activity.MoreSettingActivity;
import xyz.fycz.myreader.ui.activity.ReadRecordActivity; import xyz.fycz.myreader.ui.activity.ReadRecordActivity;
import xyz.fycz.myreader.ui.activity.RemoveAdActivity; import xyz.fycz.myreader.ui.activity.RemoveAdActivity;
import xyz.fycz.myreader.ui.activity.UserInfoActivity;
import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.dialog.DialogCreator;
import xyz.fycz.myreader.ui.dialog.LoadingDialog; import xyz.fycz.myreader.ui.dialog.LoadingDialog;
import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.SharedPreUtils;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.utils.AdUtils;
import xyz.fycz.myreader.util.utils.NetworkUtils; import xyz.fycz.myreader.util.utils.NetworkUtils;
import xyz.fycz.myreader.util.utils.RxUtils;
/** /**
* @author fengyue * @author fengyue
@ -141,6 +144,22 @@ public class MineFragment extends BaseFragment {
} }
binding.tvThemeModeSelect.setText(themeModeArr[themeMode]); binding.tvThemeModeSelect.setText(themeModeArr[themeMode]);
initShowMode(); initShowMode();
AdUtils.checkHasAd(true, true).compose(RxUtils::toSimpleSingle)
.subscribe(new MySingleObserver<Boolean>() {
@Override
public void onSuccess(@NonNull Boolean aBoolean) {
if (aBoolean && AdUtils.getAdConfig().getRemoveAdTime() > 0){
binding.mineRlRemoveAd.setVisibility(View.VISIBLE);
}else {
binding.mineRlRemoveAd.setVisibility(View.GONE);
}
}
@Override
public void onError(Throwable e) {
binding.mineRlRemoveAd.setVisibility(View.GONE);
}
});
} }
private void initShowMode() { private void initShowMode() {
@ -170,19 +189,8 @@ public class MineFragment extends BaseFragment {
super.initClick(); super.initClick();
binding.mineRlUser.setOnClickListener(v -> { binding.mineRlUser.setOnClickListener(v -> {
if (isLogin) { if (isLogin) {
DialogCreator.createCommonDialog(getActivity(), "退出登录", "确定要退出登录吗?" Intent intent = new Intent(getActivity(), UserInfoActivity.class);
, true, (dialog, which) -> { startActivityForResult(intent, APPCONST.REQUEST_LOGOUT);
File file = App.getApplication().getFileStreamPath("userConfig.fy");
if (file.delete()) {
ToastUtils.showSuccess("退出成功");
isLogin = false;
mHandler.sendEmptyMessage(1);
Intent intent = new Intent(getActivity(), LoginActivity.class);
getActivity().startActivityForResult(intent, APPCONST.REQUEST_LOGIN);
} else {
ToastUtils.showError("退出失败(Error:file.delete())");
}
}, (dialog, which) -> dialog.dismiss());
} else { } else {
Intent intent = new Intent(getActivity(), LoginActivity.class); Intent intent = new Intent(getActivity(), LoginActivity.class);
getActivity().startActivityForResult(intent, APPCONST.REQUEST_LOGIN); getActivity().startActivityForResult(intent, APPCONST.REQUEST_LOGIN);
@ -614,11 +622,11 @@ public class MineFragment extends BaseFragment {
@Override @Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
switch (requestCode) {
case APPCONST.REQUEST_LOGIN:
if (data == null) { if (data == null) {
return; return;
} }
switch (requestCode) {
case APPCONST.REQUEST_LOGIN:
isLogin = data.getBooleanExtra("isLogin", false); isLogin = data.getBooleanExtra("isLogin", false);
user = UserService.INSTANCE.readConfig(); user = UserService.INSTANCE.readConfig();
if (isLogin && user != null) { if (isLogin && user != null) {
@ -626,10 +634,17 @@ public class MineFragment extends BaseFragment {
} }
break; break;
case APPCONST.REQUEST_SETTING: case APPCONST.REQUEST_SETTING:
if (data == null) {
return;
}
if (data.getBooleanExtra(APPCONST.RESULT_NEED_REFRESH, false)){ if (data.getBooleanExtra(APPCONST.RESULT_NEED_REFRESH, false)){
initShowMode(); initShowMode();
} }
break; break;
case APPCONST.REQUEST_LOGOUT:
isLogin = false;
mHandler.sendEmptyMessage(1);
break;
} }
} }
} }

@ -12,6 +12,7 @@ import io.reactivex.SingleEmitter
import xyz.fycz.myreader.R import xyz.fycz.myreader.R
import xyz.fycz.myreader.base.BaseFragment import xyz.fycz.myreader.base.BaseFragment
import xyz.fycz.myreader.base.adapter2.onClick import xyz.fycz.myreader.base.adapter2.onClick
import xyz.fycz.myreader.base.adapter2.onLongClick
import xyz.fycz.myreader.base.observer.MySingleObserver import xyz.fycz.myreader.base.observer.MySingleObserver
import xyz.fycz.myreader.common.APPCONST import xyz.fycz.myreader.common.APPCONST
import xyz.fycz.myreader.databinding.FragmentSubscribeSourceBinding import xyz.fycz.myreader.databinding.FragmentSubscribeSourceBinding
@ -79,6 +80,14 @@ class SubscribeSourceFragment(private val sourceActivity: BookSourceActivity) :
//设置分割线 //设置分割线
binding.recyclerView.addItemDecoration(DividerItemDecoration(context)) binding.recyclerView.addItemDecoration(DividerItemDecoration(context))
mAdapter?.refreshItems(mBookSources) mAdapter?.refreshItems(mBookSources)
if (mBookSources.isNullOrEmpty()) {
binding.llNoDataTips.visibility = View.VISIBLE
binding.recyclerView.visibility = View.GONE
} else {
binding.llNoDataTips.visibility = View.GONE
binding.recyclerView.visibility = View.VISIBLE
}
} }
override fun initWidget(savedInstanceState: Bundle?) { override fun initWidget(savedInstanceState: Bundle?) {
@ -87,9 +96,14 @@ class SubscribeSourceFragment(private val sourceActivity: BookSourceActivity) :
override fun initClick() { override fun initClick() {
super.initClick() super.initClick()
binding.ivNoDataTips.onClick {
binding.tvSubscribeSource.performClick()
}
binding.tvSubscribeSource.onClick { binding.tvSubscribeSource.onClick {
startActivityForResult(Intent(context, SourceSubscribeActivity::class.java), startActivityForResult(
APPCONST.REQUEST_SUBSCRIBE) Intent(context, SourceSubscribeActivity::class.java),
APPCONST.REQUEST_SUBSCRIBE
)
} }
binding.ivGroup.setOnClickListener { view: View? -> binding.ivGroup.setOnClickListener { view: View? ->
showSourceGroupMenu(view) showSourceGroupMenu(view)
@ -101,7 +115,11 @@ class SubscribeSourceFragment(private val sourceActivity: BookSourceActivity) :
featuresMenu?.show() featuresMenu?.show()
} }
binding.tvSubscribeSourceTip.onClick { binding.tvSubscribeSourceTip.onClick {
MyAlertDialog.showTipDialogWithLink(context, getString(R.string.subscribe_source_tip), R.string.subscribe_source_detail_tip) MyAlertDialog.showTipDialogWithLink(
context,
getString(R.string.subscribe_source_tip),
R.string.subscribe_source_detail_tip
)
} }
} }
@ -111,7 +129,7 @@ class SubscribeSourceFragment(private val sourceActivity: BookSourceActivity) :
private fun showSourceGroupMenu(view: View?) { private fun showSourceGroupMenu(view: View?) {
val popupMenu = PopupMenu(sourceActivity, view, Gravity.END) val popupMenu = PopupMenu(sourceActivity, view, Gravity.END)
val groupList = BookSourceManager.getGroupList(true) val groupList = BookSourceManager.getGroupList(true)
popupMenu.menu.add(0, 0, 0, "所有书源") popupMenu.menu.add(0, 0, 0, R.string.all_source)
for (i in groupList.indices) { for (i in groupList.indices) {
popupMenu.menu.add(0, 0, i + 1, groupList[i]) popupMenu.menu.add(0, 0, i + 1, groupList[i])
} }

@ -30,6 +30,7 @@ import xyz.fycz.myreader.base.observer.MySingleObserver;
import xyz.fycz.myreader.common.URLCONST; import xyz.fycz.myreader.common.URLCONST;
import xyz.fycz.myreader.entity.ad.AdBean; import xyz.fycz.myreader.entity.ad.AdBean;
import xyz.fycz.myreader.entity.ad.AdConfig; import xyz.fycz.myreader.entity.ad.AdConfig;
import xyz.fycz.myreader.model.user.User;
import xyz.fycz.myreader.model.user.UserService; import xyz.fycz.myreader.model.user.UserService;
import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.SharedPreUtils;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
@ -49,7 +50,7 @@ public class AdUtils {
String config = getSp().getString("adConfig"); String config = getSp().getString("adConfig");
adConfig = GsonExtensionsKt.getGSON().fromJson(config, AdConfig.class); adConfig = GsonExtensionsKt.getGSON().fromJson(config, AdConfig.class);
if (adConfig == null || adConfig.getBackAdTime() == 0) { if (adConfig == null || adConfig.getBackAdTime() == 0) {
adConfig = new AdConfig(false, 60, 20, adConfig = new AdConfig(false, false, false, 60, 20,
60, 6, 3, 48, 60, 6, 3, 48,
true); true);
} }
@ -60,13 +61,23 @@ public class AdUtils {
} }
public static Single<Boolean> checkHasAd() { public static Single<Boolean> checkHasAd() {
if (hasRemoveAdReward()) return Single.just(false); return checkHasAd(false, true);
}
public static Single<Boolean> checkHasAd(boolean noRemove, boolean isUser) {
if (!noRemove && hasRemoveAdReward()) return Single.just(false);
initAd(); initAd();
return Single.create((SingleOnSubscribe<Boolean>) emitter -> { return Single.create((SingleOnSubscribe<Boolean>) emitter -> {
boolean hasAd = false; boolean hasAd = false;
if (!adConfig.isCloud() || isExpire()) { if (!adConfig.isCloud() || isExpire()) {
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded"); MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
String body = "type=adConfig" + UserService.INSTANCE.makeAuth(); String body = "type=adConfig" + UserService.INSTANCE.makeAuth();
if (UserService.INSTANCE.isLogin()) {
User user = UserService.INSTANCE.readConfig();
if (user != null) {
body += "&user=" + user.getUserName();
}
}
RequestBody requestBody = RequestBody.create(mediaType, body); RequestBody requestBody = RequestBody.create(mediaType, body);
String jsonStr = OkHttpUtils.getHtml(URLCONST.AD_URL, requestBody, "UTF-8"); String jsonStr = OkHttpUtils.getHtml(URLCONST.AD_URL, requestBody, "UTF-8");
try { try {
@ -81,7 +92,7 @@ public class AdUtils {
String res = jsonObject.getString("result"); String res = jsonObject.getString("result");
adConfig = GsonExtensionsKt.getGSON().fromJson(res, AdConfig.class); adConfig = GsonExtensionsKt.getGSON().fromJson(res, AdConfig.class);
adConfig.setCloud(true); adConfig.setCloud(true);
hasAd = adConfig.isHasAd(); hasAd = isUser ? adConfig.isUserHasAd() : adConfig.isHasAd();
getSp().putString("adConfig", res); getSp().putString("adConfig", res);
getSp().putLong("adConfigTime", System.currentTimeMillis()); getSp().putLong("adConfigTime", System.currentTimeMillis());
} }
@ -90,7 +101,7 @@ public class AdUtils {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
hasAd = adConfig.isHasAd(); hasAd = isUser ? adConfig.isUserHasAd() : adConfig.isHasAd();
} }
emitter.onSuccess(hasAd); emitter.onSuccess(hasAd);
}).compose(RxUtils::toSimpleSingle); }).compose(RxUtils::toSimpleSingle);
@ -167,7 +178,7 @@ public class AdUtils {
} }
public static boolean backSplashAd() { public static boolean backSplashAd() {
if (!adConfig.isHasAd()) return false; if (!adConfig.isUserHasAd()) return false;
long splashAdTime = getSp().getLong("splashAdTime"); long splashAdTime = getSp().getLong("splashAdTime");
long backTime = getSp().getLong("backTime"); long backTime = getSp().getLong("backTime");
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();

@ -42,6 +42,7 @@ import xyz.fycz.myreader.greendao.entity.rule.BookSource;
import xyz.fycz.myreader.greendao.service.CookieStore; import xyz.fycz.myreader.greendao.service.CookieStore;
import xyz.fycz.myreader.model.third2.analyzeRule.AnalyzeUrl; import xyz.fycz.myreader.model.third2.analyzeRule.AnalyzeUrl;
import xyz.fycz.myreader.model.third3.http.HttpHelperKt; import xyz.fycz.myreader.model.third3.http.HttpHelperKt;
import xyz.fycz.myreader.model.user.UserService;
import static xyz.fycz.myreader.util.help.SSLSocketClient.createSSLSocketFactory; import static xyz.fycz.myreader.util.help.SSLSocketClient.createSSLSocketFactory;
import static xyz.fycz.myreader.util.help.SSLSocketClient.createTrustAllManager; import static xyz.fycz.myreader.util.help.SSLSocketClient.createTrustAllManager;
@ -333,7 +334,7 @@ public class OkHttpUtils {
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.header("Authorization", "Client-ID " + UUID.randomUUID()) .header("Authorization", "Client-ID " + UserService.INSTANCE.getUUID())
.url(url) .url(url)
.post(requestBody) .post(requestBody)
.build(); .build();

@ -663,4 +663,55 @@ public class StringUtils {
return bytes; return bytes;
} }
/**
* 对字符串处理:将指定位置到指定位置的字符以星号代替
*
* @param content 传入的字符串
* @param begin 开始位置
* @param end 结束位置
* @return
*/
public static String getStarString(String content, int begin, int end) {
if (begin >= content.length() || begin < 0) {
return content;
}
if (end >= content.length() || end < 0) {
return content;
}
if (begin >= end) {
return content;
}
StringBuilder starStr = new StringBuilder();
for (int i = begin; i < end; i++) {
starStr.append("*");
}
return content.substring(0, begin) + starStr + content.substring(end, content.length());
}
/**
* 对字符加星号处理除前面几位和后面几位外其他的字符以星号代替
*
* @param content 传入的字符串
* @param frontNum 保留前面字符的位数
* @param endNum 保留后面字符的位数
* @return 带星号的字符串
*/
public static String getStarString2(String content, int frontNum, int endNum) {
if (frontNum >= content.length() || frontNum < 0) {
return content;
}
if (endNum >= content.length() || endNum < 0) {
return content;
}
if (frontNum + endNum >= content.length()) {
return content;
}
StringBuilder starStr = new StringBuilder();
for (int i = 0; i < (content.length() - frontNum - endNum); i++) {
starStr.append("*");
}
return content.substring(0, frontNum) + starStr
+ content.substring(content.length() - endNum, content.length());
}
} }

@ -7,6 +7,8 @@
<include layout="@layout/toolbar" /> <include layout="@layout/toolbar" />
<xyz.fycz.myreader.widget.RefreshLayout <xyz.fycz.myreader.widget.RefreshLayout
android:id="@+id/loading" android:id="@+id/loading"
android:layout_width="match_parent" android:layout_width="match_parent"

@ -0,0 +1,265 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="25dp"
android:paddingLeft="5dp"
android:paddingRight="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
android:text="@string/basic_service"
android:textColor="@color/textPrimary" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_username"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_common_bg"
android:gravity="center"
android:paddingHorizontal="20dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="@string/username"
android:textColor="@color/textPrimary"
android:textSize="@dimen/text_normal_size" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_last_web_back_time"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_common_bg"
android:gravity="center"
android:paddingHorizontal="20dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="@string/last_web_back_time"
android:textColor="@color/textPrimary"
android:textSize="@dimen/text_normal_size" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_last_web_back_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_email"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_common_bg"
android:gravity="center"
android:paddingHorizontal="20dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="@string/email"
android:textColor="@color/textPrimary"
android:textSize="@dimen/text_normal_size" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_reset_pwd"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_common_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingEnd="10dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/rest_pwd"
android:textColor="@color/textPrimary"
android:textSize="@dimen/text_normal_size" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
app:srcCompat="@drawable/ic_right_arrow"
app:tint="@color/textSecondary" />
</RelativeLayout>
<LinearLayout
android:id="@+id/ll_no_ad_service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="25dp"
android:paddingLeft="5dp"
android:paddingRight="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
android:text="@string/no_ad_service"
android:textColor="@color/textPrimary" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_no_ad_time"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_common_bg"
android:gravity="center"
android:paddingHorizontal="20dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="@string/no_ad_time"
android:textColor="@color/textPrimary"
android:textSize="@dimen/text_normal_size" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_no_ad_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_no_ad_device"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_common_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingEnd="10dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="@string/no_ad_device"
android:textColor="@color/textPrimary"
android:textSize="@dimen/text_normal_size" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_no_ad_device"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/textSecondary"
android:textSize="@dimen/text_normal_size"
android:layout_toStartOf="@+id/iv_no_ad_arrow"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_no_ad_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
app:srcCompat="@drawable/ic_right_arrow"
app:tint="@color/textSecondary" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_cammy_enter"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_common_bg"
android:gravity="center"
android:paddingStart="20dp"
android:paddingEnd="10dp">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/cammy_enter"
android:textColor="@color/textPrimary"
android:textSize="@dimen/text_normal_size" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
app:srcCompat="@drawable/ic_right_arrow"
app:tint="@color/textSecondary" />
</RelativeLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="15dp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_logout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_common_bg"
android:gravity="center"
android:text="@string/logout"
android:textColor="@color/textError"
android:textSize="@dimen/text_normal_size" />
</LinearLayout>

@ -25,7 +25,7 @@
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingStart="10dp" android:paddingStart="10dp"
android:paddingEnd="10dp" android:paddingEnd="10dp"
android:text="@string/subscribe_source" android:text="@string/add_subscribe"
android:textColor="@color/colorAccent" android:textColor="@color/colorAccent"
android:textSize="@dimen/text_small_size" /> android:textSize="@dimen/text_small_size" />
@ -72,15 +72,38 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:background="@color/colorBackground" /> android:background="@color/colorBackground" />
<LinearLayout
android:id="@+id/ll_no_data_tips"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp"
android:visibility="gone">
<ImageView
android:id="@+id/iv_no_data_tips"
android:layout_width="100dp"
android:layout_height="100dp"
app:srcCompat="@drawable/ic_vector_add_bookcase"
app:tint="@color/textSecondary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="当前无任何订阅书源,点击添加"
android:textColor="@color/textSecondary"
android:textSize="16sp" />
</LinearLayout>
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<xyz.fycz.myreader.widget.scroller.FastScrollRecyclerView <xyz.fycz.myreader.widget.scroller.FastScrollRecyclerView
android:id="@+id/recycler_view" android:id="@+id/recycler_view"
android:background="@color/colorForeground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
android:background="@color/colorForeground" />
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>

@ -104,7 +104,6 @@
<string name="update_log">更新日志</string> <string name="update_log">更新日志</string>
<string name="git_hub">GitHub</string> <string name="git_hub">GitHub</string>
<string name="share_log">分享崩溃日志</string> <string name="share_log">分享崩溃日志</string>
<string name="email">邮箱:fy@fycz.xyz</string>
<string name="this_github_url">https://github.com/fengyuecanzhu/FYReader</string> <string name="this_github_url">https://github.com/fengyuecanzhu/FYReader</string>
<string name="update">检查更新</string> <string name="update">检查更新</string>
<string name="thanks">致谢名单</string> <string name="thanks">致谢名单</string>
@ -435,6 +434,7 @@
<string name="new_source">新建书源</string> <string name="new_source">新建书源</string>
<string name="import_source">导入书源</string> <string name="import_source">导入书源</string>
<string name="subscribe_source">书源订阅</string> <string name="subscribe_source">书源订阅</string>
<string name="add_subscribe">添加订阅</string>
<string name="source_tip">书源说明</string> <string name="source_tip">书源说明</string>
<string name="subscribe_source_tip">订阅书源说明</string> <string name="subscribe_source_tip">订阅书源说明</string>
<string name="cancle_select_all">取消全选</string> <string name="cancle_select_all">取消全选</string>
@ -542,6 +542,17 @@
<string name="hide_user_cloud">隐藏用户及云服务</string> <string name="hide_user_cloud">隐藏用户及云服务</string>
<string name="subscribe_source_detail_tip">1、由于作者没时间维护内置书源导致大部分内置书源已经没法使用,故推出订阅书源 <string name="subscribe_source_detail_tip">1、由于作者没时间维护内置书源导致大部分内置书源已经没法使用,故推出订阅书源
\n\n2、订阅书源全部搜集自网络,将会每月更新一次\n\n3、订阅书源目前处于测试阶段,如出现bug,请前往QQ频道或QQ群(1085028304)进行反馈</string> \n\n2、订阅书源全部搜集自网络,将会每月更新一次\n\n3、订阅书源目前处于测试阶段,如出现bug,请前往QQ频道或QQ群(1085028304)进行反馈</string>
<string name="userinfo">个人中心</string>
<string name="username">用户名</string>
<string name="email">邮箱</string>
<string name="rest_pwd">重置密码</string>
<string name="last_web_back_time">上次同步时间</string>
<string name="no_ad_time">免广告到期时间</string>
<string name="no_ad_device">免广告设备绑定</string>
<string name="basic_service">基础服务</string>
<string name="no_ad_service">免广告服务</string>
<string name="cammy_enter">卡密输入</string>
<string name="logout">退出登录</string>
<!--error string start--> <!--error string start-->

@ -1,3 +1,3 @@
#Fri Jun 18 21:45:31 CST 2021 #Fri Jun 18 21:45:31 CST 2021
VERSION_CODE=239 VERSION_CODE=240
NEED_CREATE_RELEASE=true NEED_CREATE_RELEASE=true

Loading…
Cancel
Save