mirror of
https://github.com/pppscn/SmsForwarder
synced 2025-08-02 17:07:41 +08:00
新增:发送通道
的测试内容携带通道名称
#317
This commit is contained in:
parent
47b8efc8b4
commit
3edf6cc7bc
@ -210,7 +210,8 @@ class BarkFragment : BaseFragment<FragmentSendersBarkBinding?>(), View.OnClickLi
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
BarkUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
@ -190,7 +190,8 @@ class DingtalkGroupRobotFragment : BaseFragment<FragmentSendersDingtalkGroupRobo
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
DingtalkGroupRobotUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
@ -1,302 +1,303 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.EditText
|
||||
import android.widget.RadioGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersDingtalkInnerRobotBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.DingtalkInnerRobotSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.DingtalkInnerRobotUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.net.Proxy
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "钉钉企业机器人")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class DingtalkInnerRobotFragment : BaseFragment<FragmentSendersDingtalkInnerRobotBinding?>(), View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
||||
|
||||
private val TAG: String = DingtalkInnerRobotFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersDingtalkInnerRobotBinding {
|
||||
return FragmentSendersDingtalkInnerRobotBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.dingtalk_inner_robot)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, DingtalkInnerRobotSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etAgentID.setText(settingVo.agentID)
|
||||
binding!!.etAppKey.setText(settingVo.appKey)
|
||||
binding!!.etAppSecret.setText(settingVo.appSecret)
|
||||
binding!!.etUserIds.setText(settingVo.userIds)
|
||||
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
|
||||
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
|
||||
binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId())
|
||||
binding!!.etProxyHost.setText(settingVo.proxyHost)
|
||||
binding!!.etProxyPort.setText(settingVo.proxyPort)
|
||||
binding!!.sbProxyAuthenticator.isChecked = settingVo.proxyAuthenticator == true
|
||||
binding!!.etProxyUsername.setText(settingVo.proxyUsername)
|
||||
binding!!.etProxyPassword.setText(settingVo.proxyPassword)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
binding!!.sbProxyAuthenticator.setOnCheckedChangeListener(this)
|
||||
binding!!.rgProxyType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
|
||||
if (checkedId == R.id.rb_proxyHttp || checkedId == R.id.rb_proxySocks) {
|
||||
binding!!.layoutProxyHost.visibility = View.VISIBLE
|
||||
binding!!.layoutProxyPort.visibility = View.VISIBLE
|
||||
binding!!.layoutProxyAuthenticator.visibility = if (binding!!.sbProxyAuthenticator.isChecked) View.VISIBLE else View.GONE
|
||||
} else {
|
||||
binding!!.layoutProxyHost.visibility = View.GONE
|
||||
binding!!.layoutProxyPort.visibility = View.GONE
|
||||
binding!!.layoutProxyAuthenticator.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
binding!!.rgMsgType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
|
||||
binding!!.layoutCustomTemplate.visibility = if (checkedId == R.id.rb_msg_type_markdown) View.VISIBLE else View.GONE
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
|
||||
when (buttonView.id) {
|
||||
R.id.sb_proxyAuthenticator -> {
|
||||
binding!!.layoutProxyAuthenticator.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
DingtalkInnerRobotUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): DingtalkInnerRobotSetting {
|
||||
val agentID = binding!!.etAgentID.text.toString().trim()
|
||||
val appKey = binding!!.etAppKey.text.toString().trim()
|
||||
val appSecret = binding!!.etAppSecret.text.toString().trim()
|
||||
val userIds = binding!!.etUserIds.text.toString().trim()
|
||||
if (TextUtils.isEmpty(agentID) || TextUtils.isEmpty(appKey) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(userIds)) {
|
||||
throw Exception(getString(R.string.invalid_dingtalk_inner_robot))
|
||||
}
|
||||
|
||||
val proxyType: Proxy.Type = when (binding!!.rgProxyType.checkedRadioButtonId) {
|
||||
R.id.rb_proxyHttp -> Proxy.Type.HTTP
|
||||
R.id.rb_proxySocks -> Proxy.Type.SOCKS
|
||||
else -> Proxy.Type.DIRECT
|
||||
}
|
||||
val proxyHost = binding!!.etProxyHost.text.toString().trim()
|
||||
val proxyPort = binding!!.etProxyPort.text.toString().trim()
|
||||
|
||||
if (proxyType != Proxy.Type.DIRECT && (TextUtils.isEmpty(proxyHost) || TextUtils.isEmpty(proxyPort))) {
|
||||
throw Exception(getString(R.string.invalid_host_or_port))
|
||||
}
|
||||
|
||||
val proxyAuthenticator = binding!!.sbProxyAuthenticator.isChecked
|
||||
val proxyUsername = binding!!.etProxyUsername.text.toString().trim()
|
||||
val proxyPassword = binding!!.etProxyPassword.text.toString().trim()
|
||||
if (proxyAuthenticator && TextUtils.isEmpty(proxyUsername) && TextUtils.isEmpty(proxyPassword)) {
|
||||
throw Exception(getString(R.string.invalid_username_or_password))
|
||||
}
|
||||
|
||||
val msgKey = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_markdown) "sampleMarkdown" else "sampleText"
|
||||
val titleTemplate = binding!!.etTitleTemplate.text.toString().trim()
|
||||
|
||||
return DingtalkInnerRobotSetting(agentID, appKey, appSecret, userIds, msgKey, titleTemplate, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.EditText
|
||||
import android.widget.RadioGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersDingtalkInnerRobotBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.DingtalkInnerRobotSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.DingtalkInnerRobotUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.net.Proxy
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "钉钉企业机器人")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class DingtalkInnerRobotFragment : BaseFragment<FragmentSendersDingtalkInnerRobotBinding?>(), View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
||||
|
||||
private val TAG: String = DingtalkInnerRobotFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersDingtalkInnerRobotBinding {
|
||||
return FragmentSendersDingtalkInnerRobotBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.dingtalk_inner_robot)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, DingtalkInnerRobotSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etAgentID.setText(settingVo.agentID)
|
||||
binding!!.etAppKey.setText(settingVo.appKey)
|
||||
binding!!.etAppSecret.setText(settingVo.appSecret)
|
||||
binding!!.etUserIds.setText(settingVo.userIds)
|
||||
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
|
||||
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
|
||||
binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId())
|
||||
binding!!.etProxyHost.setText(settingVo.proxyHost)
|
||||
binding!!.etProxyPort.setText(settingVo.proxyPort)
|
||||
binding!!.sbProxyAuthenticator.isChecked = settingVo.proxyAuthenticator == true
|
||||
binding!!.etProxyUsername.setText(settingVo.proxyUsername)
|
||||
binding!!.etProxyPassword.setText(settingVo.proxyPassword)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
binding!!.sbProxyAuthenticator.setOnCheckedChangeListener(this)
|
||||
binding!!.rgProxyType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
|
||||
if (checkedId == R.id.rb_proxyHttp || checkedId == R.id.rb_proxySocks) {
|
||||
binding!!.layoutProxyHost.visibility = View.VISIBLE
|
||||
binding!!.layoutProxyPort.visibility = View.VISIBLE
|
||||
binding!!.layoutProxyAuthenticator.visibility = if (binding!!.sbProxyAuthenticator.isChecked) View.VISIBLE else View.GONE
|
||||
} else {
|
||||
binding!!.layoutProxyHost.visibility = View.GONE
|
||||
binding!!.layoutProxyPort.visibility = View.GONE
|
||||
binding!!.layoutProxyAuthenticator.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
binding!!.rgMsgType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
|
||||
binding!!.layoutCustomTemplate.visibility = if (checkedId == R.id.rb_msg_type_markdown) View.VISIBLE else View.GONE
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
|
||||
when (buttonView.id) {
|
||||
R.id.sb_proxyAuthenticator -> {
|
||||
binding!!.layoutProxyAuthenticator.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
DingtalkInnerRobotUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): DingtalkInnerRobotSetting {
|
||||
val agentID = binding!!.etAgentID.text.toString().trim()
|
||||
val appKey = binding!!.etAppKey.text.toString().trim()
|
||||
val appSecret = binding!!.etAppSecret.text.toString().trim()
|
||||
val userIds = binding!!.etUserIds.text.toString().trim()
|
||||
if (TextUtils.isEmpty(agentID) || TextUtils.isEmpty(appKey) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(userIds)) {
|
||||
throw Exception(getString(R.string.invalid_dingtalk_inner_robot))
|
||||
}
|
||||
|
||||
val proxyType: Proxy.Type = when (binding!!.rgProxyType.checkedRadioButtonId) {
|
||||
R.id.rb_proxyHttp -> Proxy.Type.HTTP
|
||||
R.id.rb_proxySocks -> Proxy.Type.SOCKS
|
||||
else -> Proxy.Type.DIRECT
|
||||
}
|
||||
val proxyHost = binding!!.etProxyHost.text.toString().trim()
|
||||
val proxyPort = binding!!.etProxyPort.text.toString().trim()
|
||||
|
||||
if (proxyType != Proxy.Type.DIRECT && (TextUtils.isEmpty(proxyHost) || TextUtils.isEmpty(proxyPort))) {
|
||||
throw Exception(getString(R.string.invalid_host_or_port))
|
||||
}
|
||||
|
||||
val proxyAuthenticator = binding!!.sbProxyAuthenticator.isChecked
|
||||
val proxyUsername = binding!!.etProxyUsername.text.toString().trim()
|
||||
val proxyPassword = binding!!.etProxyPassword.text.toString().trim()
|
||||
if (proxyAuthenticator && TextUtils.isEmpty(proxyUsername) && TextUtils.isEmpty(proxyPassword)) {
|
||||
throw Exception(getString(R.string.invalid_username_or_password))
|
||||
}
|
||||
|
||||
val msgKey = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_markdown) "sampleMarkdown" else "sampleText"
|
||||
val titleTemplate = binding!!.etTitleTemplate.text.toString().trim()
|
||||
|
||||
return DingtalkInnerRobotSetting(agentID, appKey, appSecret, userIds, msgKey, titleTemplate, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -1,302 +1,303 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersEmailBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.EmailSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.EmailUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.utils.ResUtils
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Email")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = EmailFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
private var mailType: String = getString(R.string.other_mail_type) //邮箱类型
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersEmailBinding {
|
||||
return FragmentSendersEmailBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.email)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
val mailTypeArray = ResUtils.getStringArray(R.array.MailType)
|
||||
Log.d(TAG, mailTypeArray.toString())
|
||||
binding!!.spMailType.setOnItemSelectedListener { _: MaterialSpinner?, position: Int, _: Long, item: Any ->
|
||||
mailType = item.toString()
|
||||
//XToastUtils.warning(mailType)
|
||||
binding!!.layoutServiceSetting.visibility = if (position == mailTypeArray.size - 1) View.VISIBLE else View.GONE
|
||||
}
|
||||
binding!!.spMailType.setOnNothingSelectedListener {
|
||||
mailType = mailTypeArray[mailTypeArray.size - 1]
|
||||
binding!!.spMailType.selectedIndex = mailTypeArray.size - 1
|
||||
binding!!.layoutServiceSetting.visibility = View.VISIBLE
|
||||
}
|
||||
binding!!.spMailType.selectedIndex = mailTypeArray.size - 1
|
||||
binding!!.layoutServiceSetting.visibility = View.VISIBLE
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, EmailSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
if (!TextUtils.isEmpty(settingVo.mailType)) {
|
||||
mailType = settingVo.mailType.toString()
|
||||
binding!!.spMailType.setSelectedItem(mailType)
|
||||
if (mailType != getString(R.string.other_mail_type)) {
|
||||
binding!!.layoutServiceSetting.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
binding!!.etFromEmail.setText(settingVo.fromEmail)
|
||||
binding!!.etPwd.setText(settingVo.pwd)
|
||||
binding!!.etNickname.setText(settingVo.nickname)
|
||||
binding!!.etHost.setText(settingVo.host)
|
||||
binding!!.etPort.setText(settingVo.port)
|
||||
binding!!.sbSsl.isChecked = settingVo.ssl == true
|
||||
binding!!.sbStartTls.isChecked = settingVo.startTls == true
|
||||
binding!!.etToEmail.setText(settingVo.toEmail)
|
||||
binding!!.etTitleTemplate.setText(settingVo.title)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSenderToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertExtraToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertTimeToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceNameToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etNickname: EditText = binding!!.etNickname
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
EmailUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): EmailSetting {
|
||||
val fromEmail = binding!!.etFromEmail.text.toString().trim()
|
||||
val pwd = binding!!.etPwd.text.toString().trim()
|
||||
val nickname = binding!!.etNickname.text.toString().trim()
|
||||
val host = binding!!.etHost.text.toString().trim()
|
||||
val port = binding!!.etPort.text.toString().trim()
|
||||
val ssl = binding!!.sbSsl.isChecked
|
||||
val startTls = binding!!.sbStartTls.isChecked
|
||||
val toEmail = binding!!.etToEmail.text.toString().trim()
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
if (TextUtils.isEmpty(fromEmail) || TextUtils.isEmpty(pwd) || TextUtils.isEmpty(toEmail)) {
|
||||
throw Exception(getString(R.string.invalid_email))
|
||||
}
|
||||
if (mailType == getString(R.string.other_mail_type) && (TextUtils.isEmpty(host) || TextUtils.isEmpty(port))) {
|
||||
throw Exception(getString(R.string.invalid_email_server))
|
||||
}
|
||||
|
||||
return EmailSetting(mailType, fromEmail, pwd, nickname, host, port, ssl, startTls, toEmail, title)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersEmailBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.EmailSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.EmailUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.utils.ResUtils
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Email")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class EmailFragment : BaseFragment<FragmentSendersEmailBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = EmailFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
private var mailType: String = getString(R.string.other_mail_type) //邮箱类型
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersEmailBinding {
|
||||
return FragmentSendersEmailBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.email)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
val mailTypeArray = ResUtils.getStringArray(R.array.MailType)
|
||||
Log.d(TAG, mailTypeArray.toString())
|
||||
binding!!.spMailType.setOnItemSelectedListener { _: MaterialSpinner?, position: Int, _: Long, item: Any ->
|
||||
mailType = item.toString()
|
||||
//XToastUtils.warning(mailType)
|
||||
binding!!.layoutServiceSetting.visibility = if (position == mailTypeArray.size - 1) View.VISIBLE else View.GONE
|
||||
}
|
||||
binding!!.spMailType.setOnNothingSelectedListener {
|
||||
mailType = mailTypeArray[mailTypeArray.size - 1]
|
||||
binding!!.spMailType.selectedIndex = mailTypeArray.size - 1
|
||||
binding!!.layoutServiceSetting.visibility = View.VISIBLE
|
||||
}
|
||||
binding!!.spMailType.selectedIndex = mailTypeArray.size - 1
|
||||
binding!!.layoutServiceSetting.visibility = View.VISIBLE
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, EmailSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
if (!TextUtils.isEmpty(settingVo.mailType)) {
|
||||
mailType = settingVo.mailType.toString()
|
||||
binding!!.spMailType.setSelectedItem(mailType)
|
||||
if (mailType != getString(R.string.other_mail_type)) {
|
||||
binding!!.layoutServiceSetting.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
binding!!.etFromEmail.setText(settingVo.fromEmail)
|
||||
binding!!.etPwd.setText(settingVo.pwd)
|
||||
binding!!.etNickname.setText(settingVo.nickname)
|
||||
binding!!.etHost.setText(settingVo.host)
|
||||
binding!!.etPort.setText(settingVo.port)
|
||||
binding!!.sbSsl.isChecked = settingVo.ssl == true
|
||||
binding!!.sbStartTls.isChecked = settingVo.startTls == true
|
||||
binding!!.etToEmail.setText(settingVo.toEmail)
|
||||
binding!!.etTitleTemplate.setText(settingVo.title)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSenderToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertExtraToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertTimeToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceNameToNickname.setOnClickListener(this)
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etNickname: EditText = binding!!.etNickname
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name_to_nickname -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etNickname, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
EmailUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): EmailSetting {
|
||||
val fromEmail = binding!!.etFromEmail.text.toString().trim()
|
||||
val pwd = binding!!.etPwd.text.toString().trim()
|
||||
val nickname = binding!!.etNickname.text.toString().trim()
|
||||
val host = binding!!.etHost.text.toString().trim()
|
||||
val port = binding!!.etPort.text.toString().trim()
|
||||
val ssl = binding!!.sbSsl.isChecked
|
||||
val startTls = binding!!.sbStartTls.isChecked
|
||||
val toEmail = binding!!.etToEmail.text.toString().trim()
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
if (TextUtils.isEmpty(fromEmail) || TextUtils.isEmpty(pwd) || TextUtils.isEmpty(toEmail)) {
|
||||
throw Exception(getString(R.string.invalid_email))
|
||||
}
|
||||
if (mailType == getString(R.string.other_mail_type) && (TextUtils.isEmpty(host) || TextUtils.isEmpty(port))) {
|
||||
throw Exception(getString(R.string.invalid_email_server))
|
||||
}
|
||||
|
||||
return EmailSetting(mailType, fromEmail, pwd, nickname, host, port, ssl, startTls, toEmail, title)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -1,246 +1,247 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersFeishuAppBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.FeishuAppSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.FeishuAppUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "飞书企业应用")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = FeishuAppFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersFeishuAppBinding {
|
||||
return FragmentSendersFeishuAppBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.feishu_app)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, FeishuAppSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etAppId.setText(settingVo.appId)
|
||||
binding!!.etAppSecret.setText(settingVo.appSecret)
|
||||
binding!!.etUserId.setText(settingVo.receiveId)
|
||||
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
|
||||
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
FeishuAppUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): FeishuAppSetting {
|
||||
val appId = binding!!.etAppId.text.toString().trim()
|
||||
val appSecret = binding!!.etAppSecret.text.toString().trim()
|
||||
val receiveId = binding!!.etUserId.text.toString().trim()
|
||||
if (TextUtils.isEmpty(appId) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(receiveId)) {
|
||||
throw Exception(getString(R.string.invalid_feishu_app_parameter))
|
||||
}
|
||||
|
||||
val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
|
||||
return FeishuAppSetting(appId, appSecret, receiveId, msgType, title)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersFeishuAppBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.FeishuAppSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.FeishuAppUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "飞书企业应用")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class FeishuAppFragment : BaseFragment<FragmentSendersFeishuAppBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = FeishuAppFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersFeishuAppBinding {
|
||||
return FragmentSendersFeishuAppBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.feishu_app)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, FeishuAppSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etAppId.setText(settingVo.appId)
|
||||
binding!!.etAppSecret.setText(settingVo.appSecret)
|
||||
binding!!.etUserId.setText(settingVo.receiveId)
|
||||
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
|
||||
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
FeishuAppUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): FeishuAppSetting {
|
||||
val appId = binding!!.etAppId.text.toString().trim()
|
||||
val appSecret = binding!!.etAppSecret.text.toString().trim()
|
||||
val receiveId = binding!!.etUserId.text.toString().trim()
|
||||
if (TextUtils.isEmpty(appId) || TextUtils.isEmpty(appSecret) || TextUtils.isEmpty(receiveId)) {
|
||||
throw Exception(getString(R.string.invalid_feishu_app_parameter))
|
||||
}
|
||||
|
||||
val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
|
||||
return FeishuAppSetting(appId, appSecret, receiveId, msgType, title)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -1,244 +1,245 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersFeishuBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.FeishuSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.FeishuUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "飞书群机器人")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = FeishuFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersFeishuBinding {
|
||||
return FragmentSendersFeishuBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.feishu)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, FeishuSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etWebhook.setText(settingVo.webhook)
|
||||
binding!!.etSecret.setText(settingVo.secret)
|
||||
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
|
||||
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
FeishuUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): FeishuSetting {
|
||||
val webhook = binding!!.etWebhook.text.toString().trim()
|
||||
if (!CommonUtils.checkUrl(webhook, false)) {
|
||||
throw Exception(getString(R.string.invalid_webhook))
|
||||
}
|
||||
|
||||
val secret = binding!!.etSecret.text.toString().trim()
|
||||
val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
|
||||
return FeishuSetting(webhook, secret, msgType, title)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersFeishuBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.FeishuSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.FeishuUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "飞书群机器人")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class FeishuFragment : BaseFragment<FragmentSendersFeishuBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = FeishuFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersFeishuBinding {
|
||||
return FragmentSendersFeishuBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.feishu)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, FeishuSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etWebhook.setText(settingVo.webhook)
|
||||
binding!!.etSecret.setText(settingVo.secret)
|
||||
binding!!.rgMsgType.check(settingVo.getMsgTypeCheckId())
|
||||
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
FeishuUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): FeishuSetting {
|
||||
val webhook = binding!!.etWebhook.text.toString().trim()
|
||||
if (!CommonUtils.checkUrl(webhook, false)) {
|
||||
throw Exception(getString(R.string.invalid_webhook))
|
||||
}
|
||||
|
||||
val secret = binding!!.etSecret.text.toString().trim()
|
||||
val msgType = if (binding!!.rgMsgType.checkedRadioButtonId == R.id.rb_msg_type_interactive) "interactive" else "text"
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
|
||||
return FeishuSetting(webhook, secret, msgType, title)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -1,242 +1,243 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersGotifyBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.GotifySetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.GotifyUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Gotify")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class GotifyFragment : BaseFragment<FragmentSendersGotifyBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = GotifyFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersGotifyBinding {
|
||||
return FragmentSendersGotifyBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.gotify)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, GotifySetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etWebServer.setText(settingVo.webServer)
|
||||
binding!!.etTitleTemplate.setText(settingVo.title)
|
||||
binding!!.etPriority.setText(settingVo.priority)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
GotifyUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): GotifySetting {
|
||||
val webServer = binding!!.etWebServer.text.toString().trim()
|
||||
if (!CommonUtils.checkUrl(webServer, false)) {
|
||||
throw Exception(getString(R.string.invalid_webserver))
|
||||
}
|
||||
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
val priority = binding!!.etPriority.text.toString().trim()
|
||||
|
||||
return GotifySetting(webServer, title, priority)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersGotifyBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.GotifySetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.GotifyUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Gotify")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class GotifyFragment : BaseFragment<FragmentSendersGotifyBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = GotifyFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersGotifyBinding {
|
||||
return FragmentSendersGotifyBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.gotify)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, GotifySetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etWebServer.setText(settingVo.webServer)
|
||||
binding!!.etTitleTemplate.setText(settingVo.title)
|
||||
binding!!.etPriority.setText(settingVo.priority)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
GotifyUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): GotifySetting {
|
||||
val webServer = binding!!.etWebServer.text.toString().trim()
|
||||
if (!CommonUtils.checkUrl(webServer, false)) {
|
||||
throw Exception(getString(R.string.invalid_webserver))
|
||||
}
|
||||
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
val priority = binding!!.etPriority.text.toString().trim()
|
||||
|
||||
return GotifySetting(webServer, title, priority)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -1,272 +1,273 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.RadioGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersPushplusBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.PushplusSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.PushplusUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "PushPlus")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class PushplusFragment : BaseFragment<FragmentSendersPushplusBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = PushplusFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersPushplusBinding {
|
||||
return FragmentSendersPushplusBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.pushplus)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, PushplusSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
if (TextUtils.isEmpty(settingVo.website) || settingVo.website == getString(R.string.pushplus_plus)) {
|
||||
binding!!.rgWebsite.check(R.id.rb_website_plus)
|
||||
} else {
|
||||
binding!!.rgWebsite.check(R.id.rb_website_hxtrip)
|
||||
}
|
||||
binding!!.etToken.setText(settingVo.token)
|
||||
binding!!.etTopic.setText(settingVo.topic)
|
||||
binding!!.etTemplate.setText(settingVo.template)
|
||||
binding!!.etChannel.setText(settingVo.channel)
|
||||
binding!!.etWebhook.setText(settingVo.webhook)
|
||||
binding!!.etCallbackUrl.setText(settingVo.callbackUrl)
|
||||
binding!!.etValidTime.setText(settingVo.validTime)
|
||||
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
binding!!.rgWebsite.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
|
||||
if (checkedId == R.id.rb_website_hxtrip) {
|
||||
binding!!.layoutPlusOne.visibility = View.GONE
|
||||
binding!!.layoutPlusTwo.visibility = View.GONE
|
||||
} else {
|
||||
binding!!.layoutPlusOne.visibility = View.VISIBLE
|
||||
binding!!.layoutPlusTwo.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
PushplusUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): PushplusSetting {
|
||||
val website = when (binding!!.rgWebsite.checkedRadioButtonId) {
|
||||
R.id.rb_website_hxtrip -> getString(R.string.pushplus_hxtrip)
|
||||
else -> getString(R.string.pushplus_plus)
|
||||
}
|
||||
|
||||
val token = binding!!.etToken.text.toString().trim()
|
||||
if (TextUtils.isEmpty(token)) {
|
||||
throw Exception(getString(R.string.invalid_token))
|
||||
}
|
||||
|
||||
val topic = binding!!.etTopic.text.toString().trim()
|
||||
val template = binding!!.etTemplate.text.toString().trim()
|
||||
val channel = binding!!.etChannel.text.toString().trim()
|
||||
val webhook = binding!!.etWebhook.text.toString().trim()
|
||||
val callbackUrl = binding!!.etCallbackUrl.text.toString().trim()
|
||||
val validTime = binding!!.etValidTime.text.toString().trim()
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
|
||||
return PushplusSetting(website, token, topic, template, channel, webhook, callbackUrl, validTime, title)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.RadioGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersPushplusBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.PushplusSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.PushplusUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "PushPlus")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class PushplusFragment : BaseFragment<FragmentSendersPushplusBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = PushplusFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersPushplusBinding {
|
||||
return FragmentSendersPushplusBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.pushplus)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, PushplusSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
if (TextUtils.isEmpty(settingVo.website) || settingVo.website == getString(R.string.pushplus_plus)) {
|
||||
binding!!.rgWebsite.check(R.id.rb_website_plus)
|
||||
} else {
|
||||
binding!!.rgWebsite.check(R.id.rb_website_hxtrip)
|
||||
}
|
||||
binding!!.etToken.setText(settingVo.token)
|
||||
binding!!.etTopic.setText(settingVo.topic)
|
||||
binding!!.etTemplate.setText(settingVo.template)
|
||||
binding!!.etChannel.setText(settingVo.channel)
|
||||
binding!!.etWebhook.setText(settingVo.webhook)
|
||||
binding!!.etCallbackUrl.setText(settingVo.callbackUrl)
|
||||
binding!!.etValidTime.setText(settingVo.validTime)
|
||||
binding!!.etTitleTemplate.setText(settingVo.titleTemplate)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btInsertExtra.setOnClickListener(this)
|
||||
binding!!.btInsertTime.setOnClickListener(this)
|
||||
binding!!.btInsertDeviceName.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
binding!!.rgWebsite.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
|
||||
if (checkedId == R.id.rb_website_hxtrip) {
|
||||
binding!!.layoutPlusOne.visibility = View.GONE
|
||||
binding!!.layoutPlusTwo.visibility = View.GONE
|
||||
} else {
|
||||
binding!!.layoutPlusOne.visibility = View.VISIBLE
|
||||
binding!!.layoutPlusTwo.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
val etTitleTemplate: EditText = binding!!.etTitleTemplate
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_extra -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_card_slot))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_time -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_receive_time))
|
||||
return
|
||||
}
|
||||
R.id.bt_insert_device_name -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(etTitleTemplate, getString(R.string.tag_device_name))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
PushplusUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): PushplusSetting {
|
||||
val website = when (binding!!.rgWebsite.checkedRadioButtonId) {
|
||||
R.id.rb_website_hxtrip -> getString(R.string.pushplus_hxtrip)
|
||||
else -> getString(R.string.pushplus_plus)
|
||||
}
|
||||
|
||||
val token = binding!!.etToken.text.toString().trim()
|
||||
if (TextUtils.isEmpty(token)) {
|
||||
throw Exception(getString(R.string.invalid_token))
|
||||
}
|
||||
|
||||
val topic = binding!!.etTopic.text.toString().trim()
|
||||
val template = binding!!.etTemplate.text.toString().trim()
|
||||
val channel = binding!!.etChannel.text.toString().trim()
|
||||
val webhook = binding!!.etWebhook.text.toString().trim()
|
||||
val callbackUrl = binding!!.etCallbackUrl.text.toString().trim()
|
||||
val validTime = binding!!.etValidTime.text.toString().trim()
|
||||
val title = binding!!.etTitleTemplate.text.toString().trim()
|
||||
|
||||
return PushplusSetting(website, token, topic, template, channel, webhook, callbackUrl, validTime, title)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -1,231 +1,232 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersServerchanBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.ServerchanSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.ServerchanUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Server酱·Turbo")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class ServerchanFragment : BaseFragment<FragmentSendersServerchanBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = ServerchanFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersServerchanBinding {
|
||||
return FragmentSendersServerchanBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.server_chan)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, ServerchanSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etSendKey.setText(settingVo.sendKey)
|
||||
binding!!.etChannel.setText(settingVo.channel)
|
||||
binding!!.etOpenid.setText(settingVo.openid)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
ServerchanUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): ServerchanSetting {
|
||||
val sendKey = binding!!.etSendKey.text.toString().trim()
|
||||
if (TextUtils.isEmpty(sendKey)) {
|
||||
throw Exception(getString(R.string.invalid_sendkey))
|
||||
}
|
||||
val channel = binding!!.etChannel.text.toString().trim()
|
||||
if (!TextUtils.isEmpty(channel)) {
|
||||
val regex = """^\d+(\|\d+)?$""".toRegex()
|
||||
if (!regex.matches(channel)) {
|
||||
throw Exception(getString(R.string.invalid_channel))
|
||||
}
|
||||
}
|
||||
val openid = binding!!.etOpenid.text.toString().trim()
|
||||
if (!TextUtils.isEmpty(openid)) {
|
||||
val regex = """^[A-Za-z\d\-_=]+(,[A-Za-z\d\-_=]+)?$""".toRegex()
|
||||
if (!regex.matches(openid)) {
|
||||
throw Exception(getString(R.string.invalid_openid))
|
||||
}
|
||||
}
|
||||
|
||||
return ServerchanSetting(sendKey, channel, openid)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersServerchanBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.ServerchanSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.ServerchanUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Server酱·Turbo")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class ServerchanFragment : BaseFragment<FragmentSendersServerchanBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = ServerchanFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersServerchanBinding {
|
||||
return FragmentSendersServerchanBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.server_chan)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, ServerchanSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.etSendKey.setText(settingVo.sendKey)
|
||||
binding!!.etChannel.setText(settingVo.channel)
|
||||
binding!!.etOpenid.setText(settingVo.openid)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
ServerchanUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): ServerchanSetting {
|
||||
val sendKey = binding!!.etSendKey.text.toString().trim()
|
||||
if (TextUtils.isEmpty(sendKey)) {
|
||||
throw Exception(getString(R.string.invalid_sendkey))
|
||||
}
|
||||
val channel = binding!!.etChannel.text.toString().trim()
|
||||
if (!TextUtils.isEmpty(channel)) {
|
||||
val regex = """^\d+(\|\d+)?$""".toRegex()
|
||||
if (!regex.matches(channel)) {
|
||||
throw Exception(getString(R.string.invalid_channel))
|
||||
}
|
||||
}
|
||||
val openid = binding!!.etOpenid.text.toString().trim()
|
||||
if (!TextUtils.isEmpty(openid)) {
|
||||
val regex = """^[A-Za-z\d\-_=]+(,[A-Za-z\d\-_=]+)?$""".toRegex()
|
||||
if (!regex.matches(openid)) {
|
||||
throw Exception(getString(R.string.invalid_openid))
|
||||
}
|
||||
}
|
||||
|
||||
return ServerchanSetting(sendKey, channel, openid)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -1,255 +1,256 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.hjq.permissions.OnPermissionCallback
|
||||
import com.hjq.permissions.Permission
|
||||
import com.hjq.permissions.XXPermissions
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersSmsBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.SmsSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.SmsUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "短信")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class SmsFragment : BaseFragment<FragmentSendersSmsBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = SmsFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersSmsBinding {
|
||||
return FragmentSendersSmsBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.sms_menu)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//检查发短信权限
|
||||
XXPermissions.with(this)
|
||||
.permission(Permission.SEND_SMS)
|
||||
.request(object : OnPermissionCallback {
|
||||
override fun onGranted(permissions: List<String>, all: Boolean) {
|
||||
if (!all) {
|
||||
XToastUtils.error(R.string.toast_granted_part)
|
||||
HttpServerUtils.enableApiSmsSend = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDenied(permissions: List<String>, never: Boolean) {
|
||||
HttpServerUtils.enableApiSmsSend = false
|
||||
if (never) {
|
||||
XToastUtils.error(R.string.toast_denied_never)
|
||||
// 如果是被永久拒绝就跳转到应用权限系统设置页面
|
||||
XXPermissions.startPermissionActivity(requireContext(), permissions)
|
||||
} else {
|
||||
XToastUtils.error(R.string.toast_denied)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, SmsSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.rgSimSlot.check(settingVo.getSmsSimSlotCheckId())
|
||||
binding!!.etMobiles.setText(settingVo.mobiles)
|
||||
binding!!.sbOnlyNoNetwork.isChecked = settingVo.onlyNoNetwork == true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(binding!!.etMobiles, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
SmsUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): SmsSetting {
|
||||
val mobiles = binding!!.etMobiles.text.toString().trim()
|
||||
if (TextUtils.isEmpty(mobiles)) {
|
||||
throw Exception(getString(R.string.invalid_phone_num))
|
||||
}
|
||||
|
||||
val simSlot = when (binding!!.rgSimSlot.checkedRadioButtonId) {
|
||||
R.id.rb_sim_slot_1 -> 1
|
||||
R.id.rb_sim_slot_2 -> 2
|
||||
else -> 0
|
||||
}
|
||||
val onlyNoNetwork = binding!!.sbOnlyNoNetwork.isChecked
|
||||
|
||||
return SmsSetting(simSlot, mobiles, onlyNoNetwork)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.hjq.permissions.OnPermissionCallback
|
||||
import com.hjq.permissions.Permission
|
||||
import com.hjq.permissions.XXPermissions
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersSmsBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.SmsSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.SmsUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "短信")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class SmsFragment : BaseFragment<FragmentSendersSmsBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = SmsFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersSmsBinding {
|
||||
return FragmentSendersSmsBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.sms_menu)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//检查发短信权限
|
||||
XXPermissions.with(this)
|
||||
.permission(Permission.SEND_SMS)
|
||||
.request(object : OnPermissionCallback {
|
||||
override fun onGranted(permissions: List<String>, all: Boolean) {
|
||||
if (!all) {
|
||||
XToastUtils.error(R.string.toast_granted_part)
|
||||
HttpServerUtils.enableApiSmsSend = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDenied(permissions: List<String>, never: Boolean) {
|
||||
HttpServerUtils.enableApiSmsSend = false
|
||||
if (never) {
|
||||
XToastUtils.error(R.string.toast_denied_never)
|
||||
// 如果是被永久拒绝就跳转到应用权限系统设置页面
|
||||
XXPermissions.startPermissionActivity(requireContext(), permissions)
|
||||
} else {
|
||||
XToastUtils.error(R.string.toast_denied)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, SmsSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.rgSimSlot.check(settingVo.getSmsSimSlotCheckId())
|
||||
binding!!.etMobiles.setText(settingVo.mobiles)
|
||||
binding!!.sbOnlyNoNetwork.isChecked = settingVo.onlyNoNetwork == true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btInsertSender.setOnClickListener(this)
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.bt_insert_sender -> {
|
||||
CommonUtils.insertOrReplaceText2Cursor(binding!!.etMobiles, getString(R.string.tag_from))
|
||||
return
|
||||
}
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
SmsUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): SmsSetting {
|
||||
val mobiles = binding!!.etMobiles.text.toString().trim()
|
||||
if (TextUtils.isEmpty(mobiles)) {
|
||||
throw Exception(getString(R.string.invalid_phone_num))
|
||||
}
|
||||
|
||||
val simSlot = when (binding!!.rgSimSlot.checkedRadioButtonId) {
|
||||
R.id.rb_sim_slot_1 -> 1
|
||||
R.id.rb_sim_slot_2 -> 2
|
||||
else -> 0
|
||||
}
|
||||
val onlyNoNetwork = binding!!.sbOnlyNoNetwork.isChecked
|
||||
|
||||
return SmsSetting(simSlot, mobiles, onlyNoNetwork)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -157,9 +157,8 @@ class SocketFragment : BaseFragment<FragmentSendersSocketBinding?>(), View.OnCli
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo(
|
||||
"sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info)
|
||||
)
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
SocketUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
@ -1,265 +1,266 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.RadioGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersTelegramBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.TelegramSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.TelegramUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.net.Proxy
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Telegram机器人")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class TelegramFragment : BaseFragment<FragmentSendersTelegramBinding?>(), View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
||||
|
||||
private val TAG: String = TelegramFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersTelegramBinding {
|
||||
return FragmentSendersTelegramBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.telegram)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, TelegramSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.rgMethod.check(settingVo.getMethodCheckId())
|
||||
binding!!.etApiToken.setText(settingVo.apiToken)
|
||||
binding!!.etChatId.setText(settingVo.chatId)
|
||||
binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId())
|
||||
binding!!.etProxyHost.setText(settingVo.proxyHost)
|
||||
binding!!.etProxyPort.setText(settingVo.proxyPort)
|
||||
binding!!.sbProxyAuthenticator.isChecked = settingVo.proxyAuthenticator == true
|
||||
binding!!.etProxyUsername.setText(settingVo.proxyUsername)
|
||||
binding!!.etProxyPassword.setText(settingVo.proxyPassword)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
binding!!.sbProxyAuthenticator.setOnCheckedChangeListener(this)
|
||||
binding!!.rgProxyType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
|
||||
if (checkedId == R.id.rb_proxyHttp || checkedId == R.id.rb_proxySocks) {
|
||||
binding!!.layoutProxyHost.visibility = View.VISIBLE
|
||||
binding!!.layoutProxyPort.visibility = View.VISIBLE
|
||||
binding!!.layoutProxyAuthenticator.visibility = if (binding!!.sbProxyAuthenticator.isChecked) View.VISIBLE else View.GONE
|
||||
} else {
|
||||
binding!!.layoutProxyHost.visibility = View.GONE
|
||||
binding!!.layoutProxyPort.visibility = View.GONE
|
||||
binding!!.layoutProxyAuthenticator.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
|
||||
//注意:因为只有一个监听,暂不需要判断id
|
||||
binding!!.layoutProxyAuthenticator.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
TelegramUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): TelegramSetting {
|
||||
val apiToken = binding!!.etApiToken.text.toString().trim()
|
||||
val chatId = binding!!.etChatId.text.toString().trim()
|
||||
if (TextUtils.isEmpty(apiToken) || TextUtils.isEmpty(chatId)) {
|
||||
throw Exception(getString(R.string.invalid_apiToken_or_chatId))
|
||||
}
|
||||
|
||||
val proxyType: Proxy.Type = when (binding!!.rgProxyType.checkedRadioButtonId) {
|
||||
R.id.rb_proxyHttp -> Proxy.Type.HTTP
|
||||
R.id.rb_proxySocks -> Proxy.Type.SOCKS
|
||||
else -> Proxy.Type.DIRECT
|
||||
}
|
||||
val proxyHost = binding!!.etProxyHost.text.toString().trim()
|
||||
val proxyPort = binding!!.etProxyPort.text.toString().trim()
|
||||
|
||||
if (proxyType != Proxy.Type.DIRECT && (TextUtils.isEmpty(proxyHost) || TextUtils.isEmpty(proxyPort))) {
|
||||
throw Exception(getString(R.string.invalid_host_or_port))
|
||||
}
|
||||
|
||||
val proxyAuthenticator = binding!!.sbProxyAuthenticator.isChecked
|
||||
val proxyUsername = binding!!.etProxyUsername.text.toString().trim()
|
||||
val proxyPassword = binding!!.etProxyPassword.text.toString().trim()
|
||||
if (proxyAuthenticator && TextUtils.isEmpty(proxyUsername) && TextUtils.isEmpty(proxyPassword)) {
|
||||
throw Exception(getString(R.string.invalid_username_or_password))
|
||||
}
|
||||
|
||||
val method = if (binding!!.rgMethod.checkedRadioButtonId == R.id.rb_method_get) "GET" else "POST"
|
||||
|
||||
return TelegramSetting(method, apiToken, chatId, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.RadioGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersTelegramBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.TelegramSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.TelegramUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.net.Proxy
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Telegram机器人")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class TelegramFragment : BaseFragment<FragmentSendersTelegramBinding?>(), View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
||||
|
||||
private val TAG: String = TelegramFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersTelegramBinding {
|
||||
return FragmentSendersTelegramBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.telegram)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, TelegramSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.rgMethod.check(settingVo.getMethodCheckId())
|
||||
binding!!.etApiToken.setText(settingVo.apiToken)
|
||||
binding!!.etChatId.setText(settingVo.chatId)
|
||||
binding!!.rgProxyType.check(settingVo.getProxyTypeCheckId())
|
||||
binding!!.etProxyHost.setText(settingVo.proxyHost)
|
||||
binding!!.etProxyPort.setText(settingVo.proxyPort)
|
||||
binding!!.sbProxyAuthenticator.isChecked = settingVo.proxyAuthenticator == true
|
||||
binding!!.etProxyUsername.setText(settingVo.proxyUsername)
|
||||
binding!!.etProxyPassword.setText(settingVo.proxyPassword)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
binding!!.sbProxyAuthenticator.setOnCheckedChangeListener(this)
|
||||
binding!!.rgProxyType.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
|
||||
if (checkedId == R.id.rb_proxyHttp || checkedId == R.id.rb_proxySocks) {
|
||||
binding!!.layoutProxyHost.visibility = View.VISIBLE
|
||||
binding!!.layoutProxyPort.visibility = View.VISIBLE
|
||||
binding!!.layoutProxyAuthenticator.visibility = if (binding!!.sbProxyAuthenticator.isChecked) View.VISIBLE else View.GONE
|
||||
} else {
|
||||
binding!!.layoutProxyHost.visibility = View.GONE
|
||||
binding!!.layoutProxyPort.visibility = View.GONE
|
||||
binding!!.layoutProxyAuthenticator.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
|
||||
//注意:因为只有一个监听,暂不需要判断id
|
||||
binding!!.layoutProxyAuthenticator.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
TelegramUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew = Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): TelegramSetting {
|
||||
val apiToken = binding!!.etApiToken.text.toString().trim()
|
||||
val chatId = binding!!.etChatId.text.toString().trim()
|
||||
if (TextUtils.isEmpty(apiToken) || TextUtils.isEmpty(chatId)) {
|
||||
throw Exception(getString(R.string.invalid_apiToken_or_chatId))
|
||||
}
|
||||
|
||||
val proxyType: Proxy.Type = when (binding!!.rgProxyType.checkedRadioButtonId) {
|
||||
R.id.rb_proxyHttp -> Proxy.Type.HTTP
|
||||
R.id.rb_proxySocks -> Proxy.Type.SOCKS
|
||||
else -> Proxy.Type.DIRECT
|
||||
}
|
||||
val proxyHost = binding!!.etProxyHost.text.toString().trim()
|
||||
val proxyPort = binding!!.etProxyPort.text.toString().trim()
|
||||
|
||||
if (proxyType != Proxy.Type.DIRECT && (TextUtils.isEmpty(proxyHost) || TextUtils.isEmpty(proxyPort))) {
|
||||
throw Exception(getString(R.string.invalid_host_or_port))
|
||||
}
|
||||
|
||||
val proxyAuthenticator = binding!!.sbProxyAuthenticator.isChecked
|
||||
val proxyUsername = binding!!.etProxyUsername.text.toString().trim()
|
||||
val proxyPassword = binding!!.etProxyPassword.text.toString().trim()
|
||||
if (proxyAuthenticator && TextUtils.isEmpty(proxyUsername) && TextUtils.isEmpty(proxyPassword)) {
|
||||
throw Exception(getString(R.string.invalid_username_or_password))
|
||||
}
|
||||
|
||||
val method = if (binding!!.rgMethod.checkedRadioButtonId == R.id.rb_method_get) "GET" else "POST"
|
||||
|
||||
return TelegramSetting(method, apiToken, chatId, proxyType, proxyHost, proxyPort, proxyAuthenticator, proxyUsername, proxyPassword)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -147,7 +147,8 @@ class UrlSchemeFragment : BaseFragment<FragmentSendersUrlSchemeBinding?>(), View
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
UrlSchemeUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
@ -1,319 +1,314 @@
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersWebhookBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.WebhookSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.WebhookUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Webhook")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class WebhookFragment : BaseFragment<FragmentSendersWebhookBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = WebhookFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
private var headerItemMap = HashMap<Int, LinearLayout>(2)
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersWebhookBinding {
|
||||
return FragmentSendersWebhookBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.webhook)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object :
|
||||
CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, WebhookSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.rgMethod.check(settingVo.getMethodCheckId())
|
||||
binding!!.etWebServer.setText(settingVo.webServer)
|
||||
binding!!.etSecret.setText(settingVo.secret)
|
||||
binding!!.etWebParams.setText(settingVo.webParams)
|
||||
//set header
|
||||
if (settingVo.headers != null) {
|
||||
for ((key, value) in settingVo.headers) {
|
||||
addHeaderItemLinearLayout(
|
||||
headerItemMap,
|
||||
binding!!.layoutHeaders,
|
||||
key,
|
||||
value
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
binding!!.btnAddHeader.setOnClickListener {
|
||||
addHeaderItemLinearLayout(
|
||||
headerItemMap,
|
||||
binding!!.layoutHeaders,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java)
|
||||
.observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo(
|
||||
"sms",
|
||||
getString(R.string.test_phone_num),
|
||||
getString(R.string.test_sender_sms),
|
||||
Date(),
|
||||
getString(R.string.test_sim_info)
|
||||
)
|
||||
WebhookUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew =
|
||||
Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): WebhookSetting {
|
||||
val webServer = binding!!.etWebServer.text.toString().trim()
|
||||
if (!CommonUtils.checkUrl(webServer, false)) {
|
||||
throw Exception(getString(R.string.invalid_webserver))
|
||||
}
|
||||
|
||||
val method = when (binding!!.rgMethod.checkedRadioButtonId) {
|
||||
R.id.rb_method_get -> "GET"
|
||||
R.id.rb_method_put -> "PUT"
|
||||
R.id.rb_method_patch -> "PATCH"
|
||||
else -> "POST"
|
||||
}
|
||||
val secret = binding!!.etSecret.text.toString().trim()
|
||||
val webParams = binding!!.etWebParams.text.toString().trim()
|
||||
val headers = getHeadersFromHeaderItemMap(headerItemMap)
|
||||
|
||||
return WebhookSetting(method, webServer, secret, webParams, headers)
|
||||
}
|
||||
|
||||
|
||||
//header序号
|
||||
private var headerItemId = 0
|
||||
|
||||
/**
|
||||
* 动态增删header
|
||||
*
|
||||
* @param headerItemMap 管理item的map,用于删除指定header
|
||||
* @param linearLayoutWebNotifyHeaders 需要挂载item的LinearLayout
|
||||
* @param key header的key,为空则不设置
|
||||
* @param value header的value,为空则不设置
|
||||
*/
|
||||
private fun addHeaderItemLinearLayout(
|
||||
headerItemMap: MutableMap<Int, LinearLayout>,
|
||||
linearLayoutWebNotifyHeaders: LinearLayout,
|
||||
key: String?,
|
||||
value: String?
|
||||
) {
|
||||
val linearLayoutItemAddHeader =
|
||||
View.inflate(requireContext(), R.layout.item_add_header, null) as LinearLayout
|
||||
val imageViewRemoveHeader =
|
||||
linearLayoutItemAddHeader.findViewById<ImageView>(R.id.imageViewRemoveHeader)
|
||||
if (key != null && value != null) {
|
||||
val editTextHeaderKey =
|
||||
linearLayoutItemAddHeader.findViewById<EditText>(R.id.editTextHeaderKey)
|
||||
val editTextHeaderValue =
|
||||
linearLayoutItemAddHeader.findViewById<EditText>(R.id.editTextHeaderValue)
|
||||
editTextHeaderKey.setText(key)
|
||||
editTextHeaderValue.setText(value)
|
||||
}
|
||||
imageViewRemoveHeader.tag = headerItemId
|
||||
imageViewRemoveHeader.setOnClickListener { view2: View ->
|
||||
val itemId = view2.tag as Int
|
||||
linearLayoutWebNotifyHeaders.removeView(headerItemMap[itemId])
|
||||
headerItemMap.remove(itemId)
|
||||
}
|
||||
linearLayoutWebNotifyHeaders.addView(linearLayoutItemAddHeader)
|
||||
headerItemMap[headerItemId] = linearLayoutItemAddHeader
|
||||
headerItemId++
|
||||
}
|
||||
|
||||
/**
|
||||
* 从EditText控件中获取全部headers
|
||||
*
|
||||
* @param headerItemMap 管理item的map
|
||||
* @return 全部headers
|
||||
*/
|
||||
private fun getHeadersFromHeaderItemMap(headerItemMap: Map<Int, LinearLayout>): Map<String, String> {
|
||||
val headers: MutableMap<String, String> = HashMap()
|
||||
for (headerItem in headerItemMap.values) {
|
||||
val editTextHeaderKey = headerItem.findViewById<EditText>(R.id.editTextHeaderKey)
|
||||
val editTextHeaderValue = headerItem.findViewById<EditText>(R.id.editTextHeaderValue)
|
||||
val key = editTextHeaderKey.text.toString().trim()
|
||||
val value = editTextHeaderValue.text.toString().trim()
|
||||
headers[key] = value
|
||||
}
|
||||
return headers
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
package com.idormy.sms.forwarder.fragment.senders
|
||||
|
||||
import android.os.Looper
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.database.AppDatabase
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
|
||||
import com.idormy.sms.forwarder.database.viewmodel.SenderViewModel
|
||||
import com.idormy.sms.forwarder.databinding.FragmentSendersWebhookBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.setting.WebhookSetting
|
||||
import com.idormy.sms.forwarder.utils.*
|
||||
import com.idormy.sms.forwarder.utils.sender.WebhookUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
|
||||
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
@Page(name = "Webhook")
|
||||
@Suppress("PrivatePropertyName")
|
||||
class WebhookFragment : BaseFragment<FragmentSendersWebhookBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = WebhookFragment::class.java.simpleName
|
||||
var titleBar: TitleBar? = null
|
||||
private val viewModel by viewModels<SenderViewModel> { BaseViewModelFactory(context) }
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
private var headerItemMap = HashMap<Int, LinearLayout>(2)
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_ID)
|
||||
var senderId: Long = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_TYPE)
|
||||
var senderType: Int = 0
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_SENDER_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentSendersWebhookBinding {
|
||||
return FragmentSendersWebhookBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.webhook)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, SettingUtils.requestTimeout)
|
||||
mCountDownHelper!!.setOnCountDownListener(object :
|
||||
CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
}
|
||||
})
|
||||
|
||||
//新增
|
||||
if (senderId <= 0) {
|
||||
titleBar?.setSubTitle(getString(R.string.add_sender))
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
return
|
||||
}
|
||||
|
||||
//编辑
|
||||
binding!!.btnDel.setText(R.string.del)
|
||||
AppDatabase.getInstance(requireContext())
|
||||
.senderDao()
|
||||
.get(senderId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : SingleObserver<Sender> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onSuccess(sender: Sender) {
|
||||
if (isClone) {
|
||||
titleBar?.setSubTitle(getString(R.string.clone_sender) + ": " + sender.name)
|
||||
binding!!.btnDel.setText(R.string.discard)
|
||||
} else {
|
||||
titleBar?.setSubTitle(getString(R.string.edit_sender) + ": " + sender.name)
|
||||
}
|
||||
binding!!.etName.setText(sender.name)
|
||||
binding!!.sbEnable.isChecked = sender.status == 1
|
||||
val settingVo = Gson().fromJson(sender.jsonSetting, WebhookSetting::class.java)
|
||||
Log.d(TAG, settingVo.toString())
|
||||
if (settingVo != null) {
|
||||
binding!!.rgMethod.check(settingVo.getMethodCheckId())
|
||||
binding!!.etWebServer.setText(settingVo.webServer)
|
||||
binding!!.etSecret.setText(settingVo.secret)
|
||||
binding!!.etWebParams.setText(settingVo.webParams)
|
||||
//set header
|
||||
if (settingVo.headers != null) {
|
||||
for ((key, value) in settingVo.headers) {
|
||||
addHeaderItemLinearLayout(
|
||||
headerItemMap,
|
||||
binding!!.layoutHeaders,
|
||||
key,
|
||||
value
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun initListeners() {
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
binding!!.btnAddHeader.setOnClickListener {
|
||||
addHeaderItemLinearLayout(
|
||||
headerItemMap,
|
||||
binding!!.layoutHeaders,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java)
|
||||
.observe(this) { mCountDownHelper?.finish() }
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
WebhookUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (Looper.myLooper() == null) Looper.prepare()
|
||||
XToastUtils.error(e.message.toString())
|
||||
Looper.loop()
|
||||
}
|
||||
LiveEventBus.get(KEY_SENDER_TEST, String::class.java).post("finish")
|
||||
}.start()
|
||||
return
|
||||
}
|
||||
R.id.btn_del -> {
|
||||
if (senderId <= 0 || isClone) {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
MaterialDialog.Builder(requireContext())
|
||||
.title(R.string.delete_sender_title)
|
||||
.content(R.string.delete_sender_tips)
|
||||
.positiveText(R.string.lab_yes)
|
||||
.negativeText(R.string.lab_no)
|
||||
.onPositive { _: MaterialDialog?, _: DialogAction? ->
|
||||
viewModel.delete(senderId)
|
||||
XToastUtils.success(R.string.delete_sender_toast)
|
||||
popToBack()
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
R.id.btn_save -> {
|
||||
val name = binding!!.etName.text.toString().trim()
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
throw Exception(getString(R.string.invalid_name))
|
||||
}
|
||||
|
||||
val status = if (binding!!.sbEnable.isChecked) 1 else 0
|
||||
val settingVo = checkSetting()
|
||||
if (isClone) senderId = 0
|
||||
val senderNew =
|
||||
Sender(senderId, senderType, name, Gson().toJson(settingVo), status)
|
||||
Log.d(TAG, senderNew.toString())
|
||||
|
||||
viewModel.insertOrUpdate(senderNew)
|
||||
XToastUtils.success(R.string.tipSaveSuccess)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSetting(): WebhookSetting {
|
||||
val webServer = binding!!.etWebServer.text.toString().trim()
|
||||
if (!CommonUtils.checkUrl(webServer, false)) {
|
||||
throw Exception(getString(R.string.invalid_webserver))
|
||||
}
|
||||
|
||||
val method = when (binding!!.rgMethod.checkedRadioButtonId) {
|
||||
R.id.rb_method_get -> "GET"
|
||||
R.id.rb_method_put -> "PUT"
|
||||
R.id.rb_method_patch -> "PATCH"
|
||||
else -> "POST"
|
||||
}
|
||||
val secret = binding!!.etSecret.text.toString().trim()
|
||||
val webParams = binding!!.etWebParams.text.toString().trim()
|
||||
val headers = getHeadersFromHeaderItemMap(headerItemMap)
|
||||
|
||||
return WebhookSetting(method, webServer, secret, webParams, headers)
|
||||
}
|
||||
|
||||
|
||||
//header序号
|
||||
private var headerItemId = 0
|
||||
|
||||
/**
|
||||
* 动态增删header
|
||||
*
|
||||
* @param headerItemMap 管理item的map,用于删除指定header
|
||||
* @param linearLayoutWebNotifyHeaders 需要挂载item的LinearLayout
|
||||
* @param key header的key,为空则不设置
|
||||
* @param value header的value,为空则不设置
|
||||
*/
|
||||
private fun addHeaderItemLinearLayout(
|
||||
headerItemMap: MutableMap<Int, LinearLayout>,
|
||||
linearLayoutWebNotifyHeaders: LinearLayout,
|
||||
key: String?,
|
||||
value: String?
|
||||
) {
|
||||
val linearLayoutItemAddHeader =
|
||||
View.inflate(requireContext(), R.layout.item_add_header, null) as LinearLayout
|
||||
val imageViewRemoveHeader =
|
||||
linearLayoutItemAddHeader.findViewById<ImageView>(R.id.imageViewRemoveHeader)
|
||||
if (key != null && value != null) {
|
||||
val editTextHeaderKey =
|
||||
linearLayoutItemAddHeader.findViewById<EditText>(R.id.editTextHeaderKey)
|
||||
val editTextHeaderValue =
|
||||
linearLayoutItemAddHeader.findViewById<EditText>(R.id.editTextHeaderValue)
|
||||
editTextHeaderKey.setText(key)
|
||||
editTextHeaderValue.setText(value)
|
||||
}
|
||||
imageViewRemoveHeader.tag = headerItemId
|
||||
imageViewRemoveHeader.setOnClickListener { view2: View ->
|
||||
val itemId = view2.tag as Int
|
||||
linearLayoutWebNotifyHeaders.removeView(headerItemMap[itemId])
|
||||
headerItemMap.remove(itemId)
|
||||
}
|
||||
linearLayoutWebNotifyHeaders.addView(linearLayoutItemAddHeader)
|
||||
headerItemMap[headerItemId] = linearLayoutItemAddHeader
|
||||
headerItemId++
|
||||
}
|
||||
|
||||
/**
|
||||
* 从EditText控件中获取全部headers
|
||||
*
|
||||
* @param headerItemMap 管理item的map
|
||||
* @return 全部headers
|
||||
*/
|
||||
private fun getHeadersFromHeaderItemMap(headerItemMap: Map<Int, LinearLayout>): Map<String, String> {
|
||||
val headers: MutableMap<String, String> = HashMap()
|
||||
for (headerItem in headerItemMap.values) {
|
||||
val editTextHeaderKey = headerItem.findViewById<EditText>(R.id.editTextHeaderKey)
|
||||
val editTextHeaderValue = headerItem.findViewById<EditText>(R.id.editTextHeaderValue)
|
||||
val key = editTextHeaderKey.text.toString().trim()
|
||||
val value = editTextHeaderValue.text.toString().trim()
|
||||
headers[key] = value
|
||||
}
|
||||
return headers
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
}
|
@ -202,7 +202,8 @@ class WeworkAgentFragment : BaseFragment<FragmentSendersWeworkAgentBinding?>(),
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
WeworkAgentUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
@ -144,7 +144,8 @@ class WeworkRobotFragment : BaseFragment<FragmentSendersWeworkRobotBinding?>(),
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), getString(R.string.test_sender_sms), Date(), getString(R.string.test_sim_info))
|
||||
val name = binding!!.etName.text.toString().trim().takeIf { it.isNotEmpty() } ?: getString(R.string.test_sender_name)
|
||||
val msgInfo = MsgInfo("sms", getString(R.string.test_phone_num), String.format(getString(R.string.test_sender_sms), name), Date(), getString(R.string.test_sim_info))
|
||||
WeworkRobotUtils.sendMsg(settingVo, msgInfo)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
@ -565,7 +565,8 @@
|
||||
<string name="seconds">secs</string>
|
||||
<string name="seconds_n">%s sec</string>
|
||||
<string name="retry">Retry</string>
|
||||
<string name="test_sender_sms">[Test Channel] Congratulations, the sending channel test is successful, please continue to add forwarding rules!</string>
|
||||
<string name="test_sender_sms">[%s] Congratulations, the sending channel test is successful, please continue to add forwarding rules!</string>
|
||||
<string name="test_sender_name">Test Channel</string>
|
||||
<string name="test_sim_info" tools:ignore="Typos">SIM1_TestOperator_18888888888</string>
|
||||
<string name="keep_reminding">Continued</string>
|
||||
<string name="resend">Resend</string>
|
||||
|
@ -566,7 +566,8 @@
|
||||
<string name="seconds">秒</string>
|
||||
<string name="seconds_n">%s 秒</string>
|
||||
<string name="retry">重试</string>
|
||||
<string name="test_sender_sms">【测试通道】恭喜您,该发送通道测试成功,请继续添加转发规则!</string>
|
||||
<string name="test_sender_sms">【%s】恭喜您,该发送通道测试成功,请继续添加转发规则!</string>
|
||||
<string name="test_sender_name">测试通道</string>
|
||||
<string name="test_sim_info" tools:ignore="Typos">SIM1_测试运营商_18888888888</string>
|
||||
<string name="keep_reminding">持续提醒</string>
|
||||
<string name="resend">重发消息</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user