App.js 5.81 KB
import React, {Fragment, useRef, useEffect, useState} from "react";
import * as tf from "@tensorflow/tfjs";
import * as qna from "@tensorflow-models/qna";
import "react-loader-spinner/dist/loader/css/react-spinner-loader.css";
import Loader from "react-loader-spinner";
import "./App.css";
import {paragraph} from "./passage";

function App() {

  // setup references, states
  //const passageRef = useRef(null);
  const questionRef = useRef(null);
  const [answer, setAnswer] = useState();
  const [model, setModel] = useState(null);

  // load tensorflow models
  const loadModel = async () => {
    const loadedModel = await qna.load();
    setModel(loadedModel);
    console.log("Model is loaded");
  }

  useEffect(() => { loadModel() }, []);

  // define question function
  const answerQuestion = async (e) => {
    if (e.which === 13 && model !== null) { // if key is enter
      console.log("Question Submitted.");
      const passage = paragraph;
      const question = questionRef.current.value;

      const answers = await model.findAnswers(question, passage);
      setAnswer(answers);
      console.log(answers);
    }
  }

  return (
      <div className="App">
        <header className="App-header">
          {model == null? // if model isn't loaded, react loader spinner will be upload in browser
            <div>
              <div>Model Loading</div>
              <Loader
                type="Puff"
                color="#00BFFF"
                height={100}
                width={100}
              />
            </div>
              : // if model is loaded, passage and answer will be shown in browser
              <Fragment>
                Ask a Question
                <input ref={questionRef} onKeyPress={answerQuestion} size="80"/>
                Answers
                {answer ? answer.map((ans, idx) => <div><b>Answer {idx + 1} - </b> {ans.text} </div>) : " : Can't Find any answers !"}
              </Fragment>
          }
        </header>
      </div>
  );
}

export default App;


/*
//import AppSearchAPIConnector from "@elastic/search-ui-app-search-connector";
import { Client } from "@elastic/elasticsearch";
 */
/*
import {
    SearchProvider,
    Results,
    SearchBox,
    PagingInfo,
    ResultsPerPage,
    Paging,
    Facet,
    Sorting
} from "@elastic/react-search-ui";
import { Layout } from "@elastic/react-search-ui-views";
*/
/*
import "@elastic/react-search-ui-views/lib/styles/styles.css";
import './App.css';
*/
/*
const connector = new AppSearchAPIConnector({
  searchKey: "search-4td7gan5kcasgygjcyexksrz",
  engineName: "video-games",
    endpointBase: "http://localhost:3002"
});
 */

/*
const client = new Client({
    node: "http://localhost:9200"
})

console.log(client);
*/
/*
const configurationOptions = { // search 쿼리와 api 연결선을 작성한 객체
    apiConnector: client,
    searchQuery: {
        search_fields: {
            name: {}
        },
        result_fields: {
            name: {
                snippet: {
                    size: 75
                }
            },
            genre: {
                snippet: {
                    size: 50,
                    fallback: true
                }
            },
            publisher: {
                snippet: {
                    size: 50,
                    fallback: true
                }
            },
            critic_score: {
                raw: {}
            },
            user_score: {
                raw: {}
            },
            platform: {
                snippet: {
                    size: 50,
                    fallback: true
                }
            },
            image_url: {
                raw: {}
            }
        },
        facets: {
            user_score: {
                type: "range",
                ranges: [
                    { from: 0, to: 5, name: "Not good" },
                    { from: 5, to: 7, name: "Not bad" },
                    { from: 7, to: 9, name: "Pretty good" },
                    { from: 9, to: 10, name: "Must play!" }
                ]
            },
            critic_score: {
                type: "range",
                ranges: [
                    { from: 0, to: 50, name: "Not good" },
                    { from: 50, to: 70, name: "Not bad" },
                    { from: 70, to: 90, name: "Pretty good" },
                    { from: 90, to: 100, name: "Must play!" }
                ]
            },
            genre: { type: "value", size: 100 },
            publisher: { type: "value", size: 100},
            platform: { type: "value", size: 100}
        }
    },
    autocompleteQuery: {
        suggestions: {
            types: {
                documents: {
                    fields: ["name"]
                }
            },
            size: 5
        }
    }
};
*/

/* <SearchProvider config={configurationOptions}>
  <div className="App">
      <Layout
          header={<SearchBox autocompleteSuggestions={true} />}
          bodyContent={<Results titleField="name" urlField="image_url"/>}
          sideContent={
              <div>
                  <Sorting
                      label={"Sort by"}
                      sortOptions={[
                          {
                              name: "Relevance",
                              value: "",
                              direction: ""
                          },
                          {
                              name: "Name",
                              value: "name",
                              direction: "asc"
                          }
                      ]}
                  />
                  <Facet field="user_score" label="User Score" />
              </div>
          }
          bodyHeader={
              <>
                  <PagingInfo />
                  <ResultsPerPage />
              </>
          }
          bodyFooter={<Paging />}
      />

  </div>
</SearchProvider>
*/