mirror of
https://github.com/maciej3031/comixify.git
synced 2026-03-11 08:54:35 +00:00
Add YouTube frontend (#5)
* Add youtube frontend * Add production build of frontend
This commit is contained in:
parent
939d017850
commit
d5ae415ce1
7 changed files with 689 additions and 322 deletions
|
|
@ -8,7 +8,8 @@ import { css } from "react-emotion";
|
|||
import {
|
||||
COMIXIFY_API,
|
||||
MAX_FILE_SIZE,
|
||||
PERMITTED_VIDEO_EXTENSIONS
|
||||
PERMITTED_VIDEO_EXTENSIONS,
|
||||
FROM_YOUTUBE_API
|
||||
} from "./constants";
|
||||
|
||||
class App extends React.Component {
|
||||
|
|
@ -19,6 +20,7 @@ class App extends React.Component {
|
|||
UPLOAD_ERROR: 3,
|
||||
DROP_ERROR: 4
|
||||
};
|
||||
ytInput = React.createRef();
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
|
@ -27,6 +29,8 @@ class App extends React.Component {
|
|||
result_comics: null
|
||||
};
|
||||
this.onVideoDrop = this.onVideoDrop.bind(this);
|
||||
this.handleResponse = this.handleResponse.bind(this);
|
||||
this.onYouTubeSubmit = this.onYouTubeSubmit.bind(this);
|
||||
this.onVideoUploadProgress = this.onVideoUploadProgress.bind(this);
|
||||
}
|
||||
onVideoUploadProgress(progressEvent) {
|
||||
|
|
@ -35,6 +39,18 @@ class App extends React.Component {
|
|||
);
|
||||
console.log(percentCompleted);
|
||||
}
|
||||
handleResponse(res) {
|
||||
if (res.data["status_message"] === "ok") {
|
||||
this.setState({
|
||||
state: App.appStates.FINISHED,
|
||||
result_comics: res.data["comic"]
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
state: App.appStates.UPLOAD_ERROR
|
||||
});
|
||||
}
|
||||
}
|
||||
processVideo(video) {
|
||||
let data = new FormData();
|
||||
data.append("file", video);
|
||||
|
|
@ -42,18 +58,7 @@ class App extends React.Component {
|
|||
headers: { "content-type": "multipart/form-data" },
|
||||
onUploadProgress: this.onVideoUploadProgress
|
||||
})
|
||||
.then(res => {
|
||||
if (res.data["status_message"] === "ok") {
|
||||
this.setState({
|
||||
state: App.appStates.FINISHED,
|
||||
result_comics: res.data["comic"]
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
state: App.appStates.UPLOAD_ERROR
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(this.handleResponse)
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
this.setState({
|
||||
|
|
@ -75,10 +80,25 @@ class App extends React.Component {
|
|||
}
|
||||
this.processVideo(files[0]);
|
||||
}
|
||||
|
||||
onYouTubeSubmit() {
|
||||
let ytLink = this.ytInput.current.value;
|
||||
post(FROM_YOUTUBE_API, {
|
||||
url: ytLink
|
||||
})
|
||||
.then(this.handleResponse)
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
this.setState({
|
||||
state: App.appStates.UPLOAD_ERROR
|
||||
});
|
||||
});
|
||||
this.setState({
|
||||
state: App.appStates.PROCESSING
|
||||
});
|
||||
}
|
||||
render() {
|
||||
let { state, drop_errors, result_comics } = this.state;
|
||||
let showDropzone = [
|
||||
let showUsage = [
|
||||
App.appStates.INITIAL,
|
||||
App.appStates.UPLOAD_ERROR,
|
||||
App.appStates.DROP_ERROR,
|
||||
|
|
@ -95,7 +115,7 @@ class App extends React.Component {
|
|||
{state === App.appStates.UPLOAD_ERROR && (
|
||||
<p>Server Error: Please try again later.</p>
|
||||
)}
|
||||
{showDropzone && (
|
||||
{showUsage && (
|
||||
<Dropzone
|
||||
onDrop={this.onVideoDrop}
|
||||
accept={PERMITTED_VIDEO_EXTENSIONS}
|
||||
|
|
@ -105,9 +125,16 @@ class App extends React.Component {
|
|||
rejectClassName="dropzone--rejected"
|
||||
multiple={false} // Only one video at the time
|
||||
>
|
||||
<p>Drop files here, or click to select manually</p>
|
||||
<p>Drop video here, or click to select manually</p>
|
||||
</Dropzone>
|
||||
)}
|
||||
{showUsage && (
|
||||
<div>
|
||||
<label htmlFor="yt-link" className="yt-label">Or use YouTube link:</label>
|
||||
<input type="url" id="yt-link" ref={this.ytInput}/>
|
||||
<button onClick={this.onYouTubeSubmit}>Run</button>
|
||||
</div>
|
||||
)}
|
||||
{state === App.appStates.PROCESSING && (
|
||||
<BarLoader
|
||||
color={"rgb(54, 215, 183)"}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
export const COMIXIFY_API = "/comixify/";
|
||||
export const FROM_YOUTUBE_API = "/comixify/from_yt/";
|
||||
export const MAX_FILE_SIZE = 50000000;
|
||||
export const PERMITTED_VIDEO_EXTENSIONS = "video/*";
|
||||
|
|
|
|||
|
|
@ -1,51 +1,54 @@
|
|||
const webpack = require("webpack");
|
||||
const merge = require("webpack-merge");
|
||||
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
|
||||
module.exports = env => {
|
||||
const merge = require("webpack-merge");
|
||||
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
|
||||
const webpack = require("webpack");
|
||||
|
||||
let common = {
|
||||
entry: {
|
||||
app: __dirname + "/App.js"
|
||||
},
|
||||
output: {
|
||||
path: __dirname + "/../static/frontend/js",
|
||||
filename: "[name].client.js"
|
||||
},
|
||||
externals: {
|
||||
cheerio: "window",
|
||||
"react/lib/ExecutionEnvironment": true,
|
||||
"react/lib/ReactContext": true
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
loader: "babel-loader",
|
||||
query: {
|
||||
presets: ["react", "stage-0", "flow"],
|
||||
plugins: ["emotion"]
|
||||
let common = {
|
||||
entry: {
|
||||
app: __dirname + "/App.js"
|
||||
},
|
||||
output: {
|
||||
path: __dirname + "/../static/frontend/js",
|
||||
filename: "[name].client.js"
|
||||
},
|
||||
externals: {
|
||||
cheerio: "window",
|
||||
"react/lib/ExecutionEnvironment": true,
|
||||
"react/lib/ReactContext": true
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
loader: "babel-loader",
|
||||
query: {
|
||||
presets: ["react", "stage-0", "flow"],
|
||||
plugins: ["emotion"]
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ["style-loader", "css-loader"]
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ["style-loader", "css-loader"]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
module.exports = merge(common, {
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
"process.env.NODE_ENV": JSON.stringify("production")
|
||||
}),
|
||||
new UglifyJsPlugin()
|
||||
],
|
||||
mode: "production"
|
||||
});
|
||||
} else {
|
||||
module.exports = merge(common, {
|
||||
mode: "development"
|
||||
});
|
||||
if (env.production) {
|
||||
return merge(common, {
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
"process.env.NODE_ENV": JSON.stringify("production")
|
||||
}),
|
||||
new UglifyJsPlugin()
|
||||
],
|
||||
mode: "production"
|
||||
});
|
||||
} else {
|
||||
return merge(common, {
|
||||
mode: "development"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,56 @@ img {
|
|||
background-color: #eee;
|
||||
}
|
||||
|
||||
.yt-label {
|
||||
margin: 10px 0 10px 20px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#yt-link {
|
||||
height: 30px;
|
||||
margin-right: 5px;
|
||||
padding: 6px 10px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #D1D1D1;
|
||||
border-radius: 3px;
|
||||
box-shadow: none;
|
||||
box-sizing: border-box;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
|
||||
#yt-link:focus {
|
||||
border: 1px solid #33C3F0;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
display: inline-block;
|
||||
height: 30px;
|
||||
padding: 0 30px;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
background-color: transparent;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #bbb;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
button:hover,
|
||||
button:focus {
|
||||
color: #333;
|
||||
border-color: #888;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
@media all and (max-width: 700px) {
|
||||
.wrap {
|
||||
margin-top: 0;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
782
package-lock.json
generated
782
package-lock.json
generated
File diff suppressed because it is too large
Load diff
10
package.json
10
package.json
|
|
@ -7,7 +7,7 @@
|
|||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "webpack --config ./frontend/client/webpack.config.js",
|
||||
"build:watch": "webpack --config ./frontend/client/webpack.config.js --watch",
|
||||
"build:prod": "NODE_ENV=production webpack --config ./frontend/client/webpack.config.js"
|
||||
"build:prod": "webpack --env.production --config ./frontend/client/webpack.config.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -35,11 +35,11 @@
|
|||
"react-dropzone": "^5.0.1",
|
||||
"react-spinners": "^0.4.5",
|
||||
"style-loader": "^0.23.0",
|
||||
"uglifyjs-webpack-plugin": "^1.2.5",
|
||||
"webpack": "^4.17.1",
|
||||
"webpack-merge": "^4.1.1"
|
||||
"uglifyjs-webpack-plugin": "^1.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack-cli": "^3.1.0"
|
||||
"webpack": "^4.20.2",
|
||||
"webpack-cli": "^3.1.0",
|
||||
"webpack-merge": "^4.1.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue