Skip to content

Instantly share code, notes, and snippets.

@manujosephv
Created November 26, 2020 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manujosephv/e2beb755de858bcc906ef17a3e2cee59 to your computer and use it in GitHub Desktop.
Save manujosephv/e2beb755de858bcc906ef17a3e2cee59 to your computer and use it in GitHub Desktop.
import React, { useEffect } from "react";
import LinearProgress from "@material-ui/core/LinearProgress";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Slider from "@material-ui/core/Slider";
import Backdrop from "@material-ui/core/Backdrop";
import SettingsIcon from "@material-ui/icons/Settings";
import Tooltip from "@material-ui/core/Tooltip";
import Link from "@material-ui/core/Link";
import Paper from "@material-ui/core/Paper";
import Box from "@material-ui/core/Box";
import Grid from "@material-ui/core/Grid";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import Collapse from "@material-ui/core/Collapse";
import ExpandLess from "@material-ui/icons/ExpandLess";
import ExpandMore from "@material-ui/icons/ExpandMore";
import axios from "axios";
import Typography from "@material-ui/core/Typography";
import InputLabel from "@material-ui/core/InputLabel";
import FormControl from "@material-ui/core/FormControl";
import clsx from "clsx";
import CircularProgress from "@material-ui/core/CircularProgress";
import Radio from "@material-ui/core/Radio";
import { green } from "@material-ui/core/colors";
import OutlinedInput from "@material-ui/core/OutlinedInput";
import IconButton from "@material-ui/core/IconButton";
import RadioGroup from "@material-ui/core/RadioGroup";
import FormLabel from "@material-ui/core/FormLabel";
import ShuffleIcon from "@material-ui/icons/Shuffle";
import InputAdornment from "@material-ui/core/InputAdornment";
import { makeStyles, withStyles } from "@material-ui/core/styles";
import CustomizedRatings from "./customRatings";
import LinkedInIcon from "@material-ui/icons/LinkedIn";
import TwitterIcon from "@material-ui/icons/Twitter";
import LanguageIcon from "@material-ui/icons/Language";
import "./quotes.css";
function Copyright() {
return (
<Grid container justify="center">
<Grid xs={12}>
<Typography variant="body2" color="textSecondary" align="center">
{"Made with "}
<span style={{ color: "#FE251B" }}>❤</span> {"Manu Joseph"}{" "}
{new Date().getFullYear()}
{"."}
</Typography>
</Grid>
<Grid xs={12} align="center">
<Link color="inherit" href="https://www.linkedin.com/in/manujosephv/">
<LinkedInIcon fontSize="small" />
</Link>
<Link color="inherit" href="https://twitter.com/manujosephv">
<TwitterIcon fontSize="small" />
</Link>
<Link color="inherit" href="https://deep-and-shallow.com/">
<LanguageIcon fontSize="small" />
</Link>
</Grid>
</Grid>
);
}
const LargeTooltip = withStyles((theme) => ({
tooltip: {
// backgroundColor: theme.palette.common.white,
// color: 'rgba(0, 0, 0, 0.87)',
boxShadow: theme.shadows[1],
fontSize: 14,
},
}))(Tooltip);
const useStyles = makeStyles((theme) => ({
root: {
height: "100vh",
},
image: {
backgroundRepeat: "no-repeat",
backgroundColor:
theme.palette.type === "light"
? theme.palette.grey[50]
: theme.palette.grey[900],
backgroundSize: "cover",
backgroundPosition: "center",
},
paper: {
margin: theme.spacing(8, 4),
display: "flex",
flexDirection: "column",
alignItems: "center",
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing(5),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
margin: {
margin: theme.spacing(1),
},
formControl: {
width: "100%",
},
textField: {
// width: '25ch',
},
slider: {
marginTop: "60px",
width: "90%",
// boxSizing: "border-box",
},
sliderLabel: {
marginTop: "5px",
},
buttonProgress: {
color: green[500],
position: "absolute",
top: "50%",
left: "50%",
marginTop: -12,
marginLeft: -12,
},
starRating: {
position: "absolute",
top: "85%",
background: ":rgba(0,0,0,0.6)",
borderRadius: "5px",
},
backdrop: {
zIndex: theme.zIndex.drawer + 1,
color: "#fff",
},
progressModel: {
width: "50%",
"& > * + *": {
marginTop: theme.spacing(2),
},
},
}));
export default function QuotesGenerator() {
const api_key = process.env.REACT_APP_API_KEY;
const api = process.env.REACT_APP_API_ENDPOINT;
const unsplashApi = "https://api.unsplash.com/photos/random";
const persona = {
serious: {
name: "AristoBot",
description:
"I am a wise old fool who ponders about Philosophy, Religion, Life and Death to uncover deep truths of the universe.",
image_search: ["universe", "life", "philosophy"],
},
motivational: {
name: "InspiratoBot",
description:
"I see life in a flood of positivity. Happiness, Hope, and Love inspires me to chase after my dreams and acheive it",
image_search: ["life", "love", "hope"],
},
funny: {
name: "FunnyBot",
description:
"I just try to be funny, because humour is the best medicine to heal the world.",
image_search: ["funny", "laugh"],
},
};
const keys = [];
for (var k in persona) keys.push(k);
const classes = useStyles();
const [modelName, setModelName] = React.useState(
keys[Math.floor(Math.random() * keys.length)]
);
const [nextSeed, setNextSeed] = React.useState("");
const [genSeed, setGenSeed] = React.useState("");
const [bgImage, setBgImage] = React.useState("");
const [quote, setQuote] = React.useState("");
const [author, setAuthor] = React.useState("");
const [open, setOpen] = React.useState(false);
const [loadingSeed, setLoadingSeed] = React.useState(false);
const [generatingQuote, setGeneratingQuote] = React.useState(false);
const [minLength, setMinLength] = React.useState(10);
const [maxLength, setMaxLength] = React.useState(100);
const [variety, setVariety] = React.useState(0.9);
const [modelLoading, setModelLoading] = React.useState(0.1);
const [rating, setRating] = React.useState(3);
// const ratingsRef = useRef()
const getRandomImage = () => {
axios
.get(unsplashApi, {
params: {
query:
persona[modelName]["image_search"][
Math.floor(
Math.random() * persona[modelName]["image_search"].length
)
],
featured: true,
orientation: "landscape",
client_id: "t5_pec0l_6ZliOm7IKWy_Hv0EzmDAxjXQK-V0Gc-A7k",
},
// paramsSerializer: params => {
// return qs.stringify(params)
// }
})
.then(function (response) {
console.log(response);
setBgImage(response["data"]["urls"]["regular"]);
})
.catch((error) => {
console.log(error.response);
setBgImage("https://source.unsplash.com/random");
});
};
useEffect(() => {
getRandomImage();
setModelLoading(true);
axios
.get(api + "/load_model/", {
params: {
key: api_key,
model_name: modelName,
},
})
.then(function (response) {
setModelLoading(false);
setGeneratingQuote(true);
axios
.get(api + "/complete_quote/", {
params: {
key: api_key,
model_name: modelName,
},
})
.then(function (response) {
console.log(response);
setQuote(response["data"]["quote"]);
setGenSeed(response["data"]["seed"]);
setAuthor(persona[modelName]["name"]);
setGeneratingQuote(false);
})
.catch((error) => {
console.log(error.response);
setQuote("Uh Oh! Something's wrong. Please come back later");
setGenSeed("");
setAuthor("AI Bot");
setGeneratingQuote(false);
});
})
.catch((error) => {
setModelLoading(false);
console.log("Model not Loaded");
console.log(error.response);
setQuote("Uh Oh! Something's wrong. Please come back later");
setGenSeed("");
setAuthor("AI Bot");
});
axios
.get(api + "/generate_seed/", {
params: {
key: api_key,
model_name: modelName,
},
})
.then(function (response) {
console.log(response);
setNextSeed(response["data"]);
})
.catch((error) => {
console.log(error.response);
});
}, []);
const handleAdvancedSettings = () => {
setOpen(!open);
};
const handleModelNameChange = (event) => {
setModelName(event.target.value);
console.log("Loading " + event.target.value);
setModelLoading(true);
axios
.get(api + "/load_model/", {
params: {
key: api_key,
model_name: event.target.value,
},
})
.then(function (response) {
setModelLoading(false);
console.log("success");
})
.catch((error) => {
console.log("Model not Loaded");
console.log(error.response);
setQuote("Uh Oh! Something's wrong. Please come back later");
setGenSeed("");
setAuthor("AI Bot");
});
};
const handleSeedChange = (event) => {
setNextSeed(event.target.value);
};
const handleSeedShuffle = (event) => {
setLoadingSeed(true);
axios
.get(api + "/generate_seed/", {
params: {
key: api_key,
model_name: modelName,
},
})
.then(function (response) {
console.log(response);
setNextSeed(response["data"]);
setLoadingSeed(false);
})
.catch((error) => {
console.log(error.response);
setLoadingSeed(false);
});
};
const handleSubmit = (event) => {
setGeneratingQuote(true);
getRandomImage();
setQuote("");
setAuthor("");
axios
.get(api + "/complete_quote/", {
params: {
key: api_key,
model_name: modelName,
seed: nextSeed === "" ? null : nextSeed,
max_words: maxLength,
min_words: minLength,
temperature: variety,
},
})
.then(function (response) {
console.log(response);
setQuote(response["data"]["quote"]);
setGenSeed(response["data"]["seed"]);
setAuthor(persona[modelName]["name"]);
// handleSeedShuffle()
setGeneratingQuote(false);
setRating(3);
// ratingsRef.current.resetRatings()
})
.catch((error) => {
console.log(error.response);
setQuote("Uh Oh! Something's wrong. Please come back later");
setAuthor("AI Bot");
setGeneratingQuote(false);
});
event.preventDefault();
};
const handleMinLength = (event, newValue) => {
setMinLength(newValue);
};
const handleMaxLength = (event, newValue) => {
setMaxLength(newValue);
};
const handleVariety = (event, newValue) => {
setVariety(newValue);
};
//saving prevous rating not current
const handleRatingsSubmit = (rating) => {
console.log(rating);
axios
.get(api + "/save_rating/", {
params: {
key: api_key,
model_name: modelName,
seed: genSeed,
rating: rating,
quote: quote,
},
// paramsSerializer: params => {
// return qs.stringify(params)
// }
})
.then(function (response) {
console.log(response);
})
.catch((error) => {
console.log(error.response);
});
};
// const bgImage = "https://source.unsplash.com/random"
return (
<Grid container component="main" className={classes.root}>
<CssBaseline />
{/* style={{background: "#f5f5f5"}} */}
<Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
<Backdrop className={classes.backdrop} open={modelLoading}>
<Typography variant="overline">Fetching {modelName}...</Typography>
<LinearProgress className={classes.progressModel} color="primary" />
</Backdrop>
<div className={classes.paper}>
<img src="/logo.png" style={{ width: "60%" }} alt="AI Quotes Generator"/>
{/* <Typography component="p" variant="subtitle2">
The AI Wizard can generate brand new quotes.
</Typography> */}
<form className={classes.form} noValidate onSubmit={handleSubmit}>
<Grid container justify="center">
<FormControl variant="outlined" className={classes.formControl}>
<FormLabel component="legend">Select the Persona</FormLabel>
<RadioGroup
row
aria-label="position"
name="position"
value={modelName}
onChange={handleModelNameChange}
>
<LargeTooltip
title={persona["motivational"]["description"]}
placement="top"
>
<FormControlLabel
value="motivational"
control={<Radio color="primary" />}
label={persona["motivational"]["name"]}
labelPlacement="end"
/>
</LargeTooltip>
<LargeTooltip
title={persona["serious"]["description"]}
placement="top"
>
<FormControlLabel
value="serious"
control={<Radio color="primary" />}
label={persona["serious"]["name"]}
labelPlacement="end"
/>
</LargeTooltip>
<LargeTooltip
title={persona["funny"]["description"]}
placement="top"
>
<FormControlLabel
value="funny"
control={<Radio color="primary" />}
label={persona["funny"]["name"]}
labelPlacement="end"
/>
</LargeTooltip>
</RadioGroup>
</FormControl>
</Grid>
<FormControl
fullWidth
className={clsx(classes.margin, classes.textField)}
>
<InputLabel htmlFor="seed" style={{ marginLeft: "2%" }}>
Start off the quote or leave it empty to go completely random
</InputLabel>
<OutlinedInput
id="seed"
type="text"
value={nextSeed}
onChange={handleSeedChange}
endAdornment={
<InputAdornment position="end">
<IconButton
aria-label="shuffle"
color="primary"
onClick={handleSeedShuffle}
>
{loadingSeed ? (
<CircularProgress size={30} />
) : (
<ShuffleIcon />
)}
</IconButton>
</InputAdornment>
}
/>
</FormControl>
<FormControl fullWidth className={clsx(classes.margin)}>
<List>
<ListItem button onClick={handleAdvancedSettings}>
<ListItemIcon>
<SettingsIcon />
</ListItemIcon>
<ListItemText primary="Advanced Settings" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<FormControl className={clsx(classes.margin, classes.slider)}>
<InputLabel
htmlFor="variety"
className={clsx(classes.sliderLabel)}
>
Variety
</InputLabel>
<Slider
id="variety"
value={variety}
onChange={handleVariety}
step={0.1}
marks
min={0.1}
max={0.9}
valueLabelDisplay="on"
/>
</FormControl>
<FormControl
fullWidth
className={clsx(classes.margin, classes.slider)}
>
<InputLabel
htmlFor="min-length"
className={clsx(classes.sliderLabel)}
>
Minimum Number of Words
</InputLabel>
<Slider
id="min-length"
value={minLength}
onChange={handleMinLength}
step={10}
marks
min={10}
max={100}
valueLabelDisplay="on"
/>
</FormControl>
<FormControl
fullWidth
className={clsx(classes.margin, classes.slider)}
>
<InputLabel
htmlFor="max-length"
className={clsx(classes.sliderLabel)}
>
Maximum Number of Words
</InputLabel>
<Slider
id="max-length"
value={maxLength}
onChange={handleMaxLength}
step={10}
marks
min={10}
max={100}
valueLabelDisplay="on"
/>
</FormControl>
</Collapse>
</List>
</FormControl>
<FormControl fullWidth className={clsx(classes.margin)}>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
disabled={generatingQuote}
className={classes.submit}
>
Generate Quote
</Button>
{generatingQuote && (
<CircularProgress
size={24}
className={classes.buttonProgress}
/>
)}
</FormControl>
<Box mt={5}>
<Copyright />
</Box>
</form>
</div>
</Grid>
<Grid
item
xs={12}
sm={4}
md={7}
className={classes.image}
style={{ backgroundImage: "url(" + bgImage + ")" }}
>
<section>
{/* <div class="line"></div> */}
<div class="quote">
<hr class="line" />
{generatingQuote ? (
<div>
<Typography
style={{ marginLeft: "10px", color: "white" }}
variant="overline"
>
Writing the quote...
</Typography>
<LinearProgress
color="secondary"
style={{ width: "100%" }}
className={classes.progressModel}
/>
</div>
) : (
<p class="text">{quote}</p>
)}
<p class="attr">{author}</p>
<hr class="line" />
</div>
{/* <div class="line"></div> */}
<CustomizedRatings
submitRating={handleRatingsSubmit}
value={rating}
setValue={setRating}
/>
</section>
</Grid>
</Grid>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment