1.更换网络BaseURL

2.新增注册功能
3.新增节点选择隐藏显示功能
This commit is contained in:
level 2025-05-28 18:14:55 +08:00
parent 661c9121d1
commit 0ec07185d4
15 changed files with 489 additions and 227 deletions

View File

@ -509,7 +509,10 @@ class LoginActivity : BaseActivity(), View.OnClickListener {
if (TextUtils.isEmpty(registerHost)) {
when {
BuildConfig.is_ym -> {
getYmRegister()
// getYmRegister()
val intent = Intent(applicationContext, RegisterActivity::class.java)
startActivity(intent)
finish()
}
BuildConfig.is_tz -> {
@ -566,17 +569,14 @@ class LoginActivity : BaseActivity(), View.OnClickListener {
}
private fun getYmRegister() {
var mmkvHost = MMKV.defaultMMKV()
val mmkvHost = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_REGISTER_HOST, "")
// com.cncat.vpn.common.log.Log.d("mmkvHost==>${mmkvHost}")
loginViewMode.getRegisterHost(object : AsyncBodyCallback {
override suspend fun suc(str: String) {
// com.cncat.vpn.common.log.Log.d("str==>${str}")
if (str != mmkvHost) {
MMKV.defaultMMKV()
.encode(BZYConstants.MMKV_KEY_REGISTER_HOST, str)
}
// mmkvHost = str
registerHost = str
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str)))
}

View File

@ -69,6 +69,7 @@ import com.cncat.vpn.service.remote.IProfileManager
import com.cncat.vpn.service.remote.wrap
import com.yingmao.clash.fragment.NewAccFragment.Companion.CHECK_NODE_REQUEST_CODE
import com.yingmao.clash.net.http.entity.ExpensesRecordRsp
import com.yingmao.clash.net.http.entity.ShowNode
import com.yingmao.clash.util.AESUtil
import com.yingmao.clash.util.CommonUtils
import com.yingmao.clash.util.Utils
@ -123,7 +124,10 @@ class NewMainActivity : BaseActivity() {
private lateinit var tvExitTime:TextView
private lateinit var clTopUp:ConstraintLayout
private lateinit var clLocation:ConstraintLayout
private lateinit var clFire:ConstraintLayout
private lateinit var tvTemporaryAccount:TextView
private lateinit var bindShow:TextView
private val mPageInfo = PageInfo()
companion object {
//记录心跳失败次数
@ -260,6 +264,9 @@ class NewMainActivity : BaseActivity() {
requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
}
}
//判断节点是否可以选择
mainAtyVM.getSelectNodeInfo()
}
/*
@ -550,7 +557,7 @@ class NewMainActivity : BaseActivity() {
data.data.data.list[0].redirectLink.let {
if(activityDialog==null){
activityDialog =
ActivityViewDialog(this, data.data.data.list[0].redirectLink)
ActivityViewDialog(this, data.data.data.list[0].content)
activityDialog?.setOnDialogClickListener(object :
OnDialogClickListener {
override fun onRechargeClickListener() {
@ -592,6 +599,15 @@ class NewMainActivity : BaseActivity() {
}
}
}
}else if(httpStatus.reqType == HttpReqType.SelectNode){
(httpStatus.rsp as ShowNode).let {
if (it.code == 200) {
val countryFlag = it.data?.countryFlag
if(countryFlag == true){
clLocation.visibility=View.VISIBLE
}
}
}
}
}
@ -628,6 +644,42 @@ class NewMainActivity : BaseActivity() {
containerVP = findViewById(R.id.container)
clLocation=findViewById(R.id.clLocation)
tvTemporaryAccount=findViewById(R.id.tvTemporaryAccount)
clFire=findViewById(R.id.clFire)
bindShow=findViewById(R.id.bindShow)
val userAccount =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
if (Utils.isEmail(userAccount) || Utils.isPhoneNumber(userAccount)) {
bindShow.visibility=View.GONE
}
bindShow.setOnClickListener {
checkBindAccountDia = MaterialDialog(this).show {
this.cancelable(false)
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.bind_account_dialog_layout,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
getCustomView().findViewById<TextView>(R.id.tv_pay_finish).setOnClickListener {
//跳转到绑定邮箱界面
showBingDialogChoose()
dismiss()
}
getCustomView().findViewById<TextView>(R.id.tv_pay_cancle).setOnClickListener {
dismiss()
}
}
}
clFire.setOnClickListener {
val uri = Uri.parse(BZYConstants.PopularApplicationsUrl)
val intent = Intent(Intent.ACTION_VIEW)
intent.setData(uri)
startActivity(intent)
drawer.close()
}
clLocation.setOnClickListener {
if (checkExpire()) {
RxToast.info(resources.getString(R.string.AccountExpired))

View File

@ -1,14 +1,18 @@
package com.yingmao.clash.act
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.os.CountDownTimer
import android.text.method.HideReturnsTransformationMethod
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.*
import androidx.appcompat.widget.AppCompatImageView
import androidx.lifecycle.ViewModelProvider
import com.cncat.vpn.service.ClashManager
import com.cncat.vpn.service.remote.IClashManager
import com.cncat.vpn.service.remote.wrap
import com.google.gson.JsonObject
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
@ -16,16 +20,18 @@ import com.yingmao.clash.view.dialog.RxDialogShapeLoading
import com.tencent.mmkv.MMKV
import com.yingmao.clash.BuildConfig
import com.yingmao.clash.R
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.base.BaseActivity
import com.cncat.vpn.common.log.Log
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.GetSMSCodeRsp
import com.yingmao.clash.net.http.entity.RegisterRsp
import com.yingmao.clash.util.AESUtil
import com.yingmao.clash.util.CommonUtils
import com.yingmao.clash.util.Utils
import com.yingmao.clash.view.PasswordTransformationMethodBigDot
import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.SlidingVerification
class RegisterActivity : BaseActivity(), View.OnClickListener {
@ -35,65 +41,99 @@ class RegisterActivity : BaseActivity(), View.OnClickListener {
private lateinit var usernameErrorTv: TextView
private lateinit var passwordErrorTv: TextView
private lateinit var verificationTipTv: TextView
private lateinit var verificationSv: SlidingVerification
private lateinit var username: String
private lateinit var password: String
private lateinit var password_check: String
private lateinit var tv_sms_code:TextView
private lateinit var et_sms_code:EditText
private lateinit var rxDialogShapeLoading: RxDialogShapeLoading
private var phoneNumber: String = ""
private lateinit var registerAtyVM: RegisterAtyVM
private var countDownTimer: CountDownTimer? = null
private var registerKey = ""
private var registerIV2 = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
//点击输入框外边隐藏输入法 必须在setContentView之后调用
setupUI(findViewById<ViewGroup>(android.R.id.content).getChildAt(0))
initView()
val registerAtyVM = ViewModelProvider(this).get(RegisterAtyVM::class.java)
// httpResponse(registerAtyVM)
httpStatus(registerAtyVM)
val clashBinder = MainApplication.getApp()?.let {
ClashManager(it).wrap() as IClashManager
}
clashBinder?.let { cb ->
val signList =
AESUtil.getSingInfo(this@RegisterActivity, BuildConfig.applicationId, AESUtil.SHA256)
if (signList.isNotEmpty()) {
val si = signList[0]
val ss1 = cb.getSS1(si)
val ss2 = cb.getSS2(si)
registerKey = cb.getRegisterKey(si)
registerIV2 = cb.getRegisterKiv(si)
com.cncat.vpn.common.log.Log.d("si==>${si}, ss1==>${ss1}, ss2==>${ss2}")
MainApplication.KEY2 = ss1
MainApplication.IV2 = ss2
}
}
registerAtyVM = ViewModelProvider(this)[RegisterAtyVM::class.java]
observe(this, registerAtyVM)
// httpStatus(registerAtyVM)
}
// private fun httpResponse(registerAtyVM: RegisterAtyVM) {
// registerAtyVM.tData.observe(this){
// if(it is RegisterRsp)
// RxToast.success(it.code + ":" + it.message)
// }
// }
override fun httpLoading(httpStatus: HttpStatus.Loading) {
when(httpStatus.reqType){
HttpReqType.BaseREGISTER->{
rxDialogShapeLoading.setMessage("注册中...")
rxDialogShapeLoading.show()
}
else->{
private fun httpStatus(registerAtyVM: RegisterAtyVM) {
registerAtyVM.statusData.observe(this) {
when (it) {
is HttpStatus.Loading -> {
rxDialogShapeLoading = RxDialogShapeLoading(this)
rxDialogShapeLoading.setMessage("注册中...")
rxDialogShapeLoading.show()
}
}
}
}
is HttpStatus.Success -> {
rxDialogShapeLoading.cancel()
with(it.rsp as RegisterRsp) {
if (code == "10000") {
RxToast.success("注册成功")
MMKV.defaultMMKV()
.encode(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, username)
//MMKV.defaultMMKV().encode(BZYConstants.MMKV_KEY_REMEMBER_PASSWORD, BZYConstants.defaultPassword)
MMKV.defaultMMKV().encode(BZYConstants.MMKV_KEY_IS_REGISTER, true)
MMKV.defaultMMKV().encode(BZYConstants.MMKV_KEY_NOTE_DEFAULT_PSW, true)
override fun httpSuccess(httpStatus: HttpStatus.Success) {
when(httpStatus.reqType){
HttpReqType.GETSMSCODE->{
(httpStatus.rsp as GetSMSCodeRsp).let { rsp ->
if (rsp.code == 1000) {
RxToast.success(resources.getString(R.string.VerificationCodeSent))
countDown()
} else {
RxToast.warning(resources.getString(R.string.VerificationCodeSentFail)+ rsp.message)
}
}
}
startActivity(Intent(this@RegisterActivity, LoginActivity::class.java))
// setResult(REGISTER_TO_LOGIN_RESULT_CODE, Intent().putExtra("username", username).putExtra("password", password))
finish()
} else
RxToast.error("注册失败:(${code})${message}")
}
}
HttpReqType.BaseREGISTER->{
rxDialogShapeLoading.cancel()
with(httpStatus.rsp as RegisterRsp) {
if (code == "200") {
RxToast.success("注册成功")
MMKV.defaultMMKV()
.encode(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, username)
MMKV.defaultMMKV().encode(BZYConstants.MMKV_KEY_IS_REGISTER, true)
MMKV.defaultMMKV().encode(BZYConstants.MMKV_KEY_NOTE_DEFAULT_PSW, true)
startActivity(Intent(this@RegisterActivity, LoginActivity::class.java))
finish()
} else
RxToast.error("注册失败:(${code})${message}")
}
}
else->{
}
}
}
override fun httpFailure(httpStatus: HttpStatus.Failure) {
when(httpStatus.reqType) {
HttpReqType.GETSMSCODE -> {
rxDialogShapeLoading.cancel()
RxToast.error("注册失败:${httpStatus.msg}")
}
else->{
is HttpStatus.Failure -> {
rxDialogShapeLoading.cancel()
RxToast.error("注册失败:${it.msg}")
}
}
}
}
@ -106,61 +146,60 @@ class RegisterActivity : BaseActivity(), View.OnClickListener {
passwordEt_check.transformationMethod = PasswordTransformationMethodBigDot()
usernameErrorTv = findViewById(R.id.tv_username_error)
passwordErrorTv = findViewById(R.id.tv_password_error)
tv_sms_code=findViewById(R.id.tv_sms_code)
et_sms_code=findViewById(R.id.et_sms_code)
rxDialogShapeLoading = RxDialogShapeLoading(this)
tv_sms_code.setOnClickListener {
phoneNumber = usernameEt.text.trim().toString()
if(Utils.isEmail(phoneNumber)||Utils.isPhoneNumber(phoneNumber)){
registerAtyVM.getSMSCode(phoneNumber)
}else{
RxToast.warning(resources.getString(R.string.phoneOrEmail))
}
}
val passwordHideCb = findViewById<CheckBox>(R.id.cb_password_hide)
passwordHideCb.setOnCheckedChangeListener(IOnCheckedChangeListener())
val passwordHideCb2 = findViewById<CheckBox>(R.id.cb_password_hide_check)
passwordHideCb2.setOnCheckedChangeListener(IOnCheckedChangeListener())
verificationSv = findViewById(R.id.sv_verification)
verificationSv.setOnSeekBarChangeListener(IOnSeekBarChangeListener())
//
verificationTipTv = findViewById(R.id.tv_verification_tip)
val registerTv = findViewById<TextView>(R.id.tv_register)
registerTv.setOnClickListener(this)
val loginTv = findViewById<TextView>(R.id.tv_login)
loginTv.setOnClickListener(this)
}
// fun register() {
// val registerAtyVM = ViewModelProvider(this).get(RegisterAtyVM::class.java)
// val params: Map<String, String> = mutableMapOf(
// "phoneNumber" to username,
// "password" to password,
// "checkPassword" to password,
// "id" to BuildConfig.productId,
//// "clientIp" to "",
// "registerAddress" to "devTest",
//// "from" to ""
// )
//
// registerAtyVM.register(params)
// }
fun doRegisterByEncryption() {
val registerAtyVM = ViewModelProvider(this).get(RegisterAtyVM::class.java)
var req_json = JsonObject()
req_json.addProperty("androidDevice", username)
req_json.addProperty("password", password)
req_json.addProperty("checkPassword", password)
req_json.addProperty("invitationCode", BuildConfig.productId)
req_json.addProperty("clientIp", "127.0.0.1")
req_json.addProperty("from", "5")
var data = AESUtil.byteArrayToHexStr(
AESUtil.encrypt(req_json.toString())
)
val params: Map<String, String> = mutableMapOf(
"data" to data
)
registerAtyVM.registerByEncryption(params)
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.tv_register -> {
if (checkInput()) doRegisterByEncryption()
val smsCode =et_sms_code.text.trim().toString()
if(smsCode.isEmpty()){
RxToast.error("验证码不能为空")
return
}
if (checkInput()){
val reqJson = JsonObject()
reqJson.addProperty("phoneNumber", username)
reqJson.addProperty("password", password)
reqJson.addProperty("password_check", password_check)
reqJson.addProperty("invitationCode", BuildConfig.productId)
reqJson.addProperty("from", "5")
reqJson.addProperty("androidDevice", Utils.getUniqueID(this))
reqJson.addProperty("smsCode", smsCode)
android.util.Log.i("VVVVVVVVVVVVV","registerKey::"+registerKey+"registerIV2::"+registerIV2)
if (registerKey.isNotEmpty() && registerIV2.isNotEmpty()) {
val data = AESUtil.byteArrayToHexStr(
AESUtil.RegisterEncrypt(reqJson.toString(), registerKey, registerIV2)
)
val params: Map<String, String> = mutableMapOf(
"data" to data
)
registerAtyVM.registerBySMSCode(params)
}
}
}
R.id.tv_login -> {
@ -171,36 +210,6 @@ class RegisterActivity : BaseActivity(), View.OnClickListener {
}
}
inner class IOnSeekBarChangeListener : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
@SuppressLint("ResourceAsColor")
override fun onStopTrackingTouch(seekBar: SeekBar?) {
seekBar?.let {
Log.d("it.progress==>${it.progress}")
if (it.progress >= it.max) {
it.isEnabled = false
verificationSv.progress = it.max
verificationTipTv.text = getString(R.string.verification_success)
verificationTipTv.setTextColor(R.color.black)
verificationSv.setProgressDrawableTiled(getDrawable(R.drawable.login_btn_bg_selector))
if (!checkInput()) {
} else {
}
} else it.progress = 0
}
}
}
private fun checkInput(): Boolean {
username = usernameEt.text.toString().trim()
if (username.isBlank()) {
@ -241,10 +250,6 @@ class RegisterActivity : BaseActivity(), View.OnClickListener {
passwordErrorTv.visibility = View.INVISIBLE
passwordErrorTv.text = ""
// if (verificationSv.progress != verificationSv.max) {
// RxToast.warning("请先滑动滑块验证")
// return false
// }
return true
}
@ -281,4 +286,23 @@ class RegisterActivity : BaseActivity(), View.OnClickListener {
override fun onBackPressed() {
super.onBackPressed()
}
private fun countDown() {
tv_sms_code.isEnabled = false
countDownTimer = object : CountDownTimer(60000, 1000) {
//1000ms运行一次onTick里面的方法
override fun onFinish() {
tv_sms_code.isEnabled = true
tv_sms_code.text = resources.getString(R.string.ObtainVerificationCode)
}
override fun onTick(millisUntilFinished: Long) {
tv_sms_code.text = "${millisUntilFinished / 1000} S"
}
}.start()
}
override fun onDestroy() {
super.onDestroy()
countDownTimer?.cancel()
}
}

View File

@ -1,18 +1,22 @@
package com.yingmao.clash.act
import android.util.Log
import androidx.lifecycle.ViewModelProvider
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.yingmao.clash.BuildConfig
import com.yingmao.clash.base.PublicViewMode
import com.yingmao.clash.net.http.HttpApi
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.NetService
import com.yingmao.clash.util.AESUtil
import com.yingmao.clash.util.Utils
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
class RegisterAtyVM : PublicViewMode() {
// fun register(params : Map<String,String>){
// val httpApi = NetService.instances.createHttps(HttpApi::class.java)
// doAsync(HttpReqType.REGISTER) { httpApi.register(params) }
// }
fun registerByEncryption(params: Map<String, String>) {
Log.e("data", "register ....")
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
@ -21,4 +25,21 @@ class RegisterAtyVM : PublicViewMode() {
httpApi.registerByEncryption(params)
}
}
fun registerBySMSCode(params: Map<String, String>) {
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
val gson = Gson()
val jsonString = gson.toJson(params)
val requestBody: RequestBody = jsonString.toRequestBody("application/json; charset=utf-8".toMediaType())
doAsync(HttpReqType.BaseREGISTER) {
httpApi.registerBySMSCode(requestBody)
}
}
fun getSMSCode(phone: String) {
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
val params = mutableMapOf(
"phoneNumber" to phone,
)
doAsync(HttpReqType.GETSMSCODE) { httpApi.appDataSMSCode(params) }
}
}

View File

@ -28,6 +28,7 @@ import com.yingmao.clash.net.http.entity.AppVersionCheckRsp
import com.yingmao.clash.net.http.entity.GetActivityRsp
import com.yingmao.clash.net.http.entity.LoginRsp2
import com.yingmao.clash.net.http.entity.SendSmsRsp
import com.yingmao.clash.net.http.entity.ShowNode
import com.yingmao.clash.net.http.entity.StartingBeans
import com.yingmao.clash.net.http.entity.UploadParamData
import com.yingmao.clash.net.http.entity.VipSignRsp
@ -82,6 +83,11 @@ interface HttpApi {
@POST("/netbarcloud/vpn/appRegister.do")
suspend fun registerByEncryption(@QueryMap params: Map<String, String>): RegisterRsp
@Headers(
"User-Agent: Octopus_Android"
)
@POST("/netbarcloud/vpn/appRegister3")
suspend fun registerBySMSCode(@Body requestBody: RequestBody): RegisterRsp
//新注册接口
@Headers(
@ -631,4 +637,15 @@ interface HttpApi {
BZYConstants.MMKV_KEY_TOKEN
).toString(),
): AppStopStatus
@Headers(
"User-Agent: Octopus_Android"
)
@GET("/netbarcloud/open/countryFlag")
suspend fun selectNodeInfo(
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString(),
): ShowNode
}

View File

@ -54,5 +54,7 @@ enum class HttpReqType(type: Int) {
AppStopStatus(50),
SplashBg(51),
GETAPPVERION(52),
StripeWeChat(53)
StripeWeChat(53),
SelectNode(54),
BaseREGISTER(54)
}

View File

@ -93,10 +93,10 @@ class NetService private constructor() : INetService {
// .sslSocketFactory(getSSLSocketFactory(), CustomTrustManager())//信任所有证书
.sslSocketFactory(getSSLSocketFactory(), trustAllCerts[0] as X509TrustManager)
.hostnameVerifier(getHostnameVerifier()!!)
if (BuildConfig.DEBUG) {
builder.addInterceptor(loggingInterceptor)
}
// builder.addInterceptor(loggingInterceptor)
// if (BuildConfig.DEBUG) {
// builder.addInterceptor(loggingInterceptor)
// }
builder.addInterceptor(loggingInterceptor)
return builder.build()
}

View File

@ -236,3 +236,18 @@ data class AppStopStatus(
@field:SerializedName("message")
val message: String? = null
) : BaseRsp
data class ShowNode(
@field:SerializedName("code")
val code: Int? = null,
@field:SerializedName("data")
val data: ShowNodeInfo? = null,
@field:SerializedName("message")
val message: String? = null
) : BaseRsp
data class ShowNodeInfo(
@field:SerializedName("countryFlag")
val countryFlag: Boolean
)

View File

@ -357,4 +357,8 @@ class MainAtyVM : PublicViewMode() {
)
doAsync(HttpReqType.EXPENSES_RECORD){httpApi.phOrderList(params)}
}
fun getSelectNodeInfo() {
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
doAsync(HttpReqType.SelectNode) { httpApi.selectNodeInfo() }
}
}

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="16"
android:viewportHeight="16">
<group>
<clip-path
android:pathData="M0,0h16v16h-16z"/>
<path
android:pathData="M4.052,9.052C3.471,8.471 3.471,7.529 4.052,6.948L10.713,0.287C11.101,-0.101 11.729,-0.101 12.116,0.287C12.503,0.674 12.503,1.302 12.116,1.689L5.805,8L12.116,14.311C12.503,14.698 12.503,15.326 12.116,15.713C11.729,16.101 11.101,16.101 10.713,15.713L4.052,9.052Z"
android:fillColor="#4F4F4F"
android:fillType="evenOdd"/>
</group>
</vector>

View File

@ -0,0 +1,19 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- This is the main color -->
<item>
<shape>
<!-- 边框颜色 -->
<solid android:color="#3228df"/>
<corners android:radius="11dp"/>
</shape>
</item>
<!-- 给View的上 左 右设置8dp的边框 -->
<item android:top="0dp" android:left="0dp" android:right="3dp" android:bottom="3dp" >
<shape>
<!-- View填充颜色 -->
<solid android:color="#FFFFFF" />
<corners android:radius="11dp"/>
</shape>
</item>
</layer-list>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="@color/white_30"/>
<item android:color="@color/white"/>
<item android:color="#4072FE"/>
</selector>

View File

@ -4,29 +4,17 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_signin"
tools:context=".act.LoginActivity">
<ImageView
android:id="@+id/iv_icon"
android:layout_width="@dimen/layout_register_icon_width"
android:layout_height="@dimen/layout_register_icon_height"
android:layout_marginStart="@dimen/layout_register_icon_start_margin"
android:layout_marginTop="@dimen/layout_register_icon_top_margin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_welcome_back"
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/aiWel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_register_welcome_text_top_margin"
android:text="@string/WelcomeRegister"
android:textColor="@color/white"
android:textSize="@dimen/layout_register_welcome_textsize"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@+id/iv_icon"
app:layout_constraintTop_toBottomOf="@+id/iv_icon" />
android:src="@mipmap/mashanglian"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="20dp"
/>
<TextView
android:id="@+id/tv_username"
@ -34,10 +22,12 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_register_username_title_text_top_margin"
android:text="@string/username"
android:textColor="@color/white"
android:textSize="@dimen/layout_register_username_title_textsize"
app:layout_constraintStart_toStartOf="@+id/iv_icon"
app:layout_constraintTop_toBottomOf="@+id/tv_welcome_back" />
android:textColor="@color/black_4F4F4F"
android:textSize="@dimen/layout_login_username_title_textsize"
android:textStyle="bold"
android:layout_marginStart="35dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/aiWel" />
<EditText
android:id="@+id/et_username"
@ -47,13 +37,17 @@
android:layout_marginTop="@dimen/layout_register_et_top_margin"
android:layout_marginEnd="@dimen/layout_register_et_end_margin"
android:background="@drawable/login_et_bg_selector"
android:hint="@string/phone_and_email"
android:inputType="textPersonName"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="@dimen/layout_register_et_textsize"
android:textColor="@color/black_4F4F4F"
android:textColorHint="@color/gray_BDBDBD"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/iv_icon"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_username" />
<TextView
@ -62,20 +56,76 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_register_username_input_err_tip_text_top_margin"
android:textColor="@color/warring"
android:layout_marginStart="35dp"
android:textSize="@dimen/layout_register_username_input_err_tip_textsize"
app:layout_constraintStart_toStartOf="@+id/iv_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_username" />
<TextView
android:id="@+id/smsCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_login_pwd_title_text_top_margin"
android:text="@string/sms_code"
android:textColor="#4F4F4F"
android:textSize="@dimen/layout_login_username_title_textsize"
app:layout_constraintStart_toStartOf="@+id/tv_username"
app:layout_constraintTop_toBottomOf="@+id/tv_username_error"
/>
<LinearLayout
android:id="@+id/llSmsCode"
android:layout_marginStart="@dimen/layout_login_et_start_margin"
android:layout_marginTop="@dimen/layout_login_et_top_margin"
android:layout_marginEnd="@dimen/layout_login_et_end_margin"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/smsCode"
>
<EditText
android:maxLength="6"
android:id="@+id/et_sms_code"
android:layout_width="0dp"
android:layout_weight="0.6"
android:layout_height="wrap_content"
android:background="@drawable/login_et_bg_selector"
android:maxLines="1"
android:inputType="number"
android:textColor="#4F4F4F"
android:textSize="16sp"
android:textStyle="bold"
android:hint="@string/correctCode"
android:textColorHint="#BDBDBD"
/>
<TextView
android:layout_marginLeft="20dp"
android:id="@+id/tv_sms_code"
android:layout_width="0dp"
android:layout_weight="0.4"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="@dimen/dp_10"
android:text="@string/SendVerificationCode"
android:textColor="@color/black"
android:textSize="@dimen/layout_login_tv_login_textsize"
android:textStyle="bold"
/>
</LinearLayout>
<TextView
android:id="@+id/tv_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_register_pwd_title_text_top_margin"
android:text="@string/password"
android:textColor="@color/white"
android:textSize="@dimen/layout_register_pwd_title_textsize"
app:layout_constraintStart_toStartOf="@+id/iv_icon"
app:layout_constraintTop_toBottomOf="@+id/tv_username_error" />
android:textColor="@color/black_4F4F4F"
android:textSize="@dimen/layout_login_username_title_textsize"
app:layout_constraintStart_toStartOf="@+id/tv_username"
app:layout_constraintTop_toBottomOf="@+id/llSmsCode" />
<EditText
android:id="@+id/et_password"
@ -87,11 +137,11 @@
android:background="@drawable/login_et_bg_selector"
android:inputType="textPassword"
android:maxLines="1"
android:textColor="@color/white"
android:textColor="#4F4F4F"
android:textSize="@dimen/layout_register_et_textsize"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/iv_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_password" />
<CheckBox
android:id="@+id/cb_password_hide"
@ -105,15 +155,16 @@
app:layout_constraintBottom_toBottomOf="@+id/et_password"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/et_password" />
<TextView
android:id="@+id/tv_password_check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_register_pwd_title_text_top_margin"
android:text="@string/password_check"
android:textColor="@color/white"
android:textSize="@dimen/layout_register_pwd_title_textsize"
app:layout_constraintStart_toStartOf="@+id/iv_icon"
android:textColor="@color/black_4F4F4F"
android:textSize="@dimen/layout_login_username_title_textsize"
app:layout_constraintStart_toStartOf="@+id/tv_password"
app:layout_constraintTop_toBottomOf="@+id/et_password" />
<EditText
android:id="@+id/et_password_check"
@ -125,11 +176,11 @@
android:background="@drawable/login_et_bg_selector"
android:inputType="textPassword"
android:maxLines="1"
android:textColor="@color/white"
android:textColor="#4F4F4F"
android:textSize="@dimen/layout_register_et_textsize"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/iv_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_password_check" />
<CheckBox
@ -149,49 +200,17 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_register_username_input_err_tip_text_top_margin"
android:layout_marginStart="35dp"
android:textColor="@color/warring"
android:textSize="@dimen/layout_register_username_input_err_tip_textsize"
app:layout_constraintStart_toStartOf="@+id/iv_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_password_check" />
<com.yingmao.clash.view.SlidingVerification
android:id="@+id/sv_verification"
android:layout_width="match_parent"
android:layout_height="48dp"
android:progressDrawable="@drawable/verification_view_bg"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:maxHeight="48dp"
android:background="@null"
android:thumb="@drawable/slide"
android:thumbOffset="-4dp"
android:splitTrack="false"
android:progress="0"
android:max="100"
android:layout_marginStart="@dimen/layout_register_tv_login_start_margin"
android:layout_marginEnd="@dimen/layout_register_tv_login_end_margin"
app:layout_constraintBottom_toTopOf="@+id/tv_register"
app:layout_constraintTop_toBottomOf="@+id/et_password" />
<TextView
android:id="@+id/tv_verification_tip"
android:layout_width="match_parent"
android:layout_height="48dp"
android:text="@string/slide_verification"
android:gravity="center"
android:textSize="16sp"
android:textColor="@color/white"
android:textStyle="bold"
android:layout_marginStart="@dimen/layout_register_tv_login_start_margin"
android:layout_marginEnd="@dimen/layout_register_tv_login_end_margin"
app:layout_constraintBottom_toTopOf="@+id/tv_register"
app:layout_constraintTop_toBottomOf="@+id/et_password" />-->
<TextView
android:id="@+id/tv_register"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="10dp"
android:layout_marginStart="@dimen/layout_register_tv_login_start_margin"
android:layout_marginEnd="@dimen/layout_register_tv_login_end_margin"
android:layout_marginBottom="@dimen/layout_register_tv_login_bottom_margin"
@ -201,31 +220,35 @@
android:textColor="@color/black"
android:textSize="@dimen/layout_register_tv_login_textsize"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="26dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="@id/llBt"
app:layout_constraintTop_toBottomOf="@+id/et_password_check" />
<LinearLayout
android:id="@+id/llBt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="10dp"
app:layout_constraintTop_toBottomOf="@+id/tv_register">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="已有账号,直接"
android:textColor="#8A99D6"
android:textSize="16sp" />
android:textColor="#000"
android:textSize="16sp"
/>
<TextView
android:id="@+id/tv_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/login"
android:padding="5dp"
android:textColor="@drawable/registerlayout_login_text_color_selector"
android:textSize="16sp" />
</LinearLayout>

View File

@ -59,6 +59,23 @@
app:layout_constraintStart_toEndOf="@+id/iv_slider"
app:layout_constraintTop_toTopOf="@+id/iv_slider" />
<TextView
android:id="@+id/bindShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/binding"
android:layout_marginEnd="20dp"
android:textColor="@color/black"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingStart="15dp"
android:paddingEnd="15dp"
android:textStyle="bold"
android:background="@drawable/oc_main_binding_bg"
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="@+id/iv_slider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/iv_slider" />
<LinearLayout
android:id="@+id/ll_activity"
android:layout_width="wrap_content"
@ -214,7 +231,7 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="20dp"
android:layout_marginTop="40dp"
android:layout_marginTop="48dp"
/>
<LinearLayout
@ -282,6 +299,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
@ -351,6 +369,40 @@
app:layout_constraintStart_toEndOf="@+id/IvSing"
app:layout_constraintTop_toTopOf="@+id/IvSing" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clFire"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/clSing">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/IvFire"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/setting_fire_line"/>
<TextView
android:id="@+id/tvFire"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="@string/PopularApplications"
android:textColor="@color/black_242426"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/IvFire"
app:layout_constraintStart_toEndOf="@+id/IvFire"
app:layout_constraintTop_toTopOf="@+id/IvFire" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clMessage"
android:layout_width="match_parent"
@ -359,7 +411,7 @@
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/clSing">
app:layout_constraintTop_toBottomOf="@+id/clFire">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/IvRechargeIc"

View File

@ -109,7 +109,7 @@ subprojects {
buildConfigField("boolean", "is_tz", "false")
buildConfigField("boolean", "is_yunti", "false")
buildConfigField("String", "applicationId", "\"com.jsq.mashanglian\"")
buildConfigField("String", "service_url", "\"https://api.ymvpnpro.cc:8700\"")
buildConfigField("String", "service_url", "\"https://api.wfvpnpro.com/\"")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "productId", "\"9972\"")
manifestPlaceholders(
@ -119,7 +119,7 @@ subprojects {
)
)
}
create("6961") {
create("2213") {
isDefault = true
dimension = flavorDimensionList[0]
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")")
@ -128,9 +128,28 @@ subprojects {
buildConfigField("boolean", "is_tz", "false")
buildConfigField("boolean", "is_yunti", "false")
buildConfigField("String", "applicationId", "\"com.jsq.mashanglian\"")
buildConfigField("String", "service_url", "\"https://api.ymvpnpro.cc:8700\"")
buildConfigField("String", "service_url", "\"https://api.wfvpnpro.com/\"")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "productId", "\"6961\"")
buildConfigField("String", "productId", "\"2213\"")
manifestPlaceholders(
mapOf(
"APP_NAME" to "@string/ConnectImmediately",
"APP_ICON" to "@mipmap/logo_connect_immediately"
)
)
}
create("8088") {
isDefault = true
dimension = flavorDimensionList[0]
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")")
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "true")
buildConfigField("boolean", "is_tz", "false")
buildConfigField("boolean", "is_yunti", "false")
buildConfigField("String", "applicationId", "\"com.jsq.mashanglian\"")
buildConfigField("String", "service_url", "\"https://api.wfvpnpro.com/\"")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "productId", "\"8088\"")
manifestPlaceholders(
mapOf(
"APP_NAME" to "@string/ConnectImmediately",