Skip to content

Commit

Permalink
add live control to shared
Browse files Browse the repository at this point in the history
  • Loading branch information
LucHeart committed Dec 29, 2023
1 parent 424a5f6 commit 7397e2b
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 101 deletions.
59 changes: 31 additions & 28 deletions src/views/dashboard/shockers/own/OwnShocker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@
<span v-if="liveMode">
<b-row class="live-type">
<b-button-group>
<b-button :class="{ active: shocker.$live.type === 'sound'}" @click="shocker.$live.type = 'sound'"><i class="fas fa-solid fa-volume-high"></i></b-button>
<b-button :class="{ active: shocker.$live.type === 'vibrate'}" @click="shocker.$live.type = 'vibrate'"><i class="fas fa-solid fa-water"></i></b-button>
<b-button :class="{ active: shocker.$live.type === 'shock'}" @click="shocker.$live.type = 'shock'"><i class="fas fa-solid fa-bolt"></i></b-button>
<b-button :class="{ active: shocker.$live.type === 'sound' }"
@click="shocker.$live.type = 'sound'"><i class="fas fa-solid fa-volume-high"></i></b-button>
<b-button :class="{ active: shocker.$live.type === 'vibrate' }"
@click="shocker.$live.type = 'vibrate'"><i class="fas fa-solid fa-water"></i></b-button>
<b-button :class="{ active: shocker.$live.type === 'shock' }"
@click="shocker.$live.type = 'shock'"><i class="fas fa-solid fa-bolt"></i></b-button>
</b-button-group>
</b-row>

Expand Down Expand Up @@ -66,14 +69,15 @@
</b-container>
</b-row>
<b-row v-if="delay.controlsDisabled" align-h="center">
<b-col md="auto">
<b-button id="delayed-actions-button" variant="nano" @click="cancelDelayed">Delayed actions in {{ this.delay.timeRemaining }}s</b-button>
<b-tooltip target="delayed-actions-button" triggers="hover">
Click to cancel
</b-tooltip>
</b-col>
</b-row>
<b-row v-else align-h="center">
<b-col md="auto">
<b-button id="delayed-actions-button" variant="nano" @click="cancelDelayed">Delayed actions in
{{ this.delay.timeRemaining }}s</b-button>
<b-tooltip target="delayed-actions-button" triggers="hover">
Click to cancel
</b-tooltip>
</b-col>
</b-row>
<b-row v-else align-h="center">
<b-col cols="auto" md="auto">
<control-button style="width: 46px" text="" icon="fa-solid fa-volume-high"
loadingIcon="fa-solid fa-spinner fa-spin" :loading="inProgress" @click="control(3)" />
Expand All @@ -88,20 +92,20 @@
</b-col>
</b-row>

<b-row class="random-slider">
<b-col md="auto">
<BFormCheckbox v-model="delay.randomSliderWarning" id="random-slider-warning-checkbox">
</BFormCheckbox>
<b-tooltip target="random-slider-warning-checkbox" triggers="hover">
Send a warning (vibrate) before sending a shock<br>
(Set slider to 0 to disable delay)
</b-tooltip>
</b-col>
<b-col>
<Slider v-model="delay.randomSliderValue" style="margin-top: 10px" :step=0.3 :min=0 :max=5
:format="formatTooltipSlider" showTooltip="focus" />
</b-col>
</b-row>
<b-row class="random-slider">
<b-col md="auto">
<BFormCheckbox v-model="delay.randomSliderWarning" id="random-slider-warning-checkbox">
</BFormCheckbox>
<b-tooltip target="random-slider-warning-checkbox" triggers="hover">
Send a warning (vibrate) before sending a shock<br>
(Set slider to 0 to disable delay)
</b-tooltip>
</b-col>
<b-col>
<Slider v-model="delay.randomSliderValue" style="margin-top: 10px" :step=0.3 :min=0 :max=5
:format="formatTooltipSlider" showTooltip="focus" />
</b-col>
</b-row>
</span>
</div>
</div>
Expand Down Expand Up @@ -220,7 +224,7 @@ export default {
this.delay.timeout = null;
}
this.delay.controlsDisabled = false;
this.delay.controlsDisabled = false;
},
delayCountDown() {
this.delay.timeRemaining = (Math.max(0, (this.delay.in - Date.now())) / 1000).toFixed(1);
Expand Down Expand Up @@ -396,5 +400,4 @@ export default {
padding: 0 12px;
}
}
}
</style>
}</style>
5 changes: 5 additions & 0 deletions src/views/dashboard/shockers/shared/Shared.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export default {
intensity: 25,
duration: 1
}
shocker.$live = {
dragging: false,
intensity: 0,
type: "vibrate"
}
});
});
});
Expand Down
174 changes: 166 additions & 8 deletions src/views/dashboard/shockers/shared/SharedDevice.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,51 @@
<b-col cols="auto">
<p>{{ device.name }}</p>
</b-col>
<b-col :class="onlineStateComp">
<i class="fa-solid fa-circle"></i>
<b-col cols="auto">
<span :id="'tooltip-state' + device.id" :class="!this.onlineState ? 'offline' : 'online'">
<i class="fa-solid fa-circle"></i>
</span>
<b-tooltip :target="'tooltip-state' + device.id" triggers="hover">
{{ !this.onlineState ? 'Offline' : 'Online' }}<span v-if="this.onlineState"><br>Firmware Version: {{
getFirmwareVersionString }}</span>
</b-tooltip>
</b-col>
<b-col cols="auto">
<span class="live" :id="'tooltip-live' + device.id" :class="{ active: this.lcgState === 1 }"
@click="liveClick">LIVE<span v-if="live.rawState === 0"> <i style="color: var(--main-text-color);" class="fas fa-cog fa-spin"></i></span></span>
<b-tooltip :target="'tooltip-live' + device.id" triggers="hover">
<span v-if="!live.enabled">Connect to Live Control</span>
<span v-else-if="live.rawState === 0">Connecting...<br><br>Gateway: {{ live.gateway }}<br>Country: {{ live.gatewayCountry }}</span>
<span v-else>Disconnect from Live Control<br><br>Gateway: {{ live.gateway }}<br>Country: {{ live.gatewayCountry }}<br>Latency: {{ live.latency }}ms</span>
</b-tooltip>
</b-col>
</b-row>
<b-row>
<b-col v-for="item in device.shockers" :key="item.id" class="shocker-col">
<shared-shocker :shocker="item"></shared-shocker>
<shared-shocker :shocker="item" :live-mode="live.rawState === 1"></shared-shocker>
</b-col>

</b-row>
</b-container>
</template>

<script>
import toastr from 'toastr';
import SharedShocker from './SharedShocker.vue';
export default {
components: { SharedShocker },
props: ['device'],
data() {
return {
onlineState: false,
firmwareVersion: null
firmwareVersion: null,
live: {
enabled: false,
gateway: null,
websocket: null,
rawState: 3,
latency: 0
}
}
},
beforeMount() {
Expand All @@ -35,7 +59,111 @@ export default {
this.firmwareVersion = data.firmwareVersion;
});
},
mounted() {
setInterval(() => {
this.updateWebSocketStatus();
}, 20);
},
methods: {
liveClick() {
this.live.enabled = !this.live.enabled;
if (this.live.enabled) {
this.startLive();
} else {
this.stopLive();
}
},
startLive() {
this.connectLive();
this.tickLoop();
},
stopLive() {
this.live.enabled = false;
this.disconnect();
},
async disconnect() {
this.live.websocket?.close();
},
async connectLive() {
await this.disconnect();
const res = await apiCall.makeCallNoThrow('GET', '1/devices/' + this.device.id + '/lcg');
if (res.status !== 200) {
console.log(res);
toastr.error(res.data.message, "Failed to connect to live control gateway");
return;
}
this.live.gateway = res.data.data.gateway;
this.live.gatewayCountry = res.data.data.country;
this.live.websocket = new WebSocket('wss://' + 'localhost:5443' + '/1/ws/live/' + this.device.id);
this.live.websocket.onclose = (event) => {
console.log(event, "Live Control Gateway Connection Closed");
this.live.websocket = null;
this.live.rawState = 3;
this.live.latency = 0;
this.live.enabled = false;
};
this.live.websocket.onerror = (event) => {
console.log(event, "Live Control Gateway Connection Error");
this.live.websocket = null;
this.live.rawState = 3;
this.live.latency = 0;
this.live.enabled = false;
};
this.live.websocket.onmessage = (event) => {
console.log(event.data);
const json = JSON.parse(event.data);
switch (json.ResponseType) {
case "Ping":
this.live.websocket.send(JSON.stringify({
RequestType: "Pong",
Data: {
Timestamp: json.Data.Timestamp
}
}));
break;
case "LatencyAnnounce":
this.live.latency = json.Data[this.$store.state.user.id];
break;
}
};
},
updateWebSocketStatus() {
this.live.rawState = this.live.websocket?.readyState;
},
tickLoop() {
if (!this.live.enabled) return;
this.device.shockers.forEach(shocker => {
if (!shocker.$live.isDragging) return;
console.log(shocker.name + " - " + shocker.$live.intensity);
this.live.websocket.send(JSON.stringify({
RequestType: "Frame",
Data: {
Shocker: shocker.id,
Intensity: parseInt(shocker.$live.intensity),
Type: shocker.$live.type
}
}));
});
setTimeout(() => {
this.tickLoop();
}, 100);
},
getOnlineState() {
if (this.$store.state.deviceStates[this.device.id] === undefined) return false;
return this.$store.state.deviceStates[this.device.id].online;
Expand All @@ -46,9 +174,14 @@ export default {
}
},
computed: {
onlineStateComp() {
return this.onlineState ? 'online' : 'offline';
}
getFirmwareVersionString() {
if (this.firmwareVersion === null) return "Older than 7.1.0.0, please upgrade.";
return this.firmwareVersion;
},
lcgState() {
if(this.live.websocket === null || this.live.rawState === null) return 3;
return this.live.rawState;
},
}
}
</script>
Expand All @@ -60,7 +193,32 @@ export default {
padding: 20px;
.shocker-col {
min-width: 300px;
@media screen and (min-width: 465px) {
min-width: 375px;
}
}
.live {
border: 1px solid;
border-color: var(--main-text-color);
padding: 0 4px;
font-size: 10pt;
background: var(--main-text-color);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
cursor: pointer;
&.active {
background: linear-gradient(to right, rgb(185, 123, 255), #e100ff);
background-clip: text;
color: transparent;
-webkit-background-clip: text;
border-image: linear-gradient(to right, rgb(167, 89, 255), #e100ff);
border-image-slice: 1;
}
}
.online {
Expand Down
Loading

0 comments on commit 7397e2b

Please sign in to comment.