mirror of
https://github.com/gradio-app/gradio.git
synced 2024-12-21 02:19:59 +08:00
fix screenshot, image editor;
This commit is contained in:
parent
7deb0aa22f
commit
dc211822ca
113
frontend/package-lock.json
generated
113
frontend/package-lock.json
generated
@ -13,9 +13,11 @@
|
||||
"@testing-library/jest-dom": "^5.11.10",
|
||||
"@testing-library/react": "^11.2.6",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@toast-ui/react-image-editor": "^3.14.2",
|
||||
"audio-react-recorder": "^1.0.4",
|
||||
"classnames": "^2.3.1",
|
||||
"fabric": "^4.5.0",
|
||||
"html2canvas-objectfit-fix": "^1.2.0",
|
||||
"jspreadsheet-ce": "^4.7.3",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
@ -2578,6 +2580,18 @@
|
||||
"@testing-library/dom": ">=7.21.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@toast-ui/react-image-editor": {
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@toast-ui/react-image-editor/-/react-image-editor-3.14.2.tgz",
|
||||
"integrity": "sha512-FWnEBTESI6yqM9eDqkGTNbnN6lM9/XxxrxMlg06sW9Dh5LvQsIYdz0G8J77brR0Qm+FXdwAK/n2jltitcTnB0Q==",
|
||||
"dependencies": {
|
||||
"fabric": "^4.2.0",
|
||||
"tui-image-editor": "^3.14.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/anymatch": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
|
||||
@ -4321,6 +4335,14 @@
|
||||
"resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz",
|
||||
"integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA="
|
||||
},
|
||||
"node_modules/base64-arraybuffer": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz",
|
||||
"integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
@ -5694,6 +5716,14 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/css-line-break": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-1.1.1.tgz",
|
||||
"integrity": "sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA==",
|
||||
"dependencies": {
|
||||
"base64-arraybuffer": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/css-loader": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz",
|
||||
@ -9610,6 +9640,17 @@
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/html2canvas-objectfit-fix": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/html2canvas-objectfit-fix/-/html2canvas-objectfit-fix-1.2.0.tgz",
|
||||
"integrity": "sha512-eBQPJyJJPgAlgtMioB42Kv+wHXGgfjUyPdYWZKbF8jUlss4J6xdj5tJM8n2uZ/94NU2UEooN97ypGdzbFE562A==",
|
||||
"dependencies": {
|
||||
"css-line-break": "1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||
@ -18884,6 +18925,27 @@
|
||||
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
||||
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
|
||||
},
|
||||
"node_modules/tui-code-snippet": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/tui-code-snippet/-/tui-code-snippet-1.5.2.tgz",
|
||||
"integrity": "sha512-6UqTlQaaC1KLcmC0HAoq5dtl1G4Fib+R+NC7pmaV7kiIlZ7JqKhUmnOoGRcreAyzd81UTK/vCvhrw9QJskpCFQ=="
|
||||
},
|
||||
"node_modules/tui-color-picker": {
|
||||
"version": "2.2.7",
|
||||
"resolved": "https://registry.npmjs.org/tui-color-picker/-/tui-color-picker-2.2.7.tgz",
|
||||
"integrity": "sha512-y7gUe6PdVBq8ruZbiOkeaN7N/DX+ogVyLkK53OM4qW5Vrc4pDWYEKlnOBCsPODb4/RSzS9iTd6fXYirXxeakJA=="
|
||||
},
|
||||
"node_modules/tui-image-editor": {
|
||||
"version": "3.14.3",
|
||||
"resolved": "https://registry.npmjs.org/tui-image-editor/-/tui-image-editor-3.14.3.tgz",
|
||||
"integrity": "sha512-zNbC+nKVYdLSvUuHK+ZWTJw6T5Jr02oPBKrdEjfGAP7gx2yfWzHbpmrsivLyiCJzKV580N4mt0mAXttB2EClYg==",
|
||||
"dependencies": {
|
||||
"core-js-pure": "^3.6.4",
|
||||
"fabric": "^4.2.0",
|
||||
"tui-code-snippet": "^1.5.0",
|
||||
"tui-color-picker": "^2.2.6"
|
||||
}
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
@ -23264,6 +23326,15 @@
|
||||
"@babel/runtime": "^7.12.5"
|
||||
}
|
||||
},
|
||||
"@toast-ui/react-image-editor": {
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@toast-ui/react-image-editor/-/react-image-editor-3.14.2.tgz",
|
||||
"integrity": "sha512-FWnEBTESI6yqM9eDqkGTNbnN6lM9/XxxrxMlg06sW9Dh5LvQsIYdz0G8J77brR0Qm+FXdwAK/n2jltitcTnB0Q==",
|
||||
"requires": {
|
||||
"fabric": "^4.2.0",
|
||||
"tui-image-editor": "^3.14.2"
|
||||
}
|
||||
},
|
||||
"@types/anymatch": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
|
||||
@ -24703,6 +24774,11 @@
|
||||
"resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz",
|
||||
"integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA="
|
||||
},
|
||||
"base64-arraybuffer": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz",
|
||||
"integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ=="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
@ -25818,6 +25894,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"css-line-break": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-1.1.1.tgz",
|
||||
"integrity": "sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"css-loader": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz",
|
||||
@ -28904,6 +28988,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"html2canvas-objectfit-fix": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/html2canvas-objectfit-fix/-/html2canvas-objectfit-fix-1.2.0.tgz",
|
||||
"integrity": "sha512-eBQPJyJJPgAlgtMioB42Kv+wHXGgfjUyPdYWZKbF8jUlss4J6xdj5tJM8n2uZ/94NU2UEooN97ypGdzbFE562A==",
|
||||
"requires": {
|
||||
"css-line-break": "1.1.1"
|
||||
}
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||
@ -36222,6 +36314,27 @@
|
||||
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
|
||||
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
|
||||
},
|
||||
"tui-code-snippet": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/tui-code-snippet/-/tui-code-snippet-1.5.2.tgz",
|
||||
"integrity": "sha512-6UqTlQaaC1KLcmC0HAoq5dtl1G4Fib+R+NC7pmaV7kiIlZ7JqKhUmnOoGRcreAyzd81UTK/vCvhrw9QJskpCFQ=="
|
||||
},
|
||||
"tui-color-picker": {
|
||||
"version": "2.2.7",
|
||||
"resolved": "https://registry.npmjs.org/tui-color-picker/-/tui-color-picker-2.2.7.tgz",
|
||||
"integrity": "sha512-y7gUe6PdVBq8ruZbiOkeaN7N/DX+ogVyLkK53OM4qW5Vrc4pDWYEKlnOBCsPODb4/RSzS9iTd6fXYirXxeakJA=="
|
||||
},
|
||||
"tui-image-editor": {
|
||||
"version": "3.14.3",
|
||||
"resolved": "https://registry.npmjs.org/tui-image-editor/-/tui-image-editor-3.14.3.tgz",
|
||||
"integrity": "sha512-zNbC+nKVYdLSvUuHK+ZWTJw6T5Jr02oPBKrdEjfGAP7gx2yfWzHbpmrsivLyiCJzKV580N4mt0mAXttB2EClYg==",
|
||||
"requires": {
|
||||
"core-js-pure": "^3.6.4",
|
||||
"fabric": "^4.2.0",
|
||||
"tui-code-snippet": "^1.5.0",
|
||||
"tui-color-picker": "^2.2.6"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
|
@ -8,9 +8,11 @@
|
||||
"@testing-library/jest-dom": "^5.11.10",
|
||||
"@testing-library/react": "^11.2.6",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@toast-ui/react-image-editor": "^3.14.2",
|
||||
"audio-react-recorder": "^1.0.4",
|
||||
"classnames": "^2.3.1",
|
||||
"fabric": "^4.5.0",
|
||||
"html2canvas-objectfit-fix": "^1.2.0",
|
||||
"jspreadsheet-ce": "^4.7.3",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
|
@ -1,4 +1,7 @@
|
||||
import React from 'react';
|
||||
import html2canvas from 'html2canvas-objectfit-fix';
|
||||
import { saveAs } from './utils';
|
||||
import ReactDOM from "react-dom";
|
||||
import classNames from "classnames";
|
||||
|
||||
import { AudioInput, AudioInputExample } from './interfaces/input/audio';
|
||||
@ -67,6 +70,7 @@ export class GradioInterface extends React.Component {
|
||||
this.flag = this.flag.bind(this);
|
||||
this.interpret = this.interpret.bind(this);
|
||||
this.removeInterpret = this.removeInterpret.bind(this);
|
||||
this.takeScreenshot = this.takeScreenshot.bind(this);
|
||||
this.handleExampleChange = this.handleExampleChange.bind(this);
|
||||
this.state = this.get_default_state();
|
||||
this.state["examples_page"] = 0;
|
||||
@ -162,6 +166,11 @@ export class GradioInterface extends React.Component {
|
||||
removeInterpret() {
|
||||
this.setState({ "interpretation": null });
|
||||
}
|
||||
takeScreenshot() {
|
||||
html2canvas(ReactDOM.findDOMNode(this)).then(canvas => {
|
||||
saveAs(canvas.toDataURL(), 'screenshot.png');
|
||||
});
|
||||
}
|
||||
handleChange(_id, value) {
|
||||
let state_change = { [_id]: value, "has_changed": true };
|
||||
if (this.props.live && !(this.state.submitting)) {
|
||||
@ -238,7 +247,7 @@ export class GradioInterface extends React.Component {
|
||||
: false
|
||||
}
|
||||
{this.props.allow_screenshot ?
|
||||
<button className="panel_button hidden">Screenshot</button>
|
||||
<button onClick={this.takeScreenshot} className="panel_button">Screenshot</button>
|
||||
: false}
|
||||
{this.props.allow_flagging ?
|
||||
(this.props.flagging_options === null ?
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { DataURLComponentExample } from '../component_example';
|
||||
import AudioReactRecorder, { RecordState } from 'audio-react-recorder'
|
||||
import { getSaliencyColor } from '../utils';
|
||||
import { getSaliencyColor } from '../../utils';
|
||||
|
||||
class AudioInput extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import ComponentExample from '../component_example';
|
||||
import classNames from "classnames";
|
||||
import { getSaliencyColor } from '../utils';
|
||||
import { getSaliencyColor } from '../../utils';
|
||||
|
||||
class CheckboxInput extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import ComponentExample from '../component_example';
|
||||
import classNames from "classnames";
|
||||
import { getSaliencyColor } from '../utils';
|
||||
import { getSaliencyColor } from '../../utils';
|
||||
|
||||
class CheckboxGroupInput extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import ComponentExample from '../component_example';
|
||||
import classNames from "classnames";
|
||||
import { getSaliencyColor } from '../utils';
|
||||
import { getSaliencyColor } from '../../utils';
|
||||
|
||||
class DropdownInput extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import ComponentExample from '../component_example';
|
||||
import {prettyBytes} from '../utils';
|
||||
import {prettyBytes} from '../../utils';
|
||||
|
||||
class FileInput extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -2,7 +2,9 @@ import React from 'react';
|
||||
import { DataURLComponentExample } from '../component_example';
|
||||
import Webcam from "react-webcam";
|
||||
import { SketchField, Tools } from '../../vendor/ReactSketch';
|
||||
import { getObjectFitSize, paintSaliency } from '../utils';
|
||||
import { getObjectFitSize, paintSaliency } from '../../utils';
|
||||
import 'tui-image-editor/dist/tui-image-editor.css';
|
||||
import ImageEditor from '@toast-ui/react-image-editor';
|
||||
|
||||
class ImageInput extends React.Component {
|
||||
constructor(props) {
|
||||
@ -14,12 +16,17 @@ class ImageInput extends React.Component {
|
||||
this.load_preview_from_files = this.load_preview_from_files.bind(this);
|
||||
this.load_preview_from_upload = this.load_preview_from_upload.bind(this);
|
||||
this.load_preview_from_drop = this.load_preview_from_drop.bind(this);
|
||||
this.saveEditor = this.saveEditor.bind(this);
|
||||
this.cancelEditor = this.cancelEditor.bind(this);
|
||||
this.snapshot = this.snapshot.bind(this);
|
||||
this.getSketch = this.getSketch.bind(this);
|
||||
this.openEditor = this.openEditor.bind(this);
|
||||
this.imgRef = React.createRef();
|
||||
this.webcamRef = React.createRef();
|
||||
this.sketchRef = React.createRef();
|
||||
this.editorRef = React.createRef();
|
||||
this.sketchKey = 0;
|
||||
this.state = { editorMode: false };
|
||||
}
|
||||
handleChange(data) {
|
||||
this.props.handleChange(data);
|
||||
@ -35,9 +42,24 @@ class ImageInput extends React.Component {
|
||||
let imageSrc = this.sketchRef.current.toDataURL();
|
||||
this.handleChange(imageSrc);
|
||||
}
|
||||
cancelEditor() {
|
||||
this.setState({"editorMode": false});
|
||||
}
|
||||
saveEditor() {
|
||||
const editorInstance = this.editorRef.current.getInstance();
|
||||
this.handleChange(editorInstance.toDataURL());
|
||||
this.setState({"editorMode": false});
|
||||
}
|
||||
onImgLoad({ target: img }) {
|
||||
this.setState({dimensions:{height:img.offsetHeight,
|
||||
width:img.offsetWidth}});
|
||||
this.setState({
|
||||
dimensions: {
|
||||
height: img.offsetHeight,
|
||||
width: img.offsetWidth
|
||||
}
|
||||
});
|
||||
}
|
||||
openEditor() {
|
||||
this.setState({ editorMode: true })
|
||||
}
|
||||
render() {
|
||||
let no_action = (evt) => {
|
||||
@ -65,6 +87,29 @@ class ImageInput extends React.Component {
|
||||
return (
|
||||
<div className="input_image">
|
||||
<div className="image_preview_holder">
|
||||
{this.state.editorMode ?
|
||||
<div className="image_editor">
|
||||
<div className="image_editor_buttons">
|
||||
<button onClick={this.saveEditor}>Save</button>
|
||||
<button onClick={this.cancelEditor}>Cancel</button>
|
||||
</div>
|
||||
<ImageEditor
|
||||
ref={this.editorRef}
|
||||
includeUI={{
|
||||
loadImage: {path: this.props.value, name: "value"},
|
||||
uiSize: {
|
||||
width: '800px',
|
||||
height: '600px',
|
||||
},
|
||||
menuBarPosition: 'left',
|
||||
}}
|
||||
cssMaxHeight={500}
|
||||
cssMaxWidth={700}
|
||||
usageStatistics={false}
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
<button className="edit_button" onClick={this.openEditor}>Edit</button>}
|
||||
<img ref={this.imgRef} onLoad={this.onImgLoad} className="image_preview" alt="" src={this.props.value} />
|
||||
</div>
|
||||
{interpretation}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import ComponentExample from '../component_example';
|
||||
import { getSaliencyColor } from '../utils';
|
||||
import { getSaliencyColor } from '../../utils';
|
||||
|
||||
class NumberInput extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import ComponentExample from '../component_example';
|
||||
import classNames from "classnames";
|
||||
import { getSaliencyColor } from '../utils';
|
||||
import { getSaliencyColor } from '../../utils';
|
||||
|
||||
class RadioInput extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import ComponentExample from '../component_example';
|
||||
import { getSaliencyColor } from '../utils';
|
||||
import { getSaliencyColor } from '../../utils';
|
||||
|
||||
class SliderInput extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import ComponentExample from '../component_example';
|
||||
import { getSaliencyColor } from '../utils';
|
||||
import { getSaliencyColor } from '../../utils';
|
||||
|
||||
class TextboxInput extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import ComponentExample from '../component_example';
|
||||
import {prettyBytes} from '../utils';
|
||||
import {prettyBytes} from '../../utils';
|
||||
|
||||
class FileOutput extends React.Component {
|
||||
render() {
|
||||
|
@ -160,6 +160,26 @@
|
||||
.image_preview_holder {
|
||||
@apply w-full h-full flex justify-center items-center bg-gray-200 relative inline-block;
|
||||
}
|
||||
.edit_button {
|
||||
@apply absolute top-1 right-1 bg-yellow-500 text-white px-2 py-1;
|
||||
}
|
||||
.image_editor {
|
||||
@apply fixed w-screen h-screen top-0 left-0 bg-black bg-opacity-50 z-40 flex flex-col justify-center items-center;
|
||||
.image_editor_buttons {
|
||||
width: 800px;
|
||||
@apply flex justify-end gap-1;
|
||||
button {
|
||||
@apply px-2 py-1 text-xl bg-black text-white font-semibold rounded-t;
|
||||
}
|
||||
}
|
||||
.tui-image-editor-header-buttons {
|
||||
@apply hidden;
|
||||
}
|
||||
.tui-colorpicker-palette-button {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
.image_preview,
|
||||
video {
|
||||
@apply w-full h-full object-contain;
|
||||
|
@ -40,6 +40,23 @@
|
||||
.panel_buttons {
|
||||
@apply flex gap-4 my-4;
|
||||
}
|
||||
.flag {
|
||||
@apply relative;
|
||||
.dropcontent {
|
||||
@apply hidden absolute top-8 left-0 bg-white border-gray-200 border-2 w-full;
|
||||
div {
|
||||
@apply p-2;
|
||||
}
|
||||
div:hover {
|
||||
@apply bg-gray-100;
|
||||
}
|
||||
}
|
||||
}
|
||||
.flag:hover:not(.disabled) {
|
||||
.dropcontent {
|
||||
@apply block;
|
||||
}
|
||||
}
|
||||
.screenshot_set {
|
||||
@apply hidden flex hidden flex-grow;
|
||||
}
|
||||
@ -86,33 +103,71 @@
|
||||
}
|
||||
}
|
||||
/* Input Components */
|
||||
.input_text textarea {
|
||||
.input_text {
|
||||
textarea {
|
||||
@apply w-full p-3 border rounded-lg shadow-inner outline-none focus:ring-1 focus:ring-inset focus:ring-indigo-200 focus:shadow-inner placeholder-gray-400;
|
||||
}
|
||||
.input_text input {
|
||||
input {
|
||||
@apply w-full p-3 border rounded-lg shadow-inner outline-none focus:ring-1 focus:ring-inset focus:ring-indigo-200 focus:shadow-inner placeholder-gray-400;
|
||||
}
|
||||
.input_number input {
|
||||
.interpretation {
|
||||
.interpretation_box {
|
||||
@apply inline-block whitespace-pre-wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
.input_number {
|
||||
input {
|
||||
@apply w-full p-3 border rounded-lg shadow-inner outline-none focus:ring-1 focus:ring-inset focus:ring-indigo-200 focus:shadow-inner placeholder-gray-400;
|
||||
}
|
||||
.interpretation {
|
||||
@apply flex h-6;
|
||||
.interpretation_box {
|
||||
@apply flex-grow;
|
||||
}
|
||||
}
|
||||
}
|
||||
.input_image {
|
||||
@apply w-full h-80;
|
||||
@apply w-full h-80 relative;
|
||||
.upload_zone {
|
||||
@apply border-8 border-gray-300 border-dashed w-full h-full flex justify-center items-center text-3xl text-gray-400 text-center cursor-pointer leading-10;
|
||||
}
|
||||
.image_preview_holder {
|
||||
@apply w-full h-full flex justify-center items-center bg-gray-300 relative inline-block;
|
||||
}
|
||||
.sketch > div {
|
||||
@apply bg-white;
|
||||
.edit_button {
|
||||
@apply absolute top-1 right-1 bg-indigo-500 text-white px-2 py-1;
|
||||
}
|
||||
.image_editor {
|
||||
@apply fixed w-screen h-screen top-0 left-0 bg-black bg-opacity-50 z-40 flex flex-col justify-center items-center;
|
||||
.image_editor_buttons {
|
||||
width: 800px;
|
||||
@apply flex justify-end gap-1;
|
||||
button {
|
||||
@apply px-2 py-1 text-xl bg-black text-white font-semibold rounded-t;
|
||||
}
|
||||
}
|
||||
.tui-image-editor-header-buttons {
|
||||
@apply hidden;
|
||||
}
|
||||
.tui-colorpicker-palette-button {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
.image_preview,
|
||||
video {
|
||||
@apply w-full h-full object-contain;
|
||||
}
|
||||
.sketch > div {
|
||||
@apply bg-white;
|
||||
}
|
||||
.snapshot {
|
||||
@apply absolute bottom-0 w-full bg-white bg-opacity-90 py-3 font-bold text-lg text-center;
|
||||
}
|
||||
.interpretation {
|
||||
@apply w-full h-full absolute top-0 left-0 flex justify-center items-center opacity-90 hover:opacity-20 transition;
|
||||
}
|
||||
}
|
||||
.input_image_example {
|
||||
@apply h-24;
|
||||
@ -157,6 +212,20 @@
|
||||
stroke-width: 4;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
.interpretation {
|
||||
@apply flex;
|
||||
.interpretation_box {
|
||||
@apply flex-grow h-4 w-4;
|
||||
}
|
||||
.interpret_check {
|
||||
@apply w-full h-full;
|
||||
}
|
||||
.interpret_check line {
|
||||
stroke: gray;
|
||||
stroke-width: 4;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
}
|
||||
}
|
||||
.input_checkbox {
|
||||
@apply flex flex-wrap gap-2;
|
||||
@ -183,6 +252,20 @@
|
||||
stroke-width: 4;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
.interpretation {
|
||||
@apply flex;
|
||||
.interpretation_box {
|
||||
@apply flex-grow h-4 w-4;
|
||||
}
|
||||
.interpret_check {
|
||||
@apply w-full h-full;
|
||||
}
|
||||
.interpret_check line {
|
||||
stroke: gray;
|
||||
stroke-width: 4;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
}
|
||||
}
|
||||
.input_dropdown {
|
||||
@apply inline-block relative;
|
||||
@ -210,6 +293,9 @@
|
||||
:hover .dropdown_menu {
|
||||
@apply block;
|
||||
}
|
||||
.interpretation_box {
|
||||
@apply p-1;
|
||||
}
|
||||
}
|
||||
.input_slider {
|
||||
@apply text-center;
|
||||
@ -226,6 +312,12 @@
|
||||
.value {
|
||||
@apply inline-block mx-auto mt-1 px-2 py-0.5 bg-gray-100 text-gray-700 rounded shadow-inner;
|
||||
}
|
||||
.interpret_range {
|
||||
@apply flex h-6;
|
||||
div {
|
||||
@apply flex-grow;
|
||||
}
|
||||
}
|
||||
}
|
||||
.input_audio {
|
||||
.audio-react-recorder {
|
||||
@ -239,6 +331,12 @@
|
||||
}
|
||||
audio {
|
||||
@apply w-full;
|
||||
.interpret_range {
|
||||
@apply flex h-4;
|
||||
div {
|
||||
@apply flex-grow h-full;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.input_video {
|
||||
@ -268,7 +366,6 @@
|
||||
@apply text-2xl p-2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output Components */
|
||||
.output_text {
|
||||
word-break: break-word;
|
||||
|
@ -73,3 +73,19 @@ export function paintSaliency(data, ctx, width, height) {
|
||||
r++;
|
||||
})
|
||||
}
|
||||
|
||||
export function saveAs(uri, filename) {
|
||||
var link = document.createElement('a');
|
||||
if (typeof link.download === 'string') {
|
||||
link.href = uri;
|
||||
link.download = filename;
|
||||
//Firefox requires the link to be in the body
|
||||
document.body.appendChild(link);
|
||||
//simulate click
|
||||
link.click();
|
||||
//remove the link when done
|
||||
document.body.removeChild(link);
|
||||
} else {
|
||||
window.open(uri);
|
||||
}
|
||||
}
|
@ -26,6 +26,30 @@ gradio.egg-info/requires.txt
|
||||
gradio.egg-info/top_level.txt
|
||||
gradio/frontend/asset-manifest.json
|
||||
gradio/frontend/index.html
|
||||
gradio/frontend/static/bundle.css
|
||||
gradio/frontend/static/bundle.css.map
|
||||
gradio/frontend/static/bundle.js
|
||||
gradio/frontend/static/bundle.js.LICENSE.txt
|
||||
gradio/frontend/static/bundle.js.map
|
||||
gradio/frontend/static/css/main.20be28ac.css
|
||||
gradio/frontend/static/css/main.20be28ac.css.map
|
||||
gradio/frontend/static/css/main.2b64a968.css
|
||||
gradio/frontend/static/css/main.2b64a968.css.map
|
||||
gradio/frontend/static/css/main.380e3222.css
|
||||
gradio/frontend/static/css/main.380e3222.css.map
|
||||
gradio/frontend/static/css/main.4aea80f8.css
|
||||
gradio/frontend/static/css/main.4aea80f8.css.map
|
||||
gradio/frontend/static/css/main.4f157d97.css
|
||||
gradio/frontend/static/css/main.4f157d97.css.map
|
||||
gradio/frontend/static/css/main.5c663906.css
|
||||
gradio/frontend/static/css/main.5c663906.css.map
|
||||
gradio/frontend/static/css/main.99922310.css
|
||||
gradio/frontend/static/css/main.99922310.css.map
|
||||
gradio/frontend/static/css/main.acb02c85.css
|
||||
gradio/frontend/static/css/main.acb02c85.css.map
|
||||
gradio/frontend/static/css/main.cbbf8898.css
|
||||
gradio/frontend/static/css/main.cbbf8898.css.map
|
||||
gradio/frontend/static/media/logo_loading.e93acd82.jpg
|
||||
test/test_demos.py
|
||||
test/test_inputs.py
|
||||
test/test_interfaces.py
|
||||
|
@ -7,8 +7,9 @@ class Component():
|
||||
A class for defining the methods that all gradio input and output components should have.
|
||||
"""
|
||||
|
||||
def __init__(self, label):
|
||||
def __init__(self, label, requires_permissions=False):
|
||||
self.label = label
|
||||
self.requires_permissions = requires_permissions
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
|
@ -1,17 +1,17 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.4f157d97.css",
|
||||
"main.css": "/static/css/main.5c663906.css",
|
||||
"main.js": "/static/bundle.js",
|
||||
"main.js.map": "/static/bundle.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/bundle.css.map": "/static/bundle.css.map",
|
||||
"static/bundle.js.LICENSE.txt": "/static/bundle.js.LICENSE.txt",
|
||||
"static/css/main.4f157d97.css.map": "/static/css/main.4f157d97.css.map",
|
||||
"static/css/main.5c663906.css.map": "/static/css/main.5c663906.css.map",
|
||||
"static/media/logo_loading.e93acd82.jpg": "/static/media/logo_loading.e93acd82.jpg"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/bundle.css",
|
||||
"static/css/main.4f157d97.css",
|
||||
"static/css/main.5c663906.css",
|
||||
"static/bundle.js"
|
||||
]
|
||||
}
|
@ -8,4 +8,4 @@
|
||||
window.config = {{ config|tojson }};
|
||||
} catch (e) {
|
||||
window.config = {};
|
||||
}</script><title>Gradio</title><link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet"><link href="static/bundle.css" rel="stylesheet"><link href="static/css/main.4f157d97.css" rel="stylesheet"></head><body><div id="root"></div><script src="static/bundle.js"></script></body></html>
|
||||
}</script><title>Gradio</title><link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet"><link href="static/bundle.css" rel="stylesheet"><link href="static/css/main.5c663906.css" rel="stylesheet"></head><body><div id="root"></div><script src="static/bundle.js"></script></body></html>
|
@ -28,9 +28,9 @@ class InputComponent(Component):
|
||||
"""
|
||||
Input Component. All input components subclass this.
|
||||
"""
|
||||
def __init__(self, label):
|
||||
def __init__(self, label, requires_permissions=False):
|
||||
self.interpret()
|
||||
super().__init__(label)
|
||||
super().__init__(label, requires_permissions)
|
||||
|
||||
def preprocess(self, x):
|
||||
"""
|
||||
@ -642,11 +642,12 @@ class Image(InputComponent):
|
||||
self.shape = shape
|
||||
self.image_mode = image_mode
|
||||
self.source = source
|
||||
requires_permissions = source == "webcam"
|
||||
self.tool = tool
|
||||
self.type = type
|
||||
self.invert_colors = invert_colors
|
||||
self.test_input = test_data.BASE64_IMAGE
|
||||
super().__init__(label)
|
||||
super().__init__(label, requires_permissions)
|
||||
|
||||
@classmethod
|
||||
def get_shortcut_implementations(cls):
|
||||
@ -821,9 +822,10 @@ class Audio(InputComponent):
|
||||
label (str): component name in interface.
|
||||
"""
|
||||
self.source = source
|
||||
requires_permissions = source == "microphone"
|
||||
self.type = type
|
||||
self.test_input = test_data.BASE64_AUDIO
|
||||
super().__init__(label)
|
||||
super().__init__(label, requires_permissions)
|
||||
|
||||
def get_template_context(self):
|
||||
return {
|
||||
|
@ -183,6 +183,7 @@ class Interface:
|
||||
self.local_url = None
|
||||
self.embedding = embedding
|
||||
self.show_tips = show_tips
|
||||
self.requires_permissions = any([component.requires_permissions for component in self.input_components])
|
||||
|
||||
data = {'fn': fn,
|
||||
'inputs': inputs,
|
||||
@ -486,6 +487,8 @@ class Interface:
|
||||
print(strings.en["COLAB_DEBUG_FALSE"])
|
||||
else:
|
||||
print(strings.en["RUNNING_LOCALLY"].format(path_to_local_server))
|
||||
if is_colab and self.requires_permissions:
|
||||
print(strings.en["MEDIA_PERMISSIONS_IN_COLAB"])
|
||||
|
||||
if private_endpoint is not None:
|
||||
share = True
|
||||
@ -567,18 +570,9 @@ class Interface:
|
||||
|
||||
|
||||
def show_tip(io):
|
||||
if not(io.show_tips):
|
||||
if not(io.show_tips) or random.random() < 0.5: # Only show tip every other use.
|
||||
return
|
||||
if random.random() < 0.8: # Only show tips once every 5 uses
|
||||
return
|
||||
relevant_tips = []
|
||||
if io.interpretation is None:
|
||||
relevant_tips.append(strings.en["TIP_INTERPRETATION"])
|
||||
if io.embedding is None and not(io.examples is None) and len(io.examples)>4:
|
||||
relevant_tips.append(strings.en["TIP_EMBEDDING"])
|
||||
if len(relevant_tips)==0:
|
||||
return
|
||||
print(random.choice(relevant_tips))
|
||||
print(random.choice(strings.en.TIPS))
|
||||
|
||||
def launch_counter():
|
||||
try:
|
||||
|
@ -23,8 +23,14 @@ en = {
|
||||
"SHARE_LINK_MESSAGE": "This share link will expire in 24 hours. If you need a permanent link, visit: https://gradio.app/introducing-hosted (NEW!)",
|
||||
"SHARE_LINK_DISPLAY": "Running on External URL: {}",
|
||||
"INLINE_DISPLAY_BELOW": "Interface loading below...",
|
||||
"TIP_INTERPRETATION": "Tip: Add interpretation to your model by simply adding `interpretation=\"default\"` to `Interface()`",
|
||||
"TIP_EMBEDDING": "Tip: View embeddings of your dataset by simply adding `embedding=\"default\"` to `Interface()`",
|
||||
"MEDIA_PERMISSIONS_IN_COLAB": "Your interface requires microphone or webcam permissions - this may cause issues in Colab. Use the External URL in case of issues.",
|
||||
"TIPS": [
|
||||
"You can add authentication to your app with the auth= kwarg in the launch command; for example: gr.Interface(...).launch(auth=('username', 'password'))",
|
||||
"Let users specify why they flagged input with the flagging_options= kwarg; for example: gr.Interface(..., flagging_options=['too slow', 'incorrect output', 'other'])",
|
||||
"You can show or hide the buttons for flagging, screenshots, and interpretation with the allow_*= kwargs; for example: gr.Interface(..., allow_screenshot=True, allow_flagging=False)",
|
||||
"The inputs and outputs flagged by the users are stored in the flagging directory, specified by the flagging_dir= kwarg. You can view this data through the interface by setting the examples= kwarg to the flagging directory; for example gr.Interface(..., examples='flagged')",
|
||||
"You can add a title and description to your interface using the title= and description= kwargs. The article= kwarg can be used to add markdown or HTML under the interface; for example gr.Interface(..., title='My app', description='Lorem ipsum')"
|
||||
]
|
||||
}
|
||||
|
||||
try:
|
||||
|
Loading…
Reference in New Issue
Block a user