From 3edf6cc7bc51850140bd9c32c3e1daa0cc3a5203 Mon Sep 17 00:00:00 2001 From: pppscn <35696959@qq.com> Date: Tue, 11 Jul 2023 09:51:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A`=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=80=9A=E9=81=93`=E7=9A=84=E6=B5=8B=E8=AF=95=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E6=90=BA=E5=B8=A6`=E9=80=9A=E9=81=93=E5=90=8D?= =?UTF-8?q?=E7=A7=B0`=20#317?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fragment/senders/BarkFragment.kt | 3 +- .../senders/DingtalkGroupRobotFragment.kt | 3 +- .../senders/DingtalkInnerRobotFragment.kt | 603 ++++++++--------- .../fragment/senders/EmailFragment.kt | 603 ++++++++--------- .../fragment/senders/FeishuAppFragment.kt | 491 +++++++------- .../fragment/senders/FeishuFragment.kt | 487 +++++++------- .../fragment/senders/GotifyFragment.kt | 483 +++++++------- .../fragment/senders/PushplusFragment.kt | 543 +++++++-------- .../fragment/senders/ServerchanFragment.kt | 461 ++++++------- .../forwarder/fragment/senders/SmsFragment.kt | 509 +++++++------- .../fragment/senders/SocketFragment.kt | 5 +- .../fragment/senders/TelegramFragment.kt | 529 +++++++-------- .../fragment/senders/UrlSchemeFragment.kt | 3 +- .../fragment/senders/WebhookFragment.kt | 631 +++++++++--------- .../fragment/senders/WeworkAgentFragment.kt | 3 +- .../fragment/senders/WeworkRobotFragment.kt | 3 +- app/src/main/res/values-en/strings.xml | 3 +- app/src/main/res/values/strings.xml | 3 +- 18 files changed, 2688 insertions(+), 2678 deletions(-) diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/BarkFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/BarkFragment.kt index e28200dc..92c5bd49 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/BarkFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/BarkFragment.kt @@ -210,7 +210,8 @@ class BarkFragment : BaseFragment(), 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() diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/DingtalkGroupRobotFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/DingtalkGroupRobotFragment.kt index fcf83d98..57c583d1 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/DingtalkGroupRobotFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/DingtalkGroupRobotFragment.kt @@ -190,7 +190,8 @@ class DingtalkGroupRobotFragment : BaseFragment(), View.OnClickListener, CompoundButton.OnCheckedChangeListener { - - private val TAG: String = DingtalkInnerRobotFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { 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 { - 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(), View.OnClickListener, CompoundButton.OnCheckedChangeListener { + + private val TAG: String = DingtalkInnerRobotFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { 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 { + 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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/EmailFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/EmailFragment.kt index ffaa9e68..5855760f 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/EmailFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/EmailFragment.kt @@ -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(), View.OnClickListener { - - private val TAG: String = EmailFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { 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 { - 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(), View.OnClickListener { + + private val TAG: String = EmailFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { 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 { + 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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/FeishuAppFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/FeishuAppFragment.kt index 208acc53..47649d7d 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/FeishuAppFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/FeishuAppFragment.kt @@ -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(), View.OnClickListener { - - private val TAG: String = FeishuAppFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { 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 { - 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(), View.OnClickListener { + + private val TAG: String = FeishuAppFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { 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 { + 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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/FeishuFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/FeishuFragment.kt index 2132e19e..a2686429 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/FeishuFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/FeishuFragment.kt @@ -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(), View.OnClickListener { - - private val TAG: String = FeishuFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { 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 { - 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(), View.OnClickListener { + + private val TAG: String = FeishuFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { 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 { + 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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/GotifyFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/GotifyFragment.kt index e1d0c829..fcef9c03 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/GotifyFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/GotifyFragment.kt @@ -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(), View.OnClickListener { - - private val TAG: String = GotifyFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { 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 { - 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(), View.OnClickListener { + + private val TAG: String = GotifyFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { 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 { + 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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/PushplusFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/PushplusFragment.kt index 70e7c2e9..03579257 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/PushplusFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/PushplusFragment.kt @@ -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(), View.OnClickListener { - - private val TAG: String = PushplusFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { 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 { - 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(), View.OnClickListener { + + private val TAG: String = PushplusFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { 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 { + 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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/ServerchanFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/ServerchanFragment.kt index 2f9004be..b2365bfc 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/ServerchanFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/ServerchanFragment.kt @@ -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(), View.OnClickListener { - - private val TAG: String = ServerchanFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { 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 { - 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(), View.OnClickListener { + + private val TAG: String = ServerchanFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { 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 { + 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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/SmsFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/SmsFragment.kt index d41a2b4d..0c6f681a 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/SmsFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/SmsFragment.kt @@ -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(), View.OnClickListener { - - private val TAG: String = SmsFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { 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, all: Boolean) { - if (!all) { - XToastUtils.error(R.string.toast_granted_part) - HttpServerUtils.enableApiSmsSend = false - } - } - - override fun onDenied(permissions: List, 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 { - 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(), View.OnClickListener { + + private val TAG: String = SmsFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { 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, all: Boolean) { + if (!all) { + XToastUtils.error(R.string.toast_granted_part) + HttpServerUtils.enableApiSmsSend = false + } + } + + override fun onDenied(permissions: List, 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 { + 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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/SocketFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/SocketFragment.kt index d60e54ab..43266d92 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/SocketFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/SocketFragment.kt @@ -157,9 +157,8 @@ class SocketFragment : BaseFragment(), 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() diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/TelegramFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/TelegramFragment.kt index 4676a158..c5665573 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/TelegramFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/TelegramFragment.kt @@ -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(), View.OnClickListener, CompoundButton.OnCheckedChangeListener { - - private val TAG: String = TelegramFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { 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 { - 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(), View.OnClickListener, CompoundButton.OnCheckedChangeListener { + + private val TAG: String = TelegramFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { 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 { + 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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/UrlSchemeFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/UrlSchemeFragment.kt index 3830d5c6..513e9f24 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/UrlSchemeFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/UrlSchemeFragment.kt @@ -147,7 +147,8 @@ class UrlSchemeFragment : BaseFragment(), 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() diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WebhookFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WebhookFragment.kt index 8ebe0c12..6f0ff47f 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WebhookFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WebhookFragment.kt @@ -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(), View.OnClickListener { - - private val TAG: String = WebhookFragment::class.java.simpleName - var titleBar: TitleBar? = null - private val viewModel by viewModels { BaseViewModelFactory(context) } - private var mCountDownHelper: CountDownButtonHelper? = null - private var headerItemMap = HashMap(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 { - 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, - linearLayoutWebNotifyHeaders: LinearLayout, - key: String?, - value: String? - ) { - val linearLayoutItemAddHeader = - View.inflate(requireContext(), R.layout.item_add_header, null) as LinearLayout - val imageViewRemoveHeader = - linearLayoutItemAddHeader.findViewById(R.id.imageViewRemoveHeader) - if (key != null && value != null) { - val editTextHeaderKey = - linearLayoutItemAddHeader.findViewById(R.id.editTextHeaderKey) - val editTextHeaderValue = - linearLayoutItemAddHeader.findViewById(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): Map { - val headers: MutableMap = HashMap() - for (headerItem in headerItemMap.values) { - val editTextHeaderKey = headerItem.findViewById(R.id.editTextHeaderKey) - val editTextHeaderValue = headerItem.findViewById(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(), View.OnClickListener { + + private val TAG: String = WebhookFragment::class.java.simpleName + var titleBar: TitleBar? = null + private val viewModel by viewModels { BaseViewModelFactory(context) } + private var mCountDownHelper: CountDownButtonHelper? = null + private var headerItemMap = HashMap(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 { + 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, + linearLayoutWebNotifyHeaders: LinearLayout, + key: String?, + value: String? + ) { + val linearLayoutItemAddHeader = + View.inflate(requireContext(), R.layout.item_add_header, null) as LinearLayout + val imageViewRemoveHeader = + linearLayoutItemAddHeader.findViewById(R.id.imageViewRemoveHeader) + if (key != null && value != null) { + val editTextHeaderKey = + linearLayoutItemAddHeader.findViewById(R.id.editTextHeaderKey) + val editTextHeaderValue = + linearLayoutItemAddHeader.findViewById(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): Map { + val headers: MutableMap = HashMap() + for (headerItem in headerItemMap.values) { + val editTextHeaderKey = headerItem.findViewById(R.id.editTextHeaderKey) + val editTextHeaderValue = headerItem.findViewById(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() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WeworkAgentFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WeworkAgentFragment.kt index c162eaf7..56decf1d 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WeworkAgentFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WeworkAgentFragment.kt @@ -202,7 +202,8 @@ class WeworkAgentFragment : BaseFragment(), 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() diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WeworkRobotFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WeworkRobotFragment.kt index 03666d7a..c6242435 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WeworkRobotFragment.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/senders/WeworkRobotFragment.kt @@ -144,7 +144,8 @@ class WeworkRobotFragment : BaseFragment(), 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() diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index bee56940..9485100c 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -565,7 +565,8 @@ secs %s sec Retry - [Test Channel] Congratulations, the sending channel test is successful, please continue to add forwarding rules! + [%s] Congratulations, the sending channel test is successful, please continue to add forwarding rules! + Test Channel SIM1_TestOperator_18888888888 Continued Resend diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c3a6e79a..2cc614db 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -566,7 +566,8 @@ %s 秒 重试 - 【测试通道】恭喜您,该发送通道测试成功,请继续添加转发规则! + 【%s】恭喜您,该发送通道测试成功,请继续添加转发规则! + 测试通道 SIM1_测试运营商_18888888888 持续提醒 重发消息