Skip to content

Commit

Permalink
#1 - some thouches
Browse files Browse the repository at this point in the history
- search icon animation
- add label to progress
TODO
- style the download ffmpeg screen
- "download all"  start process only when realy start
- make progress while getting info
  • Loading branch information
moshfeu committed Nov 21, 2018
1 parent d12ae0c commit e597ff0
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 53 deletions.
1 change: 1 addition & 0 deletions src/components/button-progress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class ButtonProgress extends React.Component<IButtonProgressProps, IButto
<span className="content">{text}</span>
<span className="progress">
<span className={`progress-inner${!this.isLoading ? ' notransition' : ''}`} style={{width: `${progress}%`, opacity: 1}}></span>
<span className="progress-counter">{progress}%</span>
</span>
</span>
</button>
Expand Down
19 changes: 15 additions & 4 deletions src/components/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,31 @@ interface IFormProps {
onSubmit: (url: string) => void;
onClear: () => void;
hasResult: boolean;
inProcess: boolean;
}

interface IFormState {
terms: string;
containerActive: boolean;
inProcess: boolean;
}

export class Form extends React.Component<IFormProps, IFormState> {
constructor(props) {
super(props);

this.state = {
terms: 'https://www.youtube.com/playlist?list=PLtKALR6MChBz1gYizYPwjggc5BGAmYRRK',
containerActive: true
terms: '',
containerActive: true,
inProcess: false
}
}

componentWillReceiveProps(newProps: IFormProps, currentProps: IFormProps) {
if (newProps.inProcess !== currentProps.inProcess) {
this.setState({
inProcess: newProps.inProcess
});
}
}

Expand Down Expand Up @@ -50,11 +61,11 @@ export class Form extends React.Component<IFormProps, IFormState> {
}

render() {
const { terms, containerActive } = this.state;
const { terms, containerActive, inProcess } = this.state;
const { hasResult } = this.props;

return (
<div className={['search-wrapper', containerActive && 'active' || '', hasResult && '-has-result' || ''].join(' ')}>
<div className={['search-wrapper', containerActive && 'active' || '', hasResult && '-has-result' || '', inProcess && '-in-process' || ''].join(' ')}>
<form onSubmit={this.onSubmit}>
<div className="input-holder">
<input className="search-input" type="url" id="playlistUrl" placeholder="Type to search" value={terms} onChange={e => this.setState({terms: e.target.value})} />
Expand Down
68 changes: 34 additions & 34 deletions src/components/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import { Form } from './form';
import { ButtonProgress } from './button-progress';

interface IMainState {
playlistUrl: string;
videos: IVideoEntity[];
process: boolean;
inProcess: boolean;
doneDownloading: boolean;
downloadProgress: string;
}
Expand All @@ -25,44 +24,44 @@ class Main extends React.Component<any, IMainState> {

this.state = {
videos: [],
process: false,
inProcess: false,
doneDownloading: false,
playlistUrl: 'https://www.youtube.com/playlist?list=PLtKALR6MChBz1gYizYPwjggc5BGAmYRRK',
// playlistUrl: 'https://www.youtube.com/playlist?list=PLtKALR6MChBz1gYizYPwjggc5BGAmYRRK',
downloadProgress: ''
};
}

componentDidMount() {
this.listenToDownloader();

this.setState({
videos: [
{
"id": "JvKKd32Yw2E",
"name": "video 1",
"progress": 0,
"status": EVideoStatus.NOT_STARTED
},
{
"id": "tPEE9ZwTmy0",
"name": "video 2",
"progress": 0,
"status": EVideoStatus.NOT_STARTED
},
{
"id": "cdwal5Kw3Fc",
"name": "video 3",
"progress": 0,
"status": EVideoStatus.NOT_STARTED
}
]
})
// this.setState({
// videos: [
// {
// "id": "JvKKd32Yw2E",
// "name": "video 1",
// "progress": 0,
// "status": EVideoStatus.NOT_STARTED
// },
// {
// "id": "tPEE9ZwTmy0",
// "name": "video 2",
// "progress": 0,
// "status": EVideoStatus.NOT_STARTED
// },
// {
// "id": "cdwal5Kw3Fc",
// "name": "video 3",
// "progress": 0,
// "status": EVideoStatus.NOT_STARTED
// }
// ]
// })
}

private fetchVideosClick = async () => {
this.setState({process: true});
const videos = await fetchVideos(this.state.playlistUrl);
this.setState({videos, process: false});
private fetchVideosClick = async (terms: string) => {
this.setState({inProcess: true});
const videos = await fetchVideos(terms);
this.setState({videos, inProcess: false});
}
private videoIndex = (videoId: string) => {
return this.state.videos.findIndex(v => v.id === videoId);
Expand Down Expand Up @@ -90,7 +89,7 @@ class Main extends React.Component<any, IMainState> {
const { videos } = this.state;
const videoIndex = this.videoIndex(videoId);
videos[videoIndex].status = EVideoStatus.DOWNLOADING;
videos[videoIndex].progress = 20 + (progress.percentage * 0.8);
videos[videoIndex].progress = 20 + Math.floor(progress.percentage * 0.8);
console.log(videos, 'progress');
this.setState({videos});
}
Expand Down Expand Up @@ -137,17 +136,18 @@ class Main extends React.Component<any, IMainState> {
}

public render() {
const { videos, downloadProgress } = this.state;
const { videos, downloadProgress, inProcess } = this.state;
return (
<div className="main">
<div className={isFFMpegInstalled() ? '' : 'hidden'}>
<Form
hasResult={!!videos.length}
onSubmit={this.fetchVideosClick}
onClear={() => this.setState({videos: []})}
inProcess={inProcess}
>
{videos.length &&
<ButtonProgress text="Download All" onClick={this.downloadAll} />
{videos.length ?
<ButtonProgress text="Download All" onClick={this.downloadAll} /> : ''
}
<div className="videos">
{videos.map(video => (
Expand Down
15 changes: 0 additions & 15 deletions src/components/video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,6 @@ export class Video extends React.Component<IVideoProps, any> {
super(props);
}

// buttonOrProgress() {
// const { video, onVideoStartClick } = this.props;

// if (video.status === EVideoStatus.NOT_STARTED) {
// return <button onClick={() => onVideoStartClick(video)}>Download "{video.name}"</button>
// } else {
// return (
// <div>
// <progress value={video.progress} max={100} /><br />
// Status: {video.status}
// </div>
// )
// }
// }

get backgroundImage(): string {
return `url(https://img.youtube.com/vi/${this.props.video.id}/mqdefault.jpg)`;
}
Expand Down
10 changes: 10 additions & 0 deletions src/styles/components/button-progress.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
letter-spacing: 1px;
font-size: 1em;
line-height: 2;
cursor: pointer;

.progress-wrap {
transform-style: preserve-3d;
Expand All @@ -34,6 +35,10 @@
position: relative;
display: block;

&:hover {
background: #095027;
}

&::before,
&::after {
position: absolute;
Expand Down Expand Up @@ -71,6 +76,7 @@
transform-origin: 50% 0%;
backface-visibility: hidden;
background: #148544;
line-height: 1.4;
}

.progress-inner {
Expand All @@ -81,6 +87,10 @@
top: 0;
}

.progress-counter {
position: relative;
}

.notransition {
transition: none !important;
}
Expand Down
14 changes: 14 additions & 0 deletions src/styles/components/form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
border-radius: 30px;
}

@include parent('.-in-process') {
animation: spinner 1s ease infinite;
}

span {
width:22px;
height:22px;
Expand Down Expand Up @@ -170,4 +174,14 @@

@media screen and (max-width: 560px) {
.search-wrapper.active .input-holder {width:200px;}
}

@keyframes spinner {
from {
transform: rotate(0deg);
}

to {
transform: rotate(360deg);
}
}
4 changes: 4 additions & 0 deletions src/styles/components/video.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@
align-items: center;
padding: 10px;
}

.name {
padding-right: 10px;
}
}

0 comments on commit e597ff0

Please sign in to comment.