feat: 使用官方一键签到加快签到速度(实验性)
This commit is contained in:
parent
e6964a3c8b
commit
74c3deb624
|
|
@ -49,13 +49,13 @@ class AboutActivity : BaseActivity() {
|
||||||
} else {
|
} else {
|
||||||
clickCount++
|
clickCount++
|
||||||
}
|
}
|
||||||
if (clickCount > 5) {
|
if (clickCount >= 7) {
|
||||||
if (appPreferences.checkCIUpdate) {
|
if (appPreferences.showExperimentalFeatures) {
|
||||||
toastShort(R.string.toast_ci_version_disabled)
|
toastShort(R.string.toast_experimental_features_disabled)
|
||||||
appPreferences.checkCIUpdate = false
|
appPreferences.showExperimentalFeatures = false
|
||||||
} else {
|
} else {
|
||||||
toastShort(R.string.toast_ci_version_enabled)
|
toastShort(R.string.toast_experimental_features_enabled)
|
||||||
appPreferences.checkCIUpdate = true
|
appPreferences.showExperimentalFeatures = true
|
||||||
}
|
}
|
||||||
clickCount = 0
|
clickCount = 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -907,4 +907,17 @@ interface ITiebaApi {
|
||||||
fun imgPortrait(
|
fun imgPortrait(
|
||||||
file: File
|
file: File
|
||||||
): Flow<CommonResponse>
|
): Flow<CommonResponse>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取吧列表
|
||||||
|
*/
|
||||||
|
fun getForumListFlow(): Flow<GetForumListBean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一键签到(官方)
|
||||||
|
*/
|
||||||
|
fun mSign(
|
||||||
|
forumIds: String,
|
||||||
|
tbs: String
|
||||||
|
): Flow<MSignBean>
|
||||||
}
|
}
|
||||||
|
|
@ -613,4 +613,13 @@ object MixedTiebaApiImpl : ITiebaApi {
|
||||||
}.build()
|
}.build()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getForumListFlow(): Flow<GetForumListBean> =
|
||||||
|
RetrofitTiebaApi.OFFICIAL_TIEBA_API.getForumListFlow()
|
||||||
|
|
||||||
|
override fun mSign(
|
||||||
|
forumIds: String,
|
||||||
|
tbs: String
|
||||||
|
): Flow<MSignBean> =
|
||||||
|
RetrofitTiebaApi.OFFICIAL_TIEBA_API.mSignFlow(forumIds, tbs)
|
||||||
}
|
}
|
||||||
|
|
@ -178,14 +178,18 @@ interface OfficialTiebaApi {
|
||||||
@Field("in_live") inLive: Int = 0
|
@Field("in_live") inLive: Int = 0
|
||||||
): Flow<FollowBean>
|
): Flow<FollowBean>
|
||||||
|
|
||||||
@Headers("${Header.FORCE_LOGIN}: ${Header.FORCE_LOGIN_TRUE}")
|
@Headers(
|
||||||
|
"${Header.FORCE_LOGIN}: ${Header.FORCE_LOGIN_TRUE}",
|
||||||
|
"${Header.NO_COMMON_PARAMS}: BDUSS"
|
||||||
|
)
|
||||||
@POST("/c/f/forum/getforumlist")
|
@POST("/c/f/forum/getforumlist")
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
fun getForumListFlow(
|
fun getForumListFlow(
|
||||||
|
@Field("BDUSS") bduss: String = AccountUtil.getBduss(BaseApplication.INSTANCE)!!,
|
||||||
|
@Field("stoken") stoken: String = AccountUtil.getSToken(BaseApplication.INSTANCE)!!,
|
||||||
|
@Field("user_id") userId: String = AccountUtil.getUid(BaseApplication.INSTANCE)!!,
|
||||||
@Field("_client_version") client_version: String = "11.10.8.6",
|
@Field("_client_version") client_version: String = "11.10.8.6",
|
||||||
@retrofit2.http.Header(Header.USER_AGENT) user_agent: String = "bdtb for Android $client_version",
|
@retrofit2.http.Header(Header.USER_AGENT) user_agent: String = "bdtb for Android $client_version",
|
||||||
@Field("stoken") stoken: String = AccountUtil.getSToken(BaseApplication.INSTANCE)!!,
|
|
||||||
@Field("user_id") userId: String = AccountUtil.getUid(BaseApplication.INSTANCE)!!
|
|
||||||
): Flow<GetForumListBean>
|
): Flow<GetForumListBean>
|
||||||
|
|
||||||
@Headers("${Header.FORCE_LOGIN}: ${Header.FORCE_LOGIN_TRUE}")
|
@Headers("${Header.FORCE_LOGIN}: ${Header.FORCE_LOGIN_TRUE}")
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,12 @@ class PreferencesFragment : PreferencesFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun refresh() {
|
private fun refresh() {
|
||||||
|
val experimentalFeatures =
|
||||||
|
attachContext.resources.getStringArray(R.array.experimental_features)
|
||||||
|
experimentalFeatures.forEach {
|
||||||
|
findPreference<Preference>(it)?.isVisible =
|
||||||
|
attachContext.appPreferences.showExperimentalFeatures
|
||||||
|
}
|
||||||
loginInfo = AccountUtil.getLoginInfo(attachContext)
|
loginInfo = AccountUtil.getLoginInfo(attachContext)
|
||||||
val accounts = AccountUtil.allAccounts
|
val accounts = AccountUtil.allAccounts
|
||||||
val usernameList: MutableList<String> = ArrayList()
|
val usernameList: MutableList<String> = ArrayList()
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package com.huanchengfly.tieba.post.models
|
||||||
|
|
||||||
data class SignDataBean(
|
data class SignDataBean(
|
||||||
val forumName: String,
|
val forumName: String,
|
||||||
|
val forumId: String,
|
||||||
val userName: String,
|
val userName: String,
|
||||||
val tbs: String
|
val tbs: String,
|
||||||
|
val canUseMSign: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
@ -69,6 +69,29 @@ object AccountUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun fetchAccountFlow(account: Account): Flow<Account> {
|
||||||
|
return TiebaApi.getInstance()
|
||||||
|
.initNickNameFlow(
|
||||||
|
account.bduss,
|
||||||
|
account.sToken
|
||||||
|
)
|
||||||
|
.zip(
|
||||||
|
TiebaApi.getInstance().loginFlow(
|
||||||
|
account.bduss,
|
||||||
|
account.sToken
|
||||||
|
)
|
||||||
|
) { initNickNameBean, loginBean ->
|
||||||
|
account.apply {
|
||||||
|
uid = loginBean.user.id
|
||||||
|
name = loginBean.user.name
|
||||||
|
nameShow = initNickNameBean.userInfo.nameShow
|
||||||
|
portrait = loginBean.user.portrait
|
||||||
|
tbs = loginBean.anti.tbs
|
||||||
|
saveOrUpdate("uid = ?", loginBean.user.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun fetchAccountFlow(
|
fun fetchAccountFlow(
|
||||||
bduss: String,
|
bduss: String,
|
||||||
sToken: String,
|
sToken: String,
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,11 @@ open class AppPreferencesUtils(context: Context) {
|
||||||
key = "oksign_slow_mode"
|
key = "oksign_slow_mode"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var oksignUseOfficialOksign by DataStoreDelegates.boolean(
|
||||||
|
defaultValue = false,
|
||||||
|
key = "oksign_use_official_oksign"
|
||||||
|
)
|
||||||
|
|
||||||
var postOrReplyWarning by DataStoreDelegates.boolean(defaultValue = true)
|
var postOrReplyWarning by DataStoreDelegates.boolean(defaultValue = true)
|
||||||
|
|
||||||
var radius by DataStoreDelegates.int(defaultValue = 8)
|
var radius by DataStoreDelegates.int(defaultValue = 8)
|
||||||
|
|
@ -101,6 +106,8 @@ open class AppPreferencesUtils(context: Context) {
|
||||||
key = "show_both_username_and_nickname"
|
key = "show_both_username_and_nickname"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var showExperimentalFeatures by DataStoreDelegates.boolean(defaultValue = false)
|
||||||
|
|
||||||
var showShortcutInThread by DataStoreDelegates.boolean(defaultValue = true)
|
var showShortcutInThread by DataStoreDelegates.boolean(defaultValue = true)
|
||||||
|
|
||||||
var showTopForumInNormalList by DataStoreDelegates.boolean(
|
var showTopForumInNormalList by DataStoreDelegates.boolean(
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.huanchengfly.tieba.post.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.huanchengfly.tieba.post.api.TiebaApi
|
import com.huanchengfly.tieba.post.api.TiebaApi
|
||||||
|
import com.huanchengfly.tieba.post.api.models.MSignBean
|
||||||
import com.huanchengfly.tieba.post.api.models.SignResultBean
|
import com.huanchengfly.tieba.post.api.models.SignResultBean
|
||||||
import com.huanchengfly.tieba.post.api.retrofit.ApiResult
|
import com.huanchengfly.tieba.post.api.retrofit.ApiResult
|
||||||
import com.huanchengfly.tieba.post.api.retrofit.doIfFailure
|
import com.huanchengfly.tieba.post.api.retrofit.doIfFailure
|
||||||
|
|
@ -98,6 +99,7 @@ class SingleAccountSigner(
|
||||||
private var position = 0
|
private var position = 0
|
||||||
private var successCount = 0
|
private var successCount = 0
|
||||||
private var totalCount = 0
|
private var totalCount = 0
|
||||||
|
private var mSignCount = 0
|
||||||
|
|
||||||
var lastFailure: Throwable? = null
|
var lastFailure: Throwable? = null
|
||||||
|
|
||||||
|
|
@ -113,12 +115,70 @@ class SingleAccountSigner(
|
||||||
signData.clear()
|
signData.clear()
|
||||||
var userName: String by Delegates.notNull()
|
var userName: String by Delegates.notNull()
|
||||||
var tbs: String by Delegates.notNull()
|
var tbs: String by Delegates.notNull()
|
||||||
AccountUtil.fetchAccountFlow(context)
|
AccountUtil.fetchAccountFlow(account)
|
||||||
.flatMapConcat { account ->
|
.flatMapConcat { account ->
|
||||||
userName = account.name
|
userName = account.name
|
||||||
tbs = account.tbs
|
tbs = account.tbs
|
||||||
TiebaApi.getInstance().forumRecommendFlow()
|
TiebaApi.getInstance().getForumListFlow()
|
||||||
}
|
}
|
||||||
|
.flatMapConcat { getForumListBean ->
|
||||||
|
val useMSign = context.appPreferences.oksignUseOfficialOksign
|
||||||
|
val mSignLevel = getForumListBean.level.toInt()
|
||||||
|
signData.addAll(getForumListBean.forumInfo
|
||||||
|
.filter { it.isSignIn != "1" }
|
||||||
|
.map {
|
||||||
|
SignDataBean(
|
||||||
|
it.forumName,
|
||||||
|
it.forumId,
|
||||||
|
userName,
|
||||||
|
tbs,
|
||||||
|
it.userLevel.toInt() >= mSignLevel
|
||||||
|
)
|
||||||
|
})
|
||||||
|
totalCount = signData.size
|
||||||
|
mSignCount = 0
|
||||||
|
if (useMSign) {
|
||||||
|
val mSignData = signData.filter { it.canUseMSign }
|
||||||
|
TiebaApi.getInstance().mSign(mSignData.joinToString(",") { it.forumId }, tbs)
|
||||||
|
.map { it.info }
|
||||||
|
} else {
|
||||||
|
flow { emit(emptyList()) }
|
||||||
|
}
|
||||||
|
.onStart {
|
||||||
|
mProgressListener?.onStart(totalCount)
|
||||||
|
}
|
||||||
|
.catch { emit(emptyList()) }
|
||||||
|
}
|
||||||
|
.flatMapConcat { mSignInfo ->
|
||||||
|
val newSignData = if (mSignInfo.isNotEmpty()) {
|
||||||
|
val mSignInfoMap = mutableMapOf<String, MSignBean.Info>()
|
||||||
|
mSignInfo.forEach {
|
||||||
|
mSignInfoMap[it.forumId] = it
|
||||||
|
}
|
||||||
|
val signedCount = mSignInfo.filter { it.signed == "1" }.size
|
||||||
|
successCount += signedCount
|
||||||
|
signData
|
||||||
|
.filter { !it.canUseMSign || mSignInfoMap[it.forumId]?.signed != "1" }
|
||||||
|
} else {
|
||||||
|
signData.toList()
|
||||||
|
}
|
||||||
|
mSignCount = totalCount - newSignData.size
|
||||||
|
newSignData
|
||||||
|
.asFlow()
|
||||||
|
.onEach {
|
||||||
|
position = signData.indexOf(it)
|
||||||
|
mProgressListener?.onProgressStart(it, position + mSignCount, signData.size)
|
||||||
|
}
|
||||||
|
.onEmpty {
|
||||||
|
mProgressListener?.onFinish(
|
||||||
|
successCount == totalCount,
|
||||||
|
successCount,
|
||||||
|
totalCount
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.map { data -> sign(data) }
|
||||||
|
}
|
||||||
|
/*
|
||||||
.flatMapConcat { forumRecommend ->
|
.flatMapConcat { forumRecommend ->
|
||||||
signData.addAll(forumRecommend.likeForum.filter { it.isSign != "1" }
|
signData.addAll(forumRecommend.likeForum.filter { it.isSign != "1" }
|
||||||
.map { SignDataBean(it.forumName, userName, tbs) })
|
.map { SignDataBean(it.forumName, userName, tbs) })
|
||||||
|
|
@ -137,6 +197,7 @@ class SingleAccountSigner(
|
||||||
}
|
}
|
||||||
.map { data -> sign(data) }
|
.map { data -> sign(data) }
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
.catch { e -> emit(ApiResult.Failure(e)) }
|
.catch { e -> emit(ApiResult.Failure(e)) }
|
||||||
.onCompletion {
|
.onCompletion {
|
||||||
mProgressListener?.onFinish(
|
mProgressListener?.onFinish(
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,11 @@
|
||||||
<item>3</item>
|
<item>3</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="experimental_features">
|
||||||
|
<item>oksign_use_official_oksign</item>
|
||||||
|
<item>checkCIUpdate</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="image_load_type_entries">
|
<string-array name="image_load_type_entries">
|
||||||
<item>@string/title_image_load_type_smart_origin</item>
|
<item>@string/title_image_load_type_smart_origin</item>
|
||||||
<item>@string/title_image_load_type_smart_load</item>
|
<item>@string/title_image_load_type_smart_load</item>
|
||||||
|
|
|
||||||
|
|
@ -485,8 +485,8 @@
|
||||||
<string name="title_dialog_error_detail">错误详情</string>
|
<string name="title_dialog_error_detail">错误详情</string>
|
||||||
<string name="button_copy_detail">复制详情</string>
|
<string name="button_copy_detail">复制详情</string>
|
||||||
<string name="snackbar_error">出现了一点小问题(%1$d)</string>
|
<string name="snackbar_error">出现了一点小问题(%1$d)</string>
|
||||||
<string name="toast_ci_version_enabled">已启用接收自动构建版本更新(需要 App Center 账号)</string>
|
<string name="toast_experimental_features_enabled">已启用实验性特性</string>
|
||||||
<string name="toast_ci_version_disabled">已禁用接收自动构建版本更新(需要 App Center 账号)</string>
|
<string name="toast_experimental_features_disabled">已禁用实验性特性</string>
|
||||||
<string name="title_thread_post_recommend">建议使用官方途径发贴</string>
|
<string name="title_thread_post_recommend">建议使用官方途径发贴</string>
|
||||||
<string name="message_thread_post_recommend">使用本 App 发贴可能会出现发贴失败、被吞等问题,甚至导致账户永久封禁等严重后果。\n我们建议你使用官方途径进行回贴。</string>
|
<string name="message_thread_post_recommend">使用本 App 发贴可能会出现发贴失败、被吞等问题,甚至导致账户永久封禁等严重后果。\n我们建议你使用官方途径进行回贴。</string>
|
||||||
<string name="button_official_client_post">使用官方客户端发贴</string>
|
<string name="button_official_client_post">使用官方客户端发贴</string>
|
||||||
|
|
@ -557,4 +557,6 @@
|
||||||
<string name="title_dialog_block_info">该账号封禁中</string>
|
<string name="title_dialog_block_info">该账号封禁中</string>
|
||||||
<string name="button_appeal">申诉</string>
|
<string name="button_appeal">申诉</string>
|
||||||
<string name="btn_hide_tip">隐藏该提示</string>
|
<string name="btn_hide_tip">隐藏该提示</string>
|
||||||
|
<string name="title_check_ci_update">接收自动构建版本更新</string>
|
||||||
|
<string name="tip_check_ci_update">需要 App Center 账号且已加入测试,如果你没有,请不要开启此选项!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -219,8 +219,7 @@
|
||||||
android:icon="@drawable/ic_round_speed"
|
android:icon="@drawable/ic_round_speed"
|
||||||
android:key="oksign_use_official_oksign"
|
android:key="oksign_use_official_oksign"
|
||||||
android:summary="@string/summary_oksign_use_official_oksign"
|
android:summary="@string/summary_oksign_use_official_oksign"
|
||||||
android:title="@string/title_oksign_use_official_oksign"
|
android:title="@string/title_oksign_use_official_oksign" />
|
||||||
app:isPreferenceVisible="false" />
|
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
|
|
@ -253,14 +252,12 @@
|
||||||
</androidx.preference.PreferenceCategory>
|
</androidx.preference.PreferenceCategory>
|
||||||
|
|
||||||
<androidx.preference.PreferenceCategory android:title="@string/title_settings_about">
|
<androidx.preference.PreferenceCategory android:title="@string/title_settings_about">
|
||||||
<!--
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:icon="@drawable/ic_round_bug_report_blue"
|
android:icon="@drawable/ic_round_bug_report_blue"
|
||||||
android:key="check_beta_update"
|
android:key="checkCIUpdate"
|
||||||
android:summary="@string/tip_check_beta_update"
|
android:summary="@string/tip_check_ci_update"
|
||||||
android:title="@string/title_check_beta_update" />
|
android:title="@string/title_check_ci_update" />
|
||||||
-->
|
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue