halaman-psikolog #1

Merged
Mahayoga merged 52 commits from halaman-psikolog into master 2026-07-06 12:37:30 +07:00
2 changed files with 229 additions and 128 deletions
Showing only changes of commit d88b961e4b - Show all commits

View File

@ -30,37 +30,10 @@
<ol> <ol>
<li><strong>Persiapan:</strong> Pastikan Tobii sudah terhubung dan berfungsi dengan baik.</li> <li><strong>Persiapan:</strong> Pastikan Tobii sudah terhubung dan berfungsi dengan baik.</li>
<li><strong>Penempatan:</strong> Tempatkan Tobii di posisi yang sesuai untuk mendeteksi gerakan mata dengan akurat.</li> <li><strong>Penempatan:</strong> Tempatkan Tobii di posisi yang sesuai untuk mendeteksi gerakan mata dengan akurat.</li>
<li><strong>Hubungkan Tobii:</strong> Hubungkan Tobii ke dalam web dengan menggunakan link API dibawah ini.</li> <li><strong>Hubungkan Tobii:</strong> Hubungkan Tobii ke dalam web dengan menggunakan aplikasi API, jika tidak terhubung, hubungi administrator.</li>
<li><strong>Hasil:</strong> Setelah menghubungkan ke web berhasil, akan muncul notifikasi bahwa Tobii telah terhubung.</li> <li><strong>Hasil:</strong> Setelah menghubungkan ke web berhasil, akan muncul notifikasi bahwa Tobii telah terhubung.</li>
<li><strong>Selanjutnya:</strong> Melakukan kalibrasi mata dengan Tobii.</li> <li><strong>Selanjutnya:</strong> Melakukan kalibrasi mata dengan Tobii.</li>
</ol> </ol>
<h5 class="">Link API Tobii:</h5>
<div class="row px-3">
<div class="col-md-11">
<input type="text" disabled id="link_api_tobii" class="input form-control mb-3" value="">
</div>
<div class="col-md-1 p-0">
<button class="btn btn-secondary" onclick="copyLinkApiTobii()">Copy</button>
</div>
</div>
<h5 class="">Link ID Tobii:</h5>
<div class="row px-3">
<div class="col-md-11">
<input type="text" disabled id="link_id_tobii" class="input form-control mb-3" value="">
</div>
<div class="col-md-1 p-0">
<button class="btn btn-secondary" onclick="copyLinkIdTobii()">Copy</button>
</div>
</div>
<h5 class="">Link Token Tobii:</h5>
<div class="row px-3">
<div class="col-md-11">
<input type="text" disabled id="link_token_tobii" class="input form-control mb-3" value="">
</div>
<div class="col-md-1 p-0">
<button class="btn btn-secondary" onclick="copyLinkTokenTobii()">Copy</button>
</div>
</div>
<p class="card-text mt-3" id="status_tobii">Memuat...</p> <p class="card-text mt-3" id="status_tobii">Memuat...</p>
<button class="btn btn-primary" id="back_btn" onclick="showTutorial(1, 'tutorial_2')">Back</button> <button class="btn btn-primary" id="back_btn" onclick="showTutorial(1, 'tutorial_2')">Back</button>
<button class="btn btn-primary" id="next_btn_connect_tobii" onclick="showTutorial(3, 'tutorial_2')">Next</button> <button class="btn btn-primary" id="next_btn_connect_tobii" onclick="showTutorial(3, 'tutorial_2')">Next</button>
@ -128,10 +101,79 @@
let getDataInterval = false; let getDataInterval = false;
let checkTobiiInterval = null; let checkTobiiInterval = null;
let tobiiConnectedStatus = false; let tobiiConnectedStatus = false;
const ws = new WebSocket('{{ env("WEBSOCKET_URL") }}'); let ws = null;
let reconnectDelay = 1000;
let maxReconnectDelay = 10000;
let SESSION_ID = '{{ $data_session->id_test_sessions }}'; let SESSION_ID = '{{ $data_session->id_test_sessions }}';
let TOKEN_SESSION = '{{ $data_session->token_session }}'; let TOKEN_SESSION = '{{ $data_session->token_session }}';
function startWebsocket() {
console.log("Connecting to WebSocket...");
ws = new WebSocket('{{ env("WEBSOCKET_URL") }}');
ws.onopen = () => {
console.log("Connected to WebSocket");
reconnectDelay = 1000;
ws.send(JSON.stringify({
type: "register",
session_id: SESSION_ID,
token_session: TOKEN_SESSION,
role: "web"
}));
searchingTobiiDevice();
ws.send(JSON.stringify({
type: "update_status",
status_sessions: false,
id_session: SESSION_ID
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Received data from WebSocket:', data);
if(data.type === 'tobii_data') {
try {
moveTheEye(data.gaze_x, data.gaze_y);
} catch(error) {
console.log(error);
}
}
if(data.type === 'status_tobii_device') {
if(data.status) {
console.log('Tobii device is connected');
tobiiConnectedStatus = true;
} else {
console.log('Tobii device is not connected');
tobiiConnectedStatus = false;
searchingTobiiDevice();
}
checkTobiiConnection();
}
if(data.type === 'reset_start_tobii') {
startTobii();
}
};
ws.onerror = function (error) {
console.log("WebSocket error");
};
ws.onclose = function () {
setTimeout(() => {
reconnectDelay = Math.min(
reconnectDelay * 2,
maxReconnectDelay
);
console.log("Disconnected from WebSocket. Retrying in " + reconnectDelay + " ms...");
startWebsocket();
}, reconnectDelay);
};
}
function showTutorial(step, tutorialId) { function showTutorial(step, tutorialId) {
$(`#${tutorialId}`).hide(); $(`#${tutorialId}`).hide();
$(`#tutorial_${step}`).show(); $(`#tutorial_${step}`).show();
@ -297,6 +339,39 @@ function checkTobiiConnection() {
} }
} }
async function searchingTobiiDevice() {
try {
console.log('Searching for tobii...');
const response = await fetch('{{ env('TOBII_API_URL') }}', {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
session_id: SESSION_ID,
token: TOKEN_SESSION,
url: "{{ env('WEBSOCKET_URL') }}"
})
}
);
if (!response.ok) {
console.error('Failed to get tobii device, retrying...');
setTimeout(5000);
searchingTobiiDevice();
return;
}
const data = await response.json();
if(data.session_id == SESSION_ID && data.token == TOKEN_SESSION) {
tobiiConnectedStatus = true;
console.log('Done searching...');
}
} catch (error) {
console.error('Error getting Tobii device:', error);
setTimeout(5000);
searchingTobiiDevice();
}
}
function startTobii() { function startTobii() {
ws.send(JSON.stringify({ ws.send(JSON.stringify({
type: "command", type: "command",
@ -320,50 +395,8 @@ function stopTobii() {
$('#calibration_point').hide(); $('#calibration_point').hide();
$('#show_calibration').hide(); $('#show_calibration').hide();
generateLinkApiTobii(); generateLinkApiTobii();
startWebsocket();
ws.onopen = () => { console.log("hehehehehehehehehhehehe");
console.log("Connected to WebSocket");
ws.send(JSON.stringify({
type: "register",
session_id: SESSION_ID,
token_session: TOKEN_SESSION,
role: "web"
}));
ws.send(JSON.stringify({
type: "update_status",
status_sessions: false,
id_session: SESSION_ID
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Received data from WebSocket:', data);
if(data.type === 'tobii_data') {
try {
moveTheEye(data.gaze_x, data.gaze_y);
} catch(error) {
console.log(error);
}
}
if(data.type === 'status_tobii_device') {
if(data.status) {
console.log('Tobii device is connected');
tobiiConnectedStatus = true;
} else {
console.log('Tobii device is not connected');
tobiiConnectedStatus = false;
}
checkTobiiConnection();
}
if(data.type === 'reset_start_tobii') {
startTobii();
}
};
}); });
</script> </script>

View File

@ -70,7 +70,9 @@
@section('script') @section('script')
<script> <script>
const ws = new WebSocket('{{ env("WEBSOCKET_URL") }}'); let ws = null;
let reconnectDelay = 1000;
let maxReconnectDelay = 10000;
const SESSION_ID = '{{ $data_session->id_test_sessions }}'; const SESSION_ID = '{{ $data_session->id_test_sessions }}';
const TOKEN_SESSION = '{{ $data_session->token_session }}'; const TOKEN_SESSION = '{{ $data_session->token_session }}';
let UNIX_END_TIME = null; let UNIX_END_TIME = null;
@ -79,6 +81,119 @@
let CURRENT_BTN = null; let CURRENT_BTN = null;
let CAPTION_BTN = null; let CAPTION_BTN = null;
function startWebsocket() {
console.log("Connecting to WebSocket...");
ws = new WebSocket('{{ env("WEBSOCKET_URL") }}');
ws.onopen = () => {
console.log("Connected to WebSocket");
ws.send(JSON.stringify({
type: "register",
session_id: SESSION_ID,
token_session: TOKEN_SESSION,
role: "web"
}));
document.addEventListener('fullscreenchange', checkFullscreen);
ws.send(JSON.stringify({
type: "update_status",
status_sessions: true,
session_id: SESSION_ID
}));
searchingTobiiDevice()
checkFullscreen();
getTimeLeft();
setInterval(updateTimeLeft, 1000);
getNavigationField();
setCurrentNavigation();
fetchQuestion(QUESTION_INDEX);
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if(data.type === 'reset_start_tobii') {
startTobii();
}
if(data.type === 'status_tobii_device') {
if(data.status) {
// console.log('Tobii device is connected');
// document.getElementById('status_tobii_device').innerText = 'Connected';
document.getElementById('bg_status_tobii').classList.remove('bg-warning');
document.getElementById('bg_status_tobii').classList.remove('bg-danger');
document.getElementById('bg_status_tobii').classList.add('bg-success');
} else {
console.log('Tobii device is not connected');
searchingTobiiDevice();
// document.getElementById('status_tobii_device').innerText = 'Not Connected';
document.getElementById('bg_status_tobii').classList.remove('bg-success');
document.getElementById('bg_status_tobii').classList.remove('bg-warning');
document.getElementById('bg_status_tobii').classList.add('bg-danger');
}
}
};
ws.onerror = function (error) {
console.log("WebSocket error");
};
ws.onclose = function () {
setTimeout(() => {
reconnectDelay = Math.min(
reconnectDelay * 2,
maxReconnectDelay
);
console.log("Disconnected from WebSocket. Retrying in " + reconnectDelay + " ms...");
document.getElementById('bg_status_tobii').classList.remove('bg-success');
document.getElementById('bg_status_tobii').classList.remove('bg-warning');
document.getElementById('bg_status_tobii').classList.add('bg-danger');
startWebsocket();
}, reconnectDelay);
};
}
async function searchingTobiiDevice() {
try {
console.log('Searching for tobii...');
const response = await fetch('{{ env('TOBII_API_URL') }}', {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
session_id: SESSION_ID,
token: TOKEN_SESSION,
url: "{{ env('WEBSOCKET_URL') }}"
})
}
);
if (!response.ok) {
console.error('Failed to get tobii device, retrying...');
setTimeout(5000);
searchingTobiiDevice();
return;
}
const data = await response.json();
if(data.session_id == SESSION_ID && data.token == TOKEN_SESSION) {
// tobiiConnectedStatus = true;
startTobii();
document.getElementById('bg_status_tobii').classList.remove('bg-success');
document.getElementById('bg_status_tobii').classList.remove('bg-warning');
document.getElementById('bg_status_tobii').classList.add('bg-danger');
console.log('Done searching...');
}
} catch (error) {
console.error('Error getting Tobii device:', error);
document.getElementById('bg_status_tobii').classList.remove('bg-success');
document.getElementById('bg_status_tobii').classList.remove('bg-warning');
document.getElementById('bg_status_tobii').classList.add('bg-danger');
setTimeout(5000);
searchingTobiiDevice();
}
}
function changeQuestion(num) { function changeQuestion(num) {
Swal.showLoading(); Swal.showLoading();
@ -106,15 +221,13 @@ function changeQuestion(num) {
formData.append('question', num); formData.append('question', num);
formData.append('id_question', QUESTION_ID); formData.append('id_question', QUESTION_ID);
formData.append('session_id', SESSION_ID); formData.append('session_id', SESSION_ID);
xhttp.open("POST", "{{ route('ujian.store') }}", false); xhttp.open("POST", "{{ route('ujian.store') }}", true);
xhttp.send(formData); xhttp.send(formData);
} }
// stopTobii(); // stopTobii();
QUESTION_INDEX = num; QUESTION_INDEX = num;
getNavigationField(); getNavigationField();
setCurrentNavigation();
fetchQuestion(QUESTION_INDEX); fetchQuestion(QUESTION_INDEX);
Swal.close();
} }
function setCurrentNavigation() { function setCurrentNavigation() {
@ -144,7 +257,7 @@ function fetchQuestion(question_index) {
} }
} }
xhttp.open("GET", "{{ route('ujian.fetchQuestion') }}?session_id=" + SESSION_ID + "&question_index=" + question_index, false); xhttp.open("GET", "{{ route('ujian.fetchQuestion') }}?session_id=" + SESSION_ID + "&question_index=" + question_index, true);
xhttp.send(); xhttp.send();
} }
@ -232,6 +345,8 @@ function getCurrentAnswer(id_question) {
} }
}); });
} }
Swal.close();
checkFullscreen();
} }
} }
}; };
@ -282,11 +397,12 @@ function getNavigationField() {
} }
} }
$('#navigation_field').html(navigation_field); $('#navigation_field').html(navigation_field);
setCurrentNavigation();
} }
} }
}; };
xhttp.open('GET', '{{ route('ujian.navigationField') }}?session_id=' + SESSION_ID, false); xhttp.open('GET', '{{ route('ujian.navigationField') }}?session_id=' + SESSION_ID, true);
xhttp.send(); xhttp.send();
} }
@ -385,55 +501,7 @@ function checkFullscreen() {
} }
$(document).ready(function() { $(document).ready(function() {
ws.onopen = () => { startWebsocket();
console.log("Connected to WebSocket");
ws.send(JSON.stringify({
type: "register",
session_id: SESSION_ID,
token_session: TOKEN_SESSION,
role: "web"
}));
document.addEventListener('fullscreenchange', checkFullscreen);
ws.send(JSON.stringify({
type: "update_status",
status_sessions: true,
session_id: SESSION_ID
}));
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if(data.type === 'reset_start_tobii') {
startTobii();
}
if(data.type === 'status_tobii_device') {
if(data.status) {
console.log('Tobii device is connected');
// document.getElementById('status_tobii_device').innerText = 'Connected';
document.getElementById('bg_status_tobii').classList.remove('bg-warning');
document.getElementById('bg_status_tobii').classList.remove('bg-danger');
document.getElementById('bg_status_tobii').classList.add('bg-success');
} else {
console.log('Tobii device is not connected');
// document.getElementById('status_tobii_device').innerText = 'Not Connected';
document.getElementById('bg_status_tobii').classList.remove('bg-success');
document.getElementById('bg_status_tobii').classList.remove('bg-warning');
document.getElementById('bg_status_tobii').classList.add('bg-danger');
}
}
};
startTobii();
checkFullscreen();
getTimeLeft();
setInterval(updateTimeLeft, 1000);
getNavigationField();
setCurrentNavigation();
fetchQuestion(QUESTION_INDEX);
};
}); });
</script> </script>
@endsection @endsection