package com.shsening.autouploadvideos.action import android.app.Instrumentation import android.os.SystemClock import android.os.Handler import com.shsening.autouploadvideos.UploadSessionActivity import com.shsening.autouploadvideos.utils.Utils import com.shsening.autouploadvideos.WebviewUtils class ActionDouyin (private var activity: UploadSessionActivity, private var threadHandler: Handler, private var videoInfo: Utils.VideoUploadTaskInfo) :PlatformActionInterface{ private var webView = activity.sessionProfileWebView var jsCode_CheckContentLoaded = """ document.querySelector('input[type="file"][name="upload-btn"]') !== null """.trimIndent() var jsCode_CheckVideoUploadFinished = """ document.querySelector('#root > div > div > div.content-body-v8tuJQ > div.preview-MNjmIb > section > section > section > section.mainPanelWrapper-uThET4.unfold-rUr6x0 > div > section:nth-child(3)') !==null """.trimIndent() var jsCode_PublishVideo_Finished ="document.querySelector('#root > div > div > div.title-UUrMOP > div > div:nth-child(1)') !== null" var jsPath_PublishVideo ="#root > div > div > div.content-body-v8tuJQ > div.form-kSES6A > div.content-confirm-container-Wp91G7 > button.button-dhlUZE.primary-cECiOJ.fixed-J9O8Yw" private fun updatePostDescription(){ WebviewUtils.addValueToInput( webView, "#root > div > div > div.content-body-v8tuJQ > div.form-kSES6A > div.publish-mention-wrapper-LWv5ed > div.editor-container-zRPSAi > div > div > div > div:nth-child(1) > div > div > input", videoInfo.title ) WebviewUtils.addValueToDiv( webView, "#root > div > div > div.content-body-v8tuJQ > div.form-kSES6A > div.publish-mention-wrapper-LWv5ed > div.editor-container-zRPSAi > div > div > div > div.outerdocbody.editor-kit-outer-container > div", videoInfo.description ) WebviewUtils.simpleElementClick( webView, "#root > div > div > div.content-body-v8tuJQ > div.form-kSES6A > div.publish-mention-wrapper-LWv5ed > div:nth-child(3) > div > div.activity-list-container-AZzfdV > div:nth-child(1)" ) WebviewUtils.simpleElementClick( webView, "#root > div > div > div.content-body-v8tuJQ > div.form-kSES6A > div.publish-mention-wrapper-LWv5ed > div:nth-child(3) > div > div.activity-list-container-AZzfdV > div:nth-child(2)" ) WebviewUtils.simpleElementClick( webView, "#root > div > div > div.content-body-v8tuJQ > div.form-kSES6A > div.content-upload-new > div > div.recommendContainer-HXvL9W > div.recommendDisplay-ifUYki > div > div:nth-child(1) > div" ) WebviewUtils.simpleElementClick( webView, "#root > div > div > div.content-body-v8tuJQ > div.form-kSES6A > div.download-content-Lci5tL > div > label:nth-child(2)" ) WebviewUtils.simpleElementClick( webView, "#root > div > div > div.content-body-v8tuJQ > div.form-kSES6A > div.publish-settings-WtW_ZW > div.schedule-part-V615Zn > div.row-suTOx_ > label:nth-child(2)" ) addValueToDatePickerInput(true,"#root > div > div > div.content-body-v8tuJQ > div.form-kSES6A > div.publish-settings-WtW_ZW > div.schedule-part-V615Zn > div.row-suTOx_ > div.date-picker-ioPchj > div > div",videoInfo.datetime) // 在主线程中设置延迟执行 threadHandler.postDelayed(Runnable { startToPublishVideo() }, 5000) } override fun checkIfContentLoaded() { webView.postDelayed({ webView.evaluateJavascript(jsCode_CheckContentLoaded) { result -> if (result == "true") { simulateSwipeAndUploadVideo() } else { webView.postDelayed({ checkIfContentLoaded() }, 1000) // 1秒后再次检查 } } }, 1000) // 每秒检查一次 } private fun startToPublishVideo(){ WebviewUtils.simpleElementClick(webView, jsPath_PublishVideo) checkVideoPublishFinished() } private fun checkVideoUploadFinished(){ webView.postDelayed({ webView.evaluateJavascript(jsCode_CheckVideoUploadFinished) { result -> if (result == "true") { // 等待视频检测和生成封面 threadHandler.postDelayed({updatePostDescription()},3000) } else { // 元素不存在,1秒后再次检查 webView.postDelayed({ checkVideoUploadFinished() }, 1000) // 1秒后再次检查 } } }, 1000) // 每秒检查一次 } private fun checkVideoPublishFinished(){ webView.postDelayed({ webView.evaluateJavascript(jsCode_PublishVideo_Finished) { result -> if (result == "true") { // video published successfully!!! activity.checkAndStartNextTask() } else { // 元素不存在,1秒后再次检查 webView.postDelayed({ checkVideoPublishFinished() }, 1000) // 1秒后再次检查 } } }, 1000) // 每秒检查一次 } private fun addValueToDatePickerInput(first:Boolean, jsPath: String, targetValue: String) { var datetimes = Utils.validateAndReturnDateTime(targetValue) ?: return var dpPanelText = datetimes[0].toString()+"年 "+datetimes[1].toString()+"月"; var dateRowColum = Utils.getDatePosition(datetimes[0], datetimes[1], datetimes[2]) ?:return; val jsCode = """ try { var dp = document.querySelector('${jsPath}'); dp.focus(); // 确保输入框获得焦点 dp.click(); // need time to popup date-picker setTimeout(() => { var dpPanel = document.querySelector('.semi-popover-content'); var dpPanelSpan = dpPanel.querySelector('div > div > div > div:nth-child(1) > div.semi-datepicker-navigation > div > button > span > span'); if (dpPanelSpan && dpPanelSpan.textContent != '${dpPanelText}'){ dpPanel.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-navigation > button:nth-child(3)').click(); } dpPanel.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-month > div.semi-datepicker-weeks > div:nth-child(${dateRowColum[0]}) > div:nth-child(${dateRowColum[1]})').click() //switch to time selection dpPanel.querySelector('div > div > div > div > div.semi-datepicker-switch > div.semi-datepicker-switch-time').click(); setTimeout(() => { dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-hour > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[3]+1)})').click(); dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-minute > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[4]+1)})').click(); }, 500); }, 500); } catch (error) { console.error('发生错误:', error); } """ webView.evaluateJavascript(jsCode,null) } private fun simulateSwipeAndUploadVideo() { val instrumentation = Instrumentation() val displayMetrics = activity.resources.displayMetrics val width = displayMetrics.widthPixels val height = displayMetrics.heightPixels val startX = width.toFloat() * 0.9f // 从右侧滑动 val endX = width.toFloat() * 0.1f // 滑动到左侧 val y = height / 3f // Y 坐标在屏幕中间 Thread { Utils.instrumentationSwipe(instrumentation, startX, y, endX, y) SystemClock.sleep(500) Utils.instrumentationSwipe(instrumentation, startX, y, endX, y) SystemClock.sleep(500) Utils.instrumentationClick(instrumentation, width / 2f, height * 2 / 4f) // back to main thread threadHandler.post { checkVideoUploadFinished() } }.start() } }