mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2025-01-18 22:00:35 +00:00
Remove asynch rework because it was already event driven
This commit is contained in:
parent
6b1f588f29
commit
25ea9ba583
@ -1,121 +1,169 @@
|
|||||||
|
/**
|
||||||
|
* This class is used to create an CorpusAnalysisClient object.
|
||||||
|
* The client handels the client server communication.
|
||||||
|
* It requests data (e.g. the analysis session or query results) from the
|
||||||
|
* the server and recieves them.
|
||||||
|
*/
|
||||||
class CorpusAnalysisClient {
|
class CorpusAnalysisClient {
|
||||||
constructor(corpusId, socket) {
|
constructor(corpusId, socket, logging=false) {
|
||||||
this.corpusId = corpusId;
|
this.corpusId = corpusId;
|
||||||
this.socket = socket;
|
|
||||||
this.displays = {};
|
this.displays = {};
|
||||||
|
this.logging = logging;
|
||||||
|
this.socket = socket;
|
||||||
|
this.socketEventListeners = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
setDisplay(type, display) {
|
// Registers one or more SocketEventListeners to the CorpusAnalysisClient.
|
||||||
this.displays[type] = display;
|
setSocketEventListeners(socketEventListeners) {
|
||||||
|
for (let listener of socketEventListeners) {
|
||||||
|
this.socketEventListeners[listener.type] = listener.listenerFunction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async initSession() {
|
loadListeners() {
|
||||||
let request = await this.requestSession();
|
for (let [type, listener] of Object.entries(this.socketEventListeners)) {
|
||||||
let recvieveSession = await this.recvieveSession();
|
listener(this);
|
||||||
console.log("corpus_analysis_init: Waiting for response"); // this happens inbetween the two functions above
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requestSession() { // should be private with ES2020
|
// Registers a CorpusAnalysisDisplay object to the CorpusAnalysisClient.
|
||||||
console.log("corpus_analysis_init: Emitting to server");
|
setDisplay(type, corpusAnalysisDisplay) {
|
||||||
|
this.displays[type] = corpusAnalysisDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Initializes the interactive corpus analysis session via socket.io.
|
||||||
|
// * This function uses helper functions.
|
||||||
|
// */
|
||||||
|
// initSession() {
|
||||||
|
// let request = this.requestSession();
|
||||||
|
// let recvieveSession = this.recvieveSession();
|
||||||
|
// console.info('corpus_analysis_init: Client waiting for response'); // this happens inbetween the two functions above
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests a corpus analysis session via socket.io.
|
||||||
|
* Opens a loading modal at the start of the request
|
||||||
|
* Should be a private method if ES2020 is finalized (Maybe?)
|
||||||
|
*/
|
||||||
|
requestSession() {
|
||||||
|
console.info('corpus_analysis_init: Client requesting session via',
|
||||||
|
'socket.emit');
|
||||||
if (this.displays.init != undefined) {
|
if (this.displays.init != undefined) {
|
||||||
this.displays.init.element.M_Modal.open();
|
this.displays.init.element.M_Modal.open();
|
||||||
this.displays.init.setVisibilityByStatus("waiting");
|
this.displays.init.setVisibilityByStatus('waiting');
|
||||||
}
|
}
|
||||||
return new Promise((resolve, reject) => {
|
this.socket.emit('corpus_analysis_init', this.corpusId);
|
||||||
this.socket.emit("corpus_analysis_init", this.corpusId);
|
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recvieveSession() { // should be private with ES2020
|
// /**
|
||||||
this.socket.on("corpus_analysis_init", (response) => {
|
// * Sends a query to the server and handles the response to that query.
|
||||||
console.log("corpus_analysis_init: Recieving response from server");
|
// * This function uses helper functions.
|
||||||
if (response.code === 200) {
|
// */
|
||||||
console.log("corpus_analysis_init: Initialization succeeded");
|
// query(queryStr) {
|
||||||
if (this.displays.init != undefined) {
|
// let requestQueryData = this.requestQueryData(queryStr);
|
||||||
this.displays.init.element.M_Modal.close();
|
// let recieveQueryProcessStatus = this.recieveQueryProcessStatus();
|
||||||
this.displays.init.setVisibilityByStatus("success");
|
// let recieveQueryData = this.recieveQueryData();
|
||||||
}
|
// console.info('corpus_analysis_query: Client waiting for query data'); // this happens inbetween the two functions above
|
||||||
} else {
|
// }
|
||||||
let errorText = `Error ${response.code} - ${response.msg}`;
|
|
||||||
if (this.displays.init.errorContainer != undefined) {
|
/**
|
||||||
this.displays.init.errorContainer.innerHTML = `<p class="red-text">` +
|
* Sends the query string to the server.
|
||||||
`<i class="material-icons tiny">error</i> ${errorText}</p>`;
|
* Should be a private method if ES2020 is finalized (Maybe?)
|
||||||
}
|
*/
|
||||||
if (this.displays.init != undefined) {
|
requestQueryData(queryStr) {
|
||||||
this.displays.init.setVisibilityByStatus("error");
|
console.info('corpus_analysis_query: Client requesting query data via',
|
||||||
}
|
'socket.emit for the query', queryStr);
|
||||||
console.error(`corpus_analysis_init: ${errorText}`);
|
// TODO: Display stuff
|
||||||
}
|
this.socket.emit('corpus_analysis_query', queryStr);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to create an CorpusAnalysisDisplay object.
|
||||||
|
* Input is one HTMLElement that can then be hidden or shown depending on
|
||||||
|
* its CSS classes.
|
||||||
|
*/
|
||||||
class CorpusAnalysisDisplay {
|
class CorpusAnalysisDisplay {
|
||||||
constructor(element) {
|
constructor(element) {
|
||||||
|
// with this function initalized modals can also be handeld
|
||||||
this.element = (() => {if (element instanceof HTMLElement) {
|
this.element = (() => {if (element instanceof HTMLElement) {
|
||||||
return element;
|
return element;
|
||||||
} else {
|
} else {
|
||||||
element = element["$el"][0];
|
element = element['$el'][0];
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
})(); // with this function modals can also be handeld
|
})();
|
||||||
this.errorContainer = element.querySelector(".error-container");
|
this.errorContainer = element.querySelector('.error-container');
|
||||||
this.showOnError = element.querySelectorAll(".show-on-error");
|
this.showOnError = element.querySelectorAll('.show-on-error');
|
||||||
this.showOnSuccess = element.querySelectorAll(".show-on-success");
|
this.showOnSuccess = element.querySelectorAll('.show-on-success');
|
||||||
this.showWhileWaiting = element.querySelectorAll(".show-while-waiting");
|
this.showWhileWaiting = element.querySelectorAll('.show-while-waiting');
|
||||||
this.hideOnComplete = element.querySelectorAll(".hide-on-complete")
|
this.hideOnComplete = element.querySelectorAll('.hide-on-complete')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Changes the visibility of its own
|
||||||
setVisibilityByStatus(status) {
|
setVisibilityByStatus(status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "error":
|
case 'error':
|
||||||
for (let element of this.showOnError) {
|
for (let element of this.showOnError) {
|
||||||
element.classList.remove("hide");
|
element.classList.remove('hide');
|
||||||
}
|
}
|
||||||
for (let element of this.showOnSuccess) {
|
for (let element of this.showOnSuccess) {
|
||||||
element.classList.add("hide");
|
element.classList.add('hide');
|
||||||
}
|
}
|
||||||
for (let element of this.showWhileWaiting) {
|
for (let element of this.showWhileWaiting) {
|
||||||
element.classList.add("hide");
|
element.classList.add('hide');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "success":
|
case 'success':
|
||||||
for (let element of this.showOnError) {
|
for (let element of this.showOnError) {
|
||||||
element.classList.add("hide");
|
element.classList.add('hide');
|
||||||
|
|
||||||
}
|
}
|
||||||
for (let element of this.showOnSuccess) {
|
for (let element of this.showOnSuccess) {
|
||||||
element.classList.remove("hide");
|
element.classList.remove('hide');
|
||||||
}
|
}
|
||||||
for (let element of this.showWhileWaiting) {
|
for (let element of this.showWhileWaiting) {
|
||||||
element.classList.add("hide");
|
element.classList.add('hide');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "waiting":
|
case 'waiting':
|
||||||
for (let element of this.showOnError) {
|
for (let element of this.showOnError) {
|
||||||
element.classList.add("hide");
|
element.classList.add('hide');
|
||||||
}
|
}
|
||||||
for (let element of this.showOnSuccess) {
|
for (let element of this.showOnSuccess) {
|
||||||
element.classList.add("hide");
|
element.classList.add('hide');
|
||||||
}
|
}
|
||||||
for (let element of this.showWhileWaiting) {
|
for (let element of this.showWhileWaiting) {
|
||||||
element.classList.remove("hide");
|
element.classList.remove('hide');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Hide all
|
// Hide all
|
||||||
for (let element of this.showOnError) {
|
for (let element of this.showOnError) {
|
||||||
element.classList.add("hide");
|
element.classList.add('hide');
|
||||||
}
|
}
|
||||||
for (let element of this.showOnSuccess) {
|
for (let element of this.showOnSuccess) {
|
||||||
element.classList.add("hide");
|
element.classList.add('hide');
|
||||||
}
|
}
|
||||||
for (let element of this.showWhileWaiting) {
|
for (let element of this.showWhileWaiting) {
|
||||||
element.classList.add("hide");
|
element.classList.add('hide');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {CorpusAnalysisClient, CorpusAnalysisDisplay};
|
/**
|
||||||
|
* This class is used to create an CorpusAnalysisDisplay object.
|
||||||
|
* Input is one HTMLElement that can then be hidden or shown depending on
|
||||||
|
* its CSS classes.
|
||||||
|
*/
|
||||||
|
class SocketEventListener {
|
||||||
|
constructor(type, listenerFunction) {
|
||||||
|
this.listenerFunction = listenerFunction;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// export both Classes from this module
|
||||||
|
export {CorpusAnalysisClient, CorpusAnalysisDisplay, SocketEventListener};
|
60
web/app/static/js/modules/nopaque.listenerFunctions.js
Normal file
60
web/app/static/js/modules/nopaque.listenerFunctions.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* Recieves a corpus analysis session via socket.io.
|
||||||
|
* Closes the loading modal that has been opend with requestSession at the
|
||||||
|
* start of the request.
|
||||||
|
*/
|
||||||
|
function recieveSession(client) {
|
||||||
|
client.socket.on('corpus_analysis_init', (response) => {
|
||||||
|
console.group('recieve session')
|
||||||
|
console.info('corpus_analysis_init: Client recieving session/or error',
|
||||||
|
'codes via socket.on');
|
||||||
|
if (response.code === 200) {
|
||||||
|
console.info('corpus_analysis_init: Initialization succeeded');
|
||||||
|
console.info(response);
|
||||||
|
console.groupEnd();
|
||||||
|
if (client.displays.init != undefined) {
|
||||||
|
client.displays.init.element.M_Modal.close();
|
||||||
|
client.displays.init.setVisibilityByStatus('success');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let errorText = `Error ${response.code} - ${response.msg}`;
|
||||||
|
if (client.displays.init.errorContainer != undefined) {
|
||||||
|
client.displays.init.errorContainer.innerHTML = `<p class="red-text">`
|
||||||
|
+ `<i class="material-icons tiny">error</i>${errorText}</p>`;
|
||||||
|
}
|
||||||
|
if (client.displays.init != undefined) {
|
||||||
|
client.displays.init.setVisibilityByStatus('error');
|
||||||
|
}
|
||||||
|
console.error(`corpus_analysis_init: ${errorText}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recieves the query process status before any actual results are being
|
||||||
|
* transmitted. So it recieves error codes if a query failed or
|
||||||
|
* was invalid etc.
|
||||||
|
*/
|
||||||
|
function recieveQueryStatus(client) {
|
||||||
|
client.socket.on('corpus_analysis_query', (response) => {
|
||||||
|
console.group('corpus_analysis_query: Client recieving query process',
|
||||||
|
'status via socket.on');
|
||||||
|
console.info(response);
|
||||||
|
console.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recieves the query data from the request and handles it.
|
||||||
|
*/
|
||||||
|
function recieveQueryData(client) {
|
||||||
|
client.socket.on('corpus_analysis_query_results', (response) => {
|
||||||
|
console.group('corpus_analysis_query_results: Client recieving query',
|
||||||
|
'data via socket.on');
|
||||||
|
console.info(response);
|
||||||
|
console.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// export listeners from this module
|
||||||
|
export {recieveSession, recieveQueryStatus, recieveQueryData};
|
@ -67,11 +67,20 @@
|
|||||||
|
|
||||||
<!-- import modules -->
|
<!-- import modules -->
|
||||||
<script type="module">
|
<script type="module">
|
||||||
// ### First Phase: document content is loaded and scripts are run ###
|
/**
|
||||||
|
* First Phase:
|
||||||
|
* document content is loaded and scripts are being imported and executed
|
||||||
|
*/
|
||||||
import {CorpusAnalysisClient,
|
import {CorpusAnalysisClient,
|
||||||
CorpusAnalysisDisplay} from "../../static/js/modules/nopaque.CorpusAnalysisClient.js";
|
CorpusAnalysisDisplay,
|
||||||
|
SocketEventListener} from '../../static/js/modules/nopaque.CorpusAnalysisClient.js';
|
||||||
|
import {recieveSession, recieveQueryStatus,
|
||||||
|
recieveQueryData} from '../../static/js/modules/nopaque.listenerFunctions.js'
|
||||||
|
|
||||||
// ### Second Phase: asynchronous and event-driven ###
|
/**
|
||||||
|
* Second Phase:
|
||||||
|
* Asynchronus and event driven code
|
||||||
|
*/
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
// init some modals
|
// init some modals
|
||||||
const initLoadingElement = document.getElementById("init-display");
|
const initLoadingElement = document.getElementById("init-display");
|
||||||
@ -81,12 +90,48 @@
|
|||||||
const initLoadingDisplay = new CorpusAnalysisDisplay(initLoadingModal);
|
const initLoadingDisplay = new CorpusAnalysisDisplay(initLoadingModal);
|
||||||
// set up CorpusAnalysisClient
|
// set up CorpusAnalysisClient
|
||||||
const client = new CorpusAnalysisClient({{ corpus_id }}, nopaque.socket);
|
const client = new CorpusAnalysisClient({{ corpus_id }}, nopaque.socket);
|
||||||
|
console.info("CorpusAnalysisClient created as client:", client);
|
||||||
// register display elements to client
|
// register display elements to client
|
||||||
client.setDisplay("init", initLoadingDisplay);
|
client.setDisplay("init", initLoadingDisplay);
|
||||||
|
// register listeners and load them
|
||||||
|
const listenForSession = new SocketEventListener('corpus_analysis_init',
|
||||||
|
recieveSession);
|
||||||
|
const listenForQueryStatus = new SocketEventListener('corpus_analysis_query',
|
||||||
|
recieveQueryStatus);
|
||||||
|
const listenForQueryData = new SocketEventListener('corpus_analysis_query_results',
|
||||||
|
recieveQueryData);
|
||||||
|
client.setSocketEventListeners([listenForSession, listenForQueryStatus,
|
||||||
|
listenForQueryData]);
|
||||||
|
client.loadListeners();
|
||||||
// Session initialization
|
// Session initialization
|
||||||
console.log("CorpusAnalysisClient created as client:", client);
|
client.requestSession();
|
||||||
client.initSession();
|
// send a query and recieve its answer data
|
||||||
|
let queryFormElement = document.getElementById("query-form");
|
||||||
|
queryFormElement.addEventListener("submit", (event) => {
|
||||||
|
try {
|
||||||
|
/**
|
||||||
|
* Selects first page of result list if pagination is already available
|
||||||
|
* from an query submitted before.
|
||||||
|
* This avoids confusion for the user e.g.: The user was on page 24
|
||||||
|
* reviewing the results and issues a new query. He would not see any
|
||||||
|
* results until the new results reach page 24 or he clicks on another
|
||||||
|
* valid result page element from the new pagination.
|
||||||
|
*/
|
||||||
|
let xpath = '//a[@class="page" and text()=1]';
|
||||||
|
let firstPageElement = document.evaluate(xpath,
|
||||||
|
document,
|
||||||
|
null,
|
||||||
|
XPathResult.FIRST_ORDERED_NODE_TYPE,
|
||||||
|
null).singleNodeValue;
|
||||||
|
firstPageElement.click();
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
// Prevent page from reloading on submit
|
||||||
|
event.preventDefault();
|
||||||
|
// Get query string and send query to server
|
||||||
|
// results.data.getQueryStr(queryFormElement);
|
||||||
|
client.requestQueryData('"this" []* "that" within 10 words;');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user