HOTFIX - Fixed isssue with bugged merge
This commit is contained in:
parent
e045ba264d
commit
9901ec2c39
|
|
@ -1,34 +0,0 @@
|
||||||
import React, { useState } from 'react';
|
|
||||||
import Article from './Article';
|
|
||||||
import "./css/ArticleEditor.css";
|
|
||||||
|
|
||||||
const ArticleEditor = (props) => {
|
|
||||||
const [content, setContent] = useState("Hello World");
|
|
||||||
|
|
||||||
let article = {
|
|
||||||
"id":"0",
|
|
||||||
"title": "Article Editor",
|
|
||||||
"desc":"This is a place to edit articles",
|
|
||||||
"contents": content
|
|
||||||
};
|
|
||||||
|
|
||||||
let copyToClipboard = () => {
|
|
||||||
navigator.clipboard.writeText(content).then(function() {
|
|
||||||
console.log('Async: Copying to clipboard was successful!');
|
|
||||||
}, function(err) {
|
|
||||||
console.error('Async: Could not copy text: ', err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="ArticleEditor">
|
|
||||||
<div id="toolbar" className="toolbar">
|
|
||||||
<div className="btn" onClick={copyToClipboard()}>Copy to Clipboard</div>
|
|
||||||
</div>
|
|
||||||
<Article article={article}/>
|
|
||||||
<textarea onInput={e=>{setContent(e.target.value)}}></textarea>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ArticleEditor;
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import {downloadModel, loadingModel, predict, error_msg} from '../actions'
|
|
||||||
import ProgressBar from "./subcomponents/ProgressBar";
|
|
||||||
//import { Link } from 'react-router-dom';
|
|
||||||
import './css/Bai.css';
|
|
||||||
|
|
||||||
|
|
||||||
class Bai extends React.Component {
|
|
||||||
/**
|
|
||||||
* Blank AI - Artificial Intelligence designed to distinguish photos of blank vs. non-blank paper scans
|
|
||||||
*/
|
|
||||||
|
|
||||||
classes = {0: "Blank", 1: "Not Blank"}
|
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
document.title = "Blank AI";
|
|
||||||
}
|
|
||||||
|
|
||||||
extExtractor (filename) {
|
|
||||||
let name = filename.split('.');
|
|
||||||
let ext = name[name.length-1];
|
|
||||||
return ext
|
|
||||||
}
|
|
||||||
|
|
||||||
async fileUpload (target, predict) {
|
|
||||||
|
|
||||||
const [file] = target.files;
|
|
||||||
|
|
||||||
let image = document.getElementById("preview")
|
|
||||||
|
|
||||||
let image_ext = ['jpg', 'png'];
|
|
||||||
|
|
||||||
let file_ext = await this.extExtractor(file.name);
|
|
||||||
|
|
||||||
if (file && image_ext.includes(file_ext)) {
|
|
||||||
|
|
||||||
let imageBM = await createImageBitmap(file);
|
|
||||||
|
|
||||||
let prediction = await predict(imageBM);
|
|
||||||
|
|
||||||
console.log(this.declassify(prediction[0]));
|
|
||||||
|
|
||||||
image.src = await URL.createObjectURL(file);
|
|
||||||
image.classList.add('show');
|
|
||||||
} else {
|
|
||||||
this.props.error_msg('Please pass JPG or PNG file Only');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declassify(prediction) {
|
|
||||||
if (prediction > 0.5) {
|
|
||||||
return this.classes[1];
|
|
||||||
} else {
|
|
||||||
return this.classes[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
let content = (this.props.model === null)?
|
|
||||||
(
|
|
||||||
<div className="content">
|
|
||||||
<h1>Would you like to download the model?</h1>
|
|
||||||
<p>By clicking Accept below, you will download the model which may be between 100 mb in size to 1 gb.</p>
|
|
||||||
<button className={`btn ${this.props.loading?"hide":""}`} onClick={()=>{this.props.loadingModel();this.props.downloadModel()}}>Accept Download</button>
|
|
||||||
<h2>{this.props.loading}</h2>
|
|
||||||
<ProgressBar progress={this.props.downloadProgress}/>
|
|
||||||
<h2>{this.props.loading?this.props.downloadProgress+"%":""}</h2>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
:(
|
|
||||||
<div className="content">
|
|
||||||
<h1>BAI Model Prediction</h1>
|
|
||||||
|
|
||||||
<p className="prediction">{this.props.last_prediction ? this.declassify(this.props.last_prediction[0]):"Waiting for Prediction"}</p>
|
|
||||||
|
|
||||||
<div className={"error " + (this.props.error?'enable':'')}>
|
|
||||||
{this.props.error}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<img id="preview" alt="preview of predicted file"/>
|
|
||||||
|
|
||||||
<input type='file' id="fileSubmit" onChange={({target}) => this.fileUpload(target, this.props.predict)} />
|
|
||||||
|
|
||||||
<button className='btn' onClick={()=>{document.getElementById('fileSubmit').click();}}>Upload Image</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="Bai">
|
|
||||||
{content}
|
|
||||||
<div className="about">
|
|
||||||
<h1>About</h1>
|
|
||||||
<p>
|
|
||||||
You can find the source, dataset and model created for BAI on github at
|
|
||||||
</p>
|
|
||||||
<a href="https://www.github.com/RaspberryProgramming/BAI"> https://www.github.com/RaspberryProgramming/BAI</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const mapStateToProps = (state) => {
|
|
||||||
return {model: state.model.model, loading: state.model.loading, last_prediction: state.model.last_prediction, downloadProgress: state.model.progress, error: state.model.error};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, {downloadModel, loadingModel, predict, error_msg})(Bai);
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
import React, { useState } from 'react';
|
|
||||||
import '../css/Buttons.css';
|
|
||||||
import { ArrowUpShort, ArrowDownShort } from 'react-bootstrap-icons';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Buttons - set of button components that are reusable throughout the app.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const ToggleButton = ({
|
|
||||||
defVal=true,
|
|
||||||
icons=[<ArrowUpShort/>, <ArrowDownShort/>],
|
|
||||||
text="",
|
|
||||||
clickAction=()=>{}
|
|
||||||
}) => {
|
|
||||||
/**
|
|
||||||
* ToggleButton - A button component for making a toggle button
|
|
||||||
* defVal: default value, true/false
|
|
||||||
* icons: array of two jsx values that are displayed depending on value
|
|
||||||
* text: text next to toggle button
|
|
||||||
* clickAction: function that will run when clicked. value is passed to this function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const [value, setValue] = useState(defVal);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="btn toggle" onClick={()=>{setValue(!value); clickAction(value);}} >
|
|
||||||
<div className={value?'on':'off'}> {icons[0]} </div>
|
|
||||||
<div className={value?'off':'on'}> {icons[1]} </div>
|
|
||||||
{text}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Button = ({children, onClick=()=>{}, href=null, className=""}) => {
|
|
||||||
if (href === null) {
|
|
||||||
return (
|
|
||||||
<button onClick={onClick} className={'btn '+ className}>
|
|
||||||
{children}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<a onClick={onClick} href={href} className={'btn '+className}>
|
|
||||||
{children}
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,210 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { getRepos, getUser, getRepoLanguages, nextPage, setSortValue } from '../../actions';
|
|
||||||
import { ToggleButton, Button } from './Buttons';
|
|
||||||
|
|
||||||
class GithubRepos extends React.Component {
|
|
||||||
|
|
||||||
perPage = 5;
|
|
||||||
sortOptions = [
|
|
||||||
// text: displayed text, value: value used for sorting
|
|
||||||
{text: "Created Date", value: "created_at"},
|
|
||||||
{text: "Last Pushed", value: "pushed_at"},
|
|
||||||
{text: "Name", value: "name"},
|
|
||||||
{text: "Number of Forks", value: "forks"},
|
|
||||||
{text: "Size", value: "size"},
|
|
||||||
{text: "Last Updated", value: "updated_at"},
|
|
||||||
];
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
|
|
||||||
document.title = "Github Repos";
|
|
||||||
|
|
||||||
if (!this.props.repos) {
|
|
||||||
|
|
||||||
this.props.getUser(this.props.username); // Receive the repos at start
|
|
||||||
this.props.getRepos(this.props.username); // Receive the repos at start
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
renderLanguages(name) {
|
|
||||||
this.props.getRepoLanguages(this.props.username, name);
|
|
||||||
|
|
||||||
// Given that we've already received the repo's languages
|
|
||||||
if (this.props.repoLanguages && this.props.repoLanguages[name]) {
|
|
||||||
|
|
||||||
// Create a bubble for each language
|
|
||||||
return Object.keys(this.props.repoLanguages[name]).map(language=>{
|
|
||||||
|
|
||||||
return <div className="language" key={language}>{language}</div>; // Language bubble JSX
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
roundUp(num) {
|
|
||||||
return num%1 === 0? num : num-(num%1)+1
|
|
||||||
}
|
|
||||||
|
|
||||||
objArrayBubbleSort(arr, value) {
|
|
||||||
/**
|
|
||||||
* arrayBubbleSort
|
|
||||||
*/
|
|
||||||
let unsorted;
|
|
||||||
let tmp;
|
|
||||||
|
|
||||||
do {
|
|
||||||
unsorted = false;
|
|
||||||
|
|
||||||
for (let i = 0; i < arr.length-1; i++) {
|
|
||||||
if (
|
|
||||||
(value.asc && arr[i][value.value] > arr[i+1][value.value]) // Ascending
|
|
||||||
|| (!value.asc && arr[i][value.value] < arr[i+1][value.value]) // Descending
|
|
||||||
) {
|
|
||||||
tmp = arr[i+1];
|
|
||||||
arr[i+1] = arr[i];
|
|
||||||
arr[i] = tmp;
|
|
||||||
|
|
||||||
unsorted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} while (unsorted);
|
|
||||||
|
|
||||||
return arr;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
renderRepos() {
|
|
||||||
|
|
||||||
if (this.props.repos) { // If the repos have been received
|
|
||||||
|
|
||||||
if (this.props.repos.length > 0) {
|
|
||||||
// Render each repo
|
|
||||||
let repos = this.props.single ? [this.props.repos[0]] : this.props.repos
|
|
||||||
|
|
||||||
let pages = this.roundUp(repos.length/this.perPage);
|
|
||||||
|
|
||||||
let sortedRepos = this.objArrayBubbleSort([...repos], this.props.sortedValue);
|
|
||||||
|
|
||||||
const render = sortedRepos.slice(0, this.props.page*this.perPage).map((repo) =>{
|
|
||||||
let updated = (new Date (repo.updated_at)).toLocaleString();
|
|
||||||
let created = (new Date (repo.created_at)).toLocaleString();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="repo" key={repo.id}>
|
|
||||||
|
|
||||||
<a href={repo.html_url} target="_blank" rel="noreferrer" className="title">{repo.name}</a>
|
|
||||||
|
|
||||||
<div className="content">
|
|
||||||
<p className="description">{repo.description ? repo.description : "No Description"}</p>
|
|
||||||
|
|
||||||
{
|
|
||||||
repo.homepage ? // If the repo has a homepage, render a button
|
|
||||||
<a href={repo.homepage} target="_blank" rel="noreferrer" className="website"> Project Website </a>:
|
|
||||||
""
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="languages">
|
|
||||||
Languages:
|
|
||||||
|
|
||||||
{
|
|
||||||
this.renderLanguages(repo.name) // Render each language for the repo
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div className="time">
|
|
||||||
Last Updated: {updated}
|
|
||||||
</div>
|
|
||||||
<div className="time">
|
|
||||||
Created: {created}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="repo-list">
|
|
||||||
<div className="sort-menu">
|
|
||||||
<div className="select-menu">
|
|
||||||
<p>Sort By: </p>
|
|
||||||
<select className="dropdown-list" onChange={v=>{
|
|
||||||
this.props.setSortValue({
|
|
||||||
...this.props.sortedValue,
|
|
||||||
value: v.target.value
|
|
||||||
});
|
|
||||||
}}>
|
|
||||||
{
|
|
||||||
this.sortOptions.map(option=>{
|
|
||||||
return (
|
|
||||||
<option
|
|
||||||
value={option.value}
|
|
||||||
key={option.value}
|
|
||||||
selected={option.value === this.props.sortedValue.value}
|
|
||||||
>
|
|
||||||
{option.text}
|
|
||||||
</option>);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
 
|
|
||||||
<ToggleButton defVal={false} clickAction={(val)=>{
|
|
||||||
console.warn(val);
|
|
||||||
this.props.setSortValue({
|
|
||||||
...this.props.sortedValue,
|
|
||||||
asc: val
|
|
||||||
});
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{render}
|
|
||||||
|
|
||||||
{this.props.page < pages ?
|
|
||||||
<Button className="mar-la mar-ra" onClick={()=>this.props.nextPage()}>Load More ({this.props.page}/{pages})</Button>
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
); // display the repo list with the rendered repos
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return <div className="loading">User doesn't have any repositories</div>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return nothing if repos haven't been received
|
|
||||||
|
|
||||||
return <div className="loading"> Loading Repositories... </div>; // Return nothing if repos haven't been collected
|
|
||||||
}
|
|
||||||
|
|
||||||
render = () => {
|
|
||||||
return (<div>{this.renderRepos()}</div>);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
|
||||||
return {
|
|
||||||
repos: state.github.repos,
|
|
||||||
repoLanguages: state.github.repoLanguages,
|
|
||||||
page: state.github.page,
|
|
||||||
sortedValue: state.github.sortedValue
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, {
|
|
||||||
getRepos,
|
|
||||||
getRepoLanguages,
|
|
||||||
getUser,
|
|
||||||
nextPage,
|
|
||||||
setSortValue
|
|
||||||
})(GithubRepos);
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import '../css/Listing.css';
|
|
||||||
|
|
||||||
const Listing = (props) => {
|
|
||||||
/**
|
|
||||||
* Listing - A subcomponent for making lists of content, mostly to make a list of links.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* title - The title of the listing
|
|
||||||
* children - JSX that is necessary in the content of the component
|
|
||||||
*/
|
|
||||||
return (
|
|
||||||
<div className="listing">
|
|
||||||
<Link to={props.link}>
|
|
||||||
<div className="title">{props.title}</div>
|
|
||||||
<div className="content">
|
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Listing;
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import '../css/ProgressBar.css';
|
|
||||||
|
|
||||||
class ProgressBar extends React.Component {
|
|
||||||
render () {
|
|
||||||
let pg = document.getElementById("ProgressBar");
|
|
||||||
|
|
||||||
let width = 0;
|
|
||||||
|
|
||||||
if (pg !== null) {
|
|
||||||
|
|
||||||
width = pg.offsetWidth*(this.props.progress/100);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="ProgressBar" id="ProgressBar">
|
|
||||||
<div style={{width:width+"px"}} className="Bar"></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProgressBar;
|
|
||||||
Loading…
Reference in New Issue