按钮互斥
This commit is contained in:
@@ -215,4 +215,16 @@ video {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
// justify-content: center;
|
||||
}
|
||||
|
||||
.left-button.active {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
/* 互斥期间的其它三枚按钮置灰禁点 */
|
||||
.left-button.disabled {
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
filter: grayscale(0.4);
|
||||
}
|
||||
@@ -3,8 +3,9 @@
|
||||
<el-scrollbar class="left"> <!-- 左边栏 -->
|
||||
<div class="center-line"> <!-- 左边栏按钮 -->
|
||||
<div v-for="(btn, index) in buttons" :key="index" style="width: 100%;">
|
||||
<div v-if="btn.show?.()" class="left-button" :style="btn.style ? btn.style() : {}" @click="btn.onClick"
|
||||
@mouseenter="hoverIndex = index" @mouseleave="hoverIndex = null">
|
||||
<div v-if="btn.show?.()" class="left-button" :class="[{ active: isActive(btn), disabled: isDisabled(btn) }]"
|
||||
:style="btn.style ? btn.style() : {}" @click="handleBtnClick(btn)" @mouseenter="hoverIndex = index"
|
||||
@mouseleave="hoverIndex = null">
|
||||
<img :src="hoverIndex === index ? btn.img.hover : btn.img.normal" alt="">
|
||||
{{ btn.label }}
|
||||
</div>
|
||||
@@ -64,7 +65,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, onBeforeUnmount, watch, inject, nextTick } from "vue";
|
||||
import { ref, onMounted, computed, onUnmounted, onBeforeUnmount, watch, inject, nextTick } from "vue";
|
||||
import VideoConverter from "h264-converter";
|
||||
import { useRouter } from 'vue-router';
|
||||
import {
|
||||
@@ -128,7 +129,7 @@ let isMsgPop = ref(false);
|
||||
//播放器列表
|
||||
let instanceList = [{}, {}, {}, {}, {}, {}, {}, {}];
|
||||
//是否是在关注主播
|
||||
let runType = ref(['', '', '', '', '', '', '', '']);
|
||||
let runType = ref('');
|
||||
//屏幕尺寸系数
|
||||
let isMonitor = ref(false);
|
||||
let iponeCoefficient = ref([{ width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }]);
|
||||
@@ -157,7 +158,56 @@ let phoneXYinfo = ref(getphoneXYinfo() == null ? [{}, {}, {}, {}, {}, {}, {}, {}
|
||||
// 当前悬浮的按钮索引
|
||||
const hoverIndex = ref(null)
|
||||
const isMonitorOn = ref(false) // false 表示关闭,true 表示开启
|
||||
// 这四个互斥模式的 key,和你的 runType 对应
|
||||
const EXCLUSIVE_KEYS = ['brushLive', 'like', 'follow', 'listen'];
|
||||
|
||||
// 映射一下中文名,仅用于提示
|
||||
const KEY_LABEL = {
|
||||
brushLive: '刷直播',
|
||||
like: '刷视频',
|
||||
follow: '一键关注并打招呼',
|
||||
listen: '监测消息',
|
||||
};
|
||||
|
||||
// 当前激活的互斥 key(runType 里只要是这四个之一就视为锁定)
|
||||
const activeKey = computed(() => EXCLUSIVE_KEYS.includes(runType.value) ? runType.value : '');
|
||||
|
||||
// 是否处于锁定(有激活模式)
|
||||
const isLocked = computed(() => !!activeKey.value);
|
||||
|
||||
// 尝试激活某个模式(带拦截、可二次点击退出)
|
||||
function tryActivate(key, runner) {
|
||||
// 其它模式在运行,阻止切换
|
||||
if (activeKey.value && activeKey.value !== key) {
|
||||
ElMessage.warning(`当前正在【${KEY_LABEL[activeKey.value]}】。请先点击“全部停止”或再次点击当前红色按钮停止。`);
|
||||
return;
|
||||
}
|
||||
// 二次点击同一按钮 => 视为停止
|
||||
if (activeKey.value === key) {
|
||||
stop(); // 你已有的停止方法,会把 runType 置空并清理状态
|
||||
return;
|
||||
}
|
||||
// 设置 runType 并跑逻辑
|
||||
runType.value = key;
|
||||
if (typeof runner === 'function') runner();
|
||||
}
|
||||
|
||||
// 供模板使用:是否为激活按钮
|
||||
function isActive(btn) {
|
||||
return !!btn.key && activeKey.value === btn.key;
|
||||
}
|
||||
|
||||
// 供模板使用:是否应禁用
|
||||
function isDisabled(btn) {
|
||||
// 只禁用互斥组内的按钮;非互斥按钮(刷新/重置/登出等)不受影响
|
||||
return !!btn.key && isLocked.value && activeKey.value !== btn.key && EXCLUSIVE_KEYS.includes(btn.key);
|
||||
}
|
||||
|
||||
// 统一处理点击,拦截禁用状态
|
||||
function handleBtnClick(btn) {
|
||||
if (isDisabled(btn)) return;
|
||||
if (typeof btn.onClick === 'function') btn.onClick();
|
||||
}
|
||||
// 你可以用这种方式声明按钮们
|
||||
const buttons = [
|
||||
{
|
||||
@@ -188,72 +238,62 @@ const buttons = [
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '打开直播',
|
||||
onClick: () => {
|
||||
runType.value[0] = 'brushLive'
|
||||
brushLive()
|
||||
},
|
||||
label: '刷直播',
|
||||
key: 'brushLive',
|
||||
onClick: () => tryActivate('brushLive', () => {
|
||||
runType.value = 'brushLive';
|
||||
brushLive();
|
||||
}),
|
||||
show: () => true,
|
||||
img: {
|
||||
normal: new URL('@/assets/video/leftBtn4.png', import.meta.url).href,
|
||||
hover: new URL('@/assets/video/leftBtn4-4.png', import.meta.url).href
|
||||
},
|
||||
style: () => ({
|
||||
backgroundColor: runType.value[0] == 'brushLive' ? 'red' : ''
|
||||
})
|
||||
style: () => ({ backgroundColor: isActive({ key: 'brushLive' }) ? 'red' : '' })
|
||||
},
|
||||
{
|
||||
label: '一键养号',
|
||||
onClick: () => {
|
||||
if (runType.value[0] == 'like') return;
|
||||
runType.value[0] = 'like'
|
||||
parentNum()
|
||||
},
|
||||
label: '刷视频',
|
||||
key: 'like',
|
||||
onClick: () => tryActivate('like', () => {
|
||||
runType.value = 'like';
|
||||
parentNum();
|
||||
}),
|
||||
show: () => true,
|
||||
img: {
|
||||
normal: new URL('@/assets/video/leftBtn5.png', import.meta.url).href,
|
||||
hover: new URL('@/assets/video/leftBtn5-5.png', import.meta.url).href
|
||||
},
|
||||
style: () => ({
|
||||
backgroundColor: runType.value[0] == 'like' ? 'red' : ''
|
||||
})
|
||||
style: () => ({ backgroundColor: isActive({ key: 'like' }) ? 'red' : '' })
|
||||
},
|
||||
{
|
||||
label: '一键关注并打招呼',
|
||||
onClick: () => {
|
||||
if (runType.value[0] == 'follow') return;
|
||||
runType.value[0] = 'follow'
|
||||
showDialog.value = true
|
||||
dialogTitle.value = '主播ID'
|
||||
selectedDevice.value = 999
|
||||
},
|
||||
key: 'follow',
|
||||
onClick: () => tryActivate('follow', () => {
|
||||
runType.value = 'follow';
|
||||
showDialog.value = true;
|
||||
dialogTitle.value = '主播ID';
|
||||
selectedDevice.value = 999;
|
||||
}),
|
||||
show: () => true,
|
||||
img: {
|
||||
normal: new URL('@/assets/video/leftBtn6.png', import.meta.url).href,
|
||||
hover: new URL('@/assets/video/leftBtn6-6.png', import.meta.url).href
|
||||
},
|
||||
style: () => ({
|
||||
backgroundColor: runType.value[0] == 'follow' ? 'red' : ''
|
||||
})
|
||||
style: () => ({ backgroundColor: isActive({ key: 'follow' }) ? 'red' : '' })
|
||||
},
|
||||
{
|
||||
label: '监测消息',
|
||||
onClick: () => {
|
||||
isMonitorOn.value = !isMonitorOn.value
|
||||
if (isMonitorOn.value) {
|
||||
openMonitor()
|
||||
} else {
|
||||
cloesMonitor()
|
||||
}
|
||||
},
|
||||
key: 'listen',
|
||||
onClick: () => tryActivate('listen', () => {
|
||||
isMonitorOn.value = true;
|
||||
openMonitor();
|
||||
}),
|
||||
show: () => true,
|
||||
img: {
|
||||
normal: new URL('@/assets/video/leftBtn1.png', import.meta.url).href,
|
||||
hover: new URL('@/assets/video/leftBtn1-1.png', import.meta.url).href
|
||||
},
|
||||
style: () => ({
|
||||
backgroundColor: isMonitorOn.value ? 'red' : ''
|
||||
})
|
||||
style: () => ({ backgroundColor: isActive({ key: 'listen' }) ? 'red' : '' })
|
||||
},
|
||||
{
|
||||
label: '全部停止',
|
||||
@@ -381,7 +421,7 @@ const initVideoStream = async (udid, index) => {
|
||||
} else if (resData.type == 'getmesNum') {
|
||||
if (resData.message == 0) {
|
||||
console.log('没有消息')
|
||||
if (runType.value[index] == 'follow') {
|
||||
if (runType.value == 'follow') {
|
||||
LikesToLikesToLikes(deviceInformation.value[index].udid, index)
|
||||
|
||||
}
|
||||
@@ -389,7 +429,7 @@ const initVideoStream = async (udid, index) => {
|
||||
} else if (resData.message == 1) {
|
||||
console.log('有消息')
|
||||
} else if (resData.message == '点击成功') {
|
||||
console.log('双击', iponeCoefficient.value[index].width, iponeCoefficient.value[index].height)
|
||||
console.log('双击', resData.x * iponeCoefficient.value[index].width, resData.y * iponeCoefficient.value[index].height, index)
|
||||
setTimeout(() => {
|
||||
clickxy(resData.x * iponeCoefficient.value[index].width, resData.y * iponeCoefficient.value[index].height, index)
|
||||
setTimeout(() => {
|
||||
@@ -406,6 +446,9 @@ const initVideoStream = async (udid, index) => {
|
||||
Back('', index)
|
||||
setTimeout(() => {
|
||||
Back('', index)
|
||||
if (runType.value == 'follow') {
|
||||
LikesToLikesToLikes(deviceInformation.value[index].udid, index)
|
||||
}
|
||||
}, 1000)
|
||||
}, 1000)
|
||||
|
||||
@@ -475,7 +518,7 @@ const initVideoStream = async (udid, index) => {
|
||||
iponeCoefficient.value[index].width = scaledW / resData.width
|
||||
iponeCoefficient.value[index].height = scaledH / resData.height
|
||||
console.log(
|
||||
`[getSize] raw=${RAW_W}x${RAW_H} -> scaled=${scaledW}x${scaledH} (align↓${ALIGN})`
|
||||
`[getSize] raw=${RAW_W}x${RAW_H} -> scaled=${scaledW}x${scaledH} (align↓${ALIGN}) ${iponeCoefficient.value[index].width} ${iponeCoefficient.value[index].height}`
|
||||
);
|
||||
} else {
|
||||
console.log(resData.type, '坐标返回:x:', resData.x, 'y:', resData.y);
|
||||
@@ -484,7 +527,7 @@ const initVideoStream = async (udid, index) => {
|
||||
phoneXYinfo.value[index].id = resData.device
|
||||
if (resData.type == 'Likes') {//判断是否是 点赞
|
||||
phoneXYinfo.value[index].Likes = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
|
||||
if (runType.value[index] == 'follow') {
|
||||
if (runType.value == 'follow') {
|
||||
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
|
||||
}
|
||||
} else if (resData.type == 'Comment') {//打开评论
|
||||
@@ -498,7 +541,7 @@ const initVideoStream = async (udid, index) => {
|
||||
phoneXYinfo.value[index].ComPush = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
|
||||
setTimeout(() => {
|
||||
Back('', index)
|
||||
if (runType.value[index] == 'follow') {
|
||||
if (runType.value == 'follow') {
|
||||
setTimeout(() => {
|
||||
Back('', index)
|
||||
}, 1000)
|
||||
@@ -612,7 +655,7 @@ const initVideoStream = async (udid, index) => {
|
||||
// 用法:
|
||||
(async () => {
|
||||
const result = await randomDelayAndExecute();
|
||||
if (runType.value[0] !== 'brushLive') {
|
||||
if (runType.value !== 'brushLive') {
|
||||
return
|
||||
}
|
||||
//30%概率
|
||||
@@ -661,7 +704,7 @@ const initVideoStream = async (udid, index) => {
|
||||
// ----------------------------------------------------------------------------------------------------报错处理
|
||||
//如果该视频无法被评论,或者没有评论,返回刷下一条视频
|
||||
if (resData.type == 'Comtext' || resData.type == 'CommentText') {
|
||||
if (runType.value[index] == 'follow') {
|
||||
if (runType.value == 'follow') {
|
||||
|
||||
Back('', index)
|
||||
setTimeout(() => {
|
||||
@@ -687,7 +730,7 @@ const initVideoStream = async (udid, index) => {
|
||||
}, 1000)
|
||||
}, 1000)
|
||||
} else if (resData.type == 'Privatetex' || resData.type == 'hostVideo' || resData.type == 'search' || resData.type == 'Attention' || resData.type == 'Comment') {
|
||||
if (runType.value[index] == 'follow') {
|
||||
if (runType.value == 'follow') {
|
||||
//关注的时候出现无法私信和没有视频的情况 错误重置
|
||||
resetApp(udid, index)
|
||||
setTimeout(() => {
|
||||
@@ -697,7 +740,7 @@ const initVideoStream = async (udid, index) => {
|
||||
}
|
||||
|
||||
} else if (resData.type == 'getmesNum') {
|
||||
if (runType.value[index] == 'follow') {
|
||||
if (runType.value == 'follow') {
|
||||
LikesToLikesToLikes(deviceInformation.value[index].udid, index)
|
||||
}
|
||||
//getmesNum出现没有消息的情况
|
||||
@@ -907,8 +950,8 @@ onMounted(() => {
|
||||
//私信
|
||||
textContentpriArr.value.forEach((item, indexA) => {
|
||||
textContentpri.value[indexA] = resB[getRandomNumber(resB.length - 1)];
|
||||
runType.value[indexA] = 'follow'
|
||||
console.log('runType', runType.value[indexA])
|
||||
runType.value = 'follow'
|
||||
console.log('runType', runType.value)
|
||||
})
|
||||
deviceInformation.value.forEach((device, indexB) => {
|
||||
if (getHostList().length <= 0) return;
|
||||
@@ -927,7 +970,7 @@ onMounted(() => {
|
||||
} else {
|
||||
// stroageHost.value = getHostList()
|
||||
stroageHost.value.push(({ country: data.country, text: data.hostsId, state: false }))
|
||||
if (runType.value[0] == 'follow') {
|
||||
if (runType.value == 'follow') {
|
||||
setHostList(stroageHost.value)
|
||||
}
|
||||
|
||||
@@ -1051,7 +1094,7 @@ async function LikesToCommentToComPush(udid, index) {
|
||||
//点赞主页4个作品+评论最后一个作品并返回
|
||||
async function LikesToLikesToLikes(udid, index) {
|
||||
isStop.value = false;
|
||||
runType.value[index] = 'follow';
|
||||
runType.value = 'follow';
|
||||
|
||||
// await sendWsTask(index, { udid, action: 'click', type: 'getmesNum', index, resourceId: 'com.zhiliaoapp.musically:id/jyv' });
|
||||
await sendWsTask(index, { udid, action: 'click', type: 'search', index, resourceId: 'com.zhiliaoapp.musically:id/gtz' });
|
||||
@@ -1093,7 +1136,7 @@ function setComText(index) {
|
||||
}, 300);
|
||||
console.log('发送评论内容', index, textContent.value[index])
|
||||
wslist[index].send(setClipboard(textContent.value[index]));
|
||||
if (runType.value[index] === 'follow') {
|
||||
if (runType.value === 'follow') {
|
||||
textContent.value[index] = getContentList()[index][getRandomNumber(getContentList()[index].length - 1)];
|
||||
}
|
||||
}
|
||||
@@ -1124,7 +1167,7 @@ function setPrivateText(index, datatype) {
|
||||
}, 300);
|
||||
console.log('发送私信内容', index, textContentpri.value[index])
|
||||
//如果是在关注主播中,发送的开场白进行对应国家翻译
|
||||
if (runType.value[index] === 'follow' && datatype == 'PrivatePush') {
|
||||
if (runType.value === 'follow' && datatype == 'PrivatePush') {
|
||||
translation({ msg: getContentpriList()[index][getRandomNumber(getContentpriList()[index].length - 1)], country: hostIdArr.value[index].country }).then(res => {
|
||||
console.log(res)
|
||||
textContentpri.value[index] = res;
|
||||
@@ -1312,7 +1355,7 @@ function sendWsTask(index, data) {
|
||||
if (data.type == 'isHost') {
|
||||
}
|
||||
if (data.type == 'Comment') {
|
||||
if (runType.value[index] == 'follow') {
|
||||
if (runType.value == 'follow') {
|
||||
clickxy(160, 360, index)
|
||||
}
|
||||
}
|
||||
@@ -1431,7 +1474,7 @@ function stop() {
|
||||
//停止当前任务
|
||||
|
||||
//重置当前状态
|
||||
runType.value[i] = ''
|
||||
runType.value = ''
|
||||
//清除观看视频定时器
|
||||
clearInterval(playTimer.value[i])
|
||||
playTimer.value[i] = null;//清除定时器
|
||||
@@ -1458,7 +1501,7 @@ function openMonitor(type) {
|
||||
|
||||
deviceInformation.value.forEach((device, index) => {
|
||||
wsActions.getmesNum(device.udid, index)
|
||||
runType.value[index] = 'listen'
|
||||
runType.value = 'listen'
|
||||
})
|
||||
isShowMes.value = setInterval(() => {
|
||||
deviceInformation.value.forEach((device, index) => {
|
||||
@@ -1471,7 +1514,7 @@ function openMonitor(type) {
|
||||
function cloesMonitor() {
|
||||
isMonitorOn.value = false;//关闭监听
|
||||
deviceInformation.value.forEach((device, index) => {
|
||||
runType.value[index] = ''
|
||||
runType.value = ''
|
||||
})
|
||||
clearInterval(isShowMes.value)
|
||||
isShowMes.value = ''
|
||||
@@ -1481,14 +1524,14 @@ function cloesMonitor() {
|
||||
function parentNum() {
|
||||
isStop.value = false;
|
||||
deviceInformation.value.forEach((device, index) => {
|
||||
runType.value[index] = 'like'
|
||||
runType.value = 'like'
|
||||
wsActions.isHost(device.udid, index)
|
||||
})
|
||||
}
|
||||
function brushLive() {
|
||||
isStop.value = false;
|
||||
deviceInformation.value.forEach((device, index) => {
|
||||
runType.value[index] = 'brushLive'
|
||||
runType.value = 'brushLive'
|
||||
wsActions.toLive(device.udid, index)
|
||||
})
|
||||
}
|
||||
@@ -1518,7 +1561,7 @@ function onDialogConfirm(result, type, index, isMon) {
|
||||
isMonitor.value = isMon //是否自动回复
|
||||
textContentpriArr.value.forEach((item, indexA) => {
|
||||
textContentpri.value[indexA] = result[getRandomNumber(result.length - 1)];
|
||||
runType.value[indexA] = 'follow'
|
||||
runType.value = 'follow'
|
||||
})
|
||||
// isStop.value = true; //停止所有任务
|
||||
setContentpriList(result)
|
||||
|
||||
Reference in New Issue
Block a user