Skip to content

Commit

Permalink
PLS dirty implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
maxlk96 committed Oct 4, 2024
1 parent fbd4d85 commit 5fe40c3
Show file tree
Hide file tree
Showing 5 changed files with 379 additions and 42 deletions.
219 changes: 178 additions & 41 deletions frontend/src/components/About.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,181 @@
<template>
<div class="text-grey-lighten-1 text-body-2">
<p class="mb-3">
VatIRIS is an interpretation of its real-world counterpart
<a href="https://www.awos.se/sv-se/products/iris.aspx" target="_blank">IRIS</a> -
Integrated Real-time Information System, but adapted and extended for use by VATSIM
controllers in Sweden.
</p>
<p>It's currently under heavy development, so please expect bugs.</p>
<p>
Welcome to file bug reports or feature requests as
<a href="https://github.com/minsulander/vatiris/issues" target="_blank">issues</a>
</p>
<p class="mt-3" v-if="auth.user">
Logged in as {{ auth.user.personal.name_full }}, {{ auth.user.cid }},
{{ auth.user.vatsim.rating.short }}
<span v-if="auth.user.vatsim.subdivision && auth.user.vatsim.subdivision.name">
from {{ auth.user.vatsim.subdivision.name }}</span
>
<span v-else-if="auth.user.vatsim.division && auth.user.vatsim.division.name">
from {{ auth.user.vatsim.division.name }}</span
>
</p>
<p class="mt-3">
<router-link class="text-grey-darken-1" to="privacy">Privacy policy</router-link>
</p>
<p class="text-grey-darken-1 mt-3">
Copyright &copy; 2024 Martin Insulander and contributors
</p>
<p class="mt-3">
<a
class="text-grey-darken-1"
href="https://github.com/minsulander/vatiris"
target="_blank"
><v-icon>mdi-github</v-icon> VatIRIS on GitHub</a
>
</p>
<p class="mb-3">
VatIRIS is an interpretation of its real-world counterpart
<a href="https://www.awos.se/sv-se/products/iris.aspx" target="_blank">IRIS</a> -
Integrated Real-time Information System, but adapted and extended for use by VATSIM
controllers in Sweden.
</p>
<p>It's currently under heavy development, so please expect bugs.</p>
<p>
Welcome to file bug reports or feature requests as
<a href="https://github.com/minsulander/vatiris/issues" target="_blank">issues</a>
</p>
<p class="mt-3" v-if="auth.user">
Logged in as {{ auth.user.personal.name_full }}, {{ auth.user.cid }},
{{ auth.user.vatsim.rating.short }}
<span v-if="auth.user.vatsim.subdivision && auth.user.vatsim.subdivision.name">
from {{ auth.user.vatsim.subdivision.name }}</span
>
<span v-else-if="auth.user.vatsim.division && auth.user.vatsim.division.name">
from {{ auth.user.vatsim.division.name }}</span
>
</p>
<p class="mt-3">
<router-link class="text-grey-darken-1" to="privacy">Privacy policy</router-link>
</p>
<p class="text-grey-darken-1 mt-3">
Copyright &copy; 2024 Martin Insulander and contributors
</p>
<p class="mt-3">
<a
class="text-grey-darken-1"
href="https://github.com/minsulander/vatiris"
target="_blank"
><v-icon>mdi-github</v-icon> VatIRIS on GitHub</a
>
</p>

<!-- New buttons for selecting logic -->
<div class="mt-3">
Set PLS Logic
<v-btn
:color="logic === 'cid' ? 'primary' : 'default'"
@click="setLogic('cid')"
class="mr-2"
>
CID
</v-btn>
<v-btn
:color="logic === 'position' ? 'primary' : 'default'"
@click="setLogic('position')"
>
Position
</v-btn>
</div>

<!-- CID logic -->
<div v-if="logic === 'cid'" class="mt-3">
<v-checkbox
v-model="useVatsimCid"
label="Use VATSIM connect CID"
@change="handleCidOption"
></v-checkbox>
<div v-if="!useVatsimCid">
<v-text-field
label="CID 1"
v-model="manualCid1"
outlined
dense
></v-text-field>
<v-text-field
label="CID 2"
v-model="manualCid2"
outlined
dense
></v-text-field>
</div>
</div>

<!-- Position logic -->
<div v-if="logic === 'position'" class="mt-3">
<v-text-field
label="Position 1"
v-model="pos1"
outlined
dense
></v-text-field>
<v-text-field
label="Position 2"
v-model="pos2"
outlined
dense
></v-text-field>
</div>

<!-- Apply button -->
<v-btn color="success" class="mt-3" @click="applyLogic">Apply</v-btn>
</div>
</template>

<script setup lang="ts">
import { useAuthStore } from "@/stores/auth"
const auth = useAuthStore()
</script>
</template>

<script setup lang="ts">
import { ref, watch } from "vue"
import { useAuthStore } from "@/stores/auth"
import axios from "axios"
import useEventBus from "@/eventbus"
const auth = useAuthStore()
const bus = useEventBus() // Event bus instance
// Reactive state variables
const logic = ref("cid") // Default logic set to 'cid'
const pos1 = ref("")
const pos2 = ref("")
const useVatsimCid = ref(true) // Default checkbox state is checked
const manualCid1 = ref("")
const manualCid2 = ref("")
// Method to handle logic selection
const setLogic = (selectedLogic: string) => {
logic.value = selectedLogic
console.log(`Selected logic: ${selectedLogic}`)
// Reset relevant fields when logic changes
if (selectedLogic === "cid") {
useVatsimCid.value = true
manualCid1.value = ""
manualCid2.value = ""
} else if (selectedLogic === "position") {
pos1.value = ""
pos2.value = ""
}
}
// Method to handle checkbox change
const handleCidOption = () => {
if (useVatsimCid.value) {
manualCid1.value = ""
manualCid2.value = ""
}
}
// Method to apply the logic selection and emit the event
const applyLogic = () => {
let type = logic.value.toUpperCase()
let value = []
if (logic.value === "cid") {
if (useVatsimCid.value) {
// Use VATSIM CID from auth store
value = [auth.user.cid]
} else {
// Use manually entered CIDs
value = [manualCid1.value, manualCid2.value].filter(v => v)
}
} else if (logic.value === "position") {
// Use positions
value = [pos1.value, pos2.value].filter(v => v)
}
// Emit an event to notify PLSTimer.vue of the updated logic
bus.emit("logicChanged", { type, value })
console.log(`Logic applied: type=${type}, value=${value}`)
}
</script>

<style scoped>
.mt-3 {
margin-top: 1rem;
}
.mr-2 {
margin-right: 0.5rem;
}
h2 {
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
</style>

173 changes: 173 additions & 0 deletions frontend/src/components/PLSTimer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<template>
<div>
<span v-if="loading">-</span>
<span v-else-if="matchedControllers.length > 0">
( PLS: {{ sessionLength }} )
</span>
<span v-else>( PLS: NIL )</span>
</div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from "vue"
import axios from "axios"
import moment from "moment"
import useEventBus from "@/eventbus"
// Reactive data
const searchType = ref("CID") // Default to "CID"
const searchValue = ref([]) // Array of CIDs or positions to search for
const sessionLength = ref("00:00:00")
const matchedControllers = ref([])
const matchedGroup = ref("") // Tracks which group the matched controller belongs to
const loading = ref(true) // To track the loading state
let intervalId = null // To keep track of the setInterval ID
let refreshIntervalId = null // To keep track of the 10-second refresh interval
const bus = useEventBus() // Event bus instance
// Function to fetch and filter controllers
async function fetchSessionData() {
loading.value = true // Set loading to true when fetching data
try {
const response = await axios.get("http://localhost:3001/api/controllers")
const controllers = [
...response.data.activeControllers,
...response.data.availableControllers,
...response.data.awayControllers,
]
// Reset the matched group and controllers
matchedControllers.value = []
matchedGroup.value = ""
// Filter controllers based on selected CID or Position
if (searchType.value === "CID") {
// Check activeControllers
matchedControllers.value = response.data.activeControllers.filter(controller =>
searchValue.value.includes(controller.CID)
)
if (matchedControllers.value.length > 0) {
matchedGroup.value = "active"
} else {
// Check availableControllers if no match in active
matchedControllers.value = response.data.availableControllers.filter(controller =>
searchValue.value.includes(controller.CID)
)
if (matchedControllers.value.length > 0) {
matchedGroup.value = "available"
} else {
// Check awayControllers if no match in active or available
matchedControllers.value = response.data.awayControllers.filter(controller =>
searchValue.value.includes(controller.CID)
)
if (matchedControllers.value.length > 0) {
matchedGroup.value = "away"
}
}
}
} else {
// Check for position match in all controller groups
matchedControllers.value = response.data.activeControllers.filter(controller =>
searchValue.value.includes(controller.position)
)
if (matchedControllers.value.length > 0) {
matchedGroup.value = "active"
} else {
matchedControllers.value = response.data.availableControllers.filter(controller =>
searchValue.value.includes(controller.position)
)
if (matchedControllers.value.length > 0) {
matchedGroup.value = "available"
} else {
matchedControllers.value = response.data.awayControllers.filter(controller =>
searchValue.value.includes(controller.position)
)
if (matchedControllers.value.length > 0) {
matchedGroup.value = "away"
}
}
}
}
// Calculate the session length if a match is found
if (matchedControllers.value.length > 0) {
const timestamp = matchedControllers.value[0].timestamp
const sessionStart = moment(timestamp)
startUpdatingSessionLength(sessionStart)
} else {
sessionLength.value = "00:00:00"
clearInterval(intervalId)
}
} catch (error) {
console.error("Error fetching session data:", error)
} finally {
loading.value = false // Set loading to false after fetching data
}
}
// Function to start updating session length in real-time
function startUpdatingSessionLength(sessionStart) {
if (intervalId) {
clearInterval(intervalId) // Clear any existing interval before starting a new one
}
intervalId = setInterval(() => {
const now = moment()
const duration = moment.duration(now.diff(sessionStart))
let formattedTime = `${String(duration.hours()).padStart(2, "0")}:${String(
duration.minutes()
).padStart(2, "0")}:${String(duration.seconds()).padStart(2, "0")}`
// Append "P" or "Ö" depending on the matched group
if (matchedGroup.value === "available") {
formattedTime += " P"
} else if (matchedGroup.value === "away") {
formattedTime += " \u00D6" // Append Unicode character "Ö"
}
sessionLength.value = formattedTime
}, 1000)
}
// Function to set up auto-refresh every 10 seconds
function startAutoRefresh() {
if (refreshIntervalId) {
clearInterval(refreshIntervalId) // Clear any existing refresh interval
}
refreshIntervalId = setInterval(() => {
fetchSessionData() // Refresh data every 10 seconds
}, 10000)
}
// Clear interval when component is unmounted
onBeforeUnmount(() => {
if (intervalId) {
clearInterval(intervalId)
}
if (refreshIntervalId) {
clearInterval(refreshIntervalId)
}
})
// Fetch data and start auto-refresh when component is mounted
onMounted(() => {
fetchSessionData() // Initial fetch
startAutoRefresh() // Start auto-refresh every 10 seconds
// Listen for the "refresh" event from the event bus
bus.on("refresh", () => {
fetchSessionData() // Fetch data immediately on refresh event
})
// Listen for logic change event from About.vue
bus.on("logicChanged", ({ type, value }) => {
searchType.value = type
searchValue.value = value
fetchSessionData() // Fetch data based on the new logic
})
})
</script>

Loading

0 comments on commit 5fe40c3

Please sign in to comment.