Skip to content

Commit

Permalink
Merge pull request #22 from TriPSs/improvements
Browse files Browse the repository at this point in the history
Improvements
  • Loading branch information
TriPSs authored Aug 13, 2017
2 parents a7169c5 + b454b5f commit a9f3811
Show file tree
Hide file tree
Showing 96 changed files with 1,367 additions and 787 deletions.
56 changes: 4 additions & 52 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,6 @@
## Pull Requests
The branch to be PR'd against depends on what the feature is. If the PR is adding functionality that is related to the current release, it should be made towards the latest `release-x.x.x` branch. Otherwise, it should be made towards `dev-master`.
# Contributing

## Setup:
This project has **VERY** strict eslint rules. Adding eslint support to your text-editor will make contributing a lot easier.
We love pull requests from everyone. By participating in this project, you
agree to abide by the thoughtbot [code of conduct].

## Editor Configuration
### Atom
Recommended Development Packages:
```bash
apm install editorconfig es6-javascript javascript-snippets linter linter-eslint language-babel autocomplete-flow
```

### Sublime
* https://github.com/sindresorhus/editorconfig-sublime#readme
* https://github.com/SublimeLinter/SublimeLinter3
* https://github.com/roadhump/SublimeLinter-eslint
* https://github.com/babel/babel-sublime

## FAQ
* `CALL_AND_RETRY_LAST Allocation failed`: If your node process's heap runs out of memory (`CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory`), kill close the electron app and restart the electron process. A proper solution hasn't been found for this yet.
* Build Fails: If your build fails, make sure you're using the latest node and npm versions and try running the following steps:
```console
npm cache clean
rm -rf node_modules
npm i
npm rb
```
If you have cloned this project and haven't pulled changes incrementally, delete the entire project directory and start from scratch
If that fails, try [reinstalling xcode](https://github.com/chentsulin/electron-react-boilerplate/issues/383#issuecomment-246428151)

### Others
* [Editorconfig](http://editorconfig.org/#download)
* [ESLint](http://eslint.org/docs/user-guide/integrations#editors)
* Babel Syntax Plugin

## Development Tooling
The Redux devtools are hidden by default and can be shown with `ctrl + h`

## Dependencies
* All dependencies are `devDependencies`.

## Code Conventions
* Code style:
* Imports must have at least two lines after them
* All function declarations and expressions must include parameter type annotations. Callbacks should not be annotated
* All destructured imports should be broken down into new lines.
* Functional Programming
* Use **pure functions** when possible
* Use Array `.map`, `.reduce`, and `.filter` instead of for loops
* Avoid all mutation, use the ES6 spread instead
* React
* Use Higher Order Components when possible
* Avoid `setState` as much as possible! Use **Redux** to update the state.
[code of conduct]: https://thoughtbot.com/open-source-code-of-conduct
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<h1 align="center">
<img height="200" width="200" src="resources/background.png" alt="logo" />
<img height="200" width="200" src="./resources/logo.png" alt="logo" />
<br />
Popcorn Time
</h1>
Expand All @@ -13,11 +13,14 @@
<a target="_blank" href="https://ci.appveyor.com/project/tripss/popcorn-time-desktop/branch/master">
<img src="https://ci.appveyor.com/api/projects/status/071qeglg94au8wr2/branch/master?svg=true&maxAge=86400" alt="AppVeyor Build status" />
</a>
<a target="_blank" href="https://david-dm.org/tripss/popcorn-time-desktop?type=dev">
<img src="https://img.shields.io/david/dev/tripss/popcorn-time-desktop.svg?maxAge=86400" alt="npm dev dependencies" />
<a target="_blank" href="https://david-dm.org/tripss/popcorn-time-desktop" title="dependencies status">
<img src="https://david-dm.org/tripss/popcorn-time-desktop/status.svg"/>
</a>
<a target="_blank" href="https://gitter.im/amilajack/popcorn-time-desktop?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge">
<img src="https://badges.gitter.im/amilajack/popcorn-time-desktop.svg" alt="Gitter" />
<a target="_blank" href="https://david-dm.org/tripss/popcorn-time-desktop?type=dev" title="devDependencies status">
<img src="https://david-dm.org/tripss/popcorn-time-desktop/dev-status.svg"/>
</a>
<a target="_blank" href="https://gitter.im/popcorn-time-desktop/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge">
<img src="https://badges.gitter.im/popcorn-time-desktop.svg" alt="Gitter" />
</a>
<a target="_blank" href="https://github.com/tripss/popcorn-time-desktop/pulls">
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome" />
Expand Down Expand Up @@ -70,15 +73,15 @@ npm run package
Please see the [contributing guide](https://github.com/tripss/popcorn-time-desktop/blob/master/CONTRIBUTING.md)

## Todos:
See the [roadmap](https://github.com/tripss/popcorn-time-desktop/wiki/Road-Map-and-Progress) for the full list.
See the [milestones](https://github.com/TriPSs/popcorn-time-desktop/milestones) for the full list.

## Screenshots

### Home Page:
![Home Page](https://raw.githubusercontent.com/TriPSs/popcorn-time-desktop/master/images/home.png)
![Home Page](./images/home.png)

### Movie Page:
![Movie page](https://raw.githubusercontent.com/TriPSs/popcorn-time-desktop/master/images/movie.png)
![Movie page](./images/movie.png)

### Show page:
![Show page](https://raw.githubusercontent.com/TriPSs/popcorn-time-desktop/master/images/show.png)
![Show page](./images/show.png)
2 changes: 2 additions & 0 deletions app/api/Butter.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ export default new (class {

getMovies = (page: number = 1, filters: Object = {}) => (
this.pctAdapter.getMovies(page, filters)
.then(this.metadataAdapter.updateMoviesWatched)
)

getMovie = (itemId: string) => (
this.pctAdapter.getMovie(itemId)
.then(this.metadataAdapter.updateMovieWatched)
)

getShows = (page: number = 1, filters: Object = {}) => (
Expand Down
4 changes: 4 additions & 0 deletions app/api/Database/Database.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import WatchedDB from './Watched'
import BookmarksDB from './Bookmarks'
import MoviesDB from './Movies'
import ShowsDB from './Shows'
import SettingsDB from './Settings'

const log = debug('api:database')

Expand All @@ -18,6 +19,8 @@ export class Database {

shows: ShowsDB

settings: SettingsDB

constructor() {
const dbLocation = remote.app.getPath('userData')

Expand All @@ -27,6 +30,7 @@ export class Database {
this.bookmarks = new BookmarksDB(dbLocation)
this.movies = new MoviesDB(dbLocation)
this.shows = new ShowsDB(dbLocation)
this.settings = new SettingsDB(dbLocation)
}

}
Expand Down
1 change: 1 addition & 0 deletions app/api/Database/Settings/SettingsConstants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DISCLAIMER = 'disclaimer'
46 changes: 46 additions & 0 deletions app/api/Database/Settings/SettingsDB.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import Datastore from 'nedb'

export default class {

db: Datastore

constructor(dbLocation: string) {
this.db = new Datastore({
filename: `${dbLocation}/data/settings.db`,
autoload: true,
})

this.db.ensureIndex({
fieldName: 'key',
unique : true,
})
}

add = (key: string, value: string) => new Promise(resolve => this.db.insert({ key, value }, resolve))

get = (key: string) => new Promise(resolve => this.db.find({ key }, (error, docs) => {
if (error) {
return resolve({ error, docs })
}

if (!docs.length) {
return resolve({ error, docs: false })
}

if (docs.length && docs.length === 1) {
return resolve({ error, docs: docs[0] })
}

return resolve({ error, docs })

}))

getAll = () => new Promise(resolve => this.db.find({}, (error, docs) =>
resolve({ error, docs }),
))

update = (key: string, value: string) => new Promise(resolve => this.db.update({ key, value }, resolve))

remove = (key: string) => new Promise(resolve => this.db.remove({ key }, resolve))

}
3 changes: 3 additions & 0 deletions app/api/Database/Settings/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import SettingsDB from './SettingsDB'

export default SettingsDB
23 changes: 15 additions & 8 deletions app/api/Database/Watched/WatchedDB.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,25 @@ export class WatchedDB {
resolve(),
))

markMovieWatched = (id: string) => this.markWatched({ id, type: 'movie' })
markMovieWatched = (id: string, percentage: number) => this.markWatched({ id, percentage, type: 'movie' })

markMovieUnWatched = (id: string) => this.unmarkWatched({ id, type: 'movie' })

getMoviesWatched = () => new Promise(resolve => this.db.find({ type: 'movie' }, (error, docs) =>
resolve(docs.map(item => item.id)),
resolve({ error, docs }),
))

updateMoviePercentage = (id: string, percentage: number) =>
new Promise(resolve =>
this.db.update({ id, type: 'movie' }, { $set: { percentage } }, {}, (err, numAffected) => {
if (!numAffected) {
this.markMovieWatched(id, percentage).then(resolve)

} else {
resolve()
}
}))

markEpisodeNotWatched = (showId: string, season: string, episode: string) =>
this.unmarkWatched({ showId, season, episode, type: 'episode' })

Expand All @@ -45,12 +56,8 @@ export class WatchedDB {
}))

getEpisodesWatchedOfShow = (showId: string) => new Promise(resolve =>
this.db.find(
{
showId,
type: 'episode',
}, (error, docs) => resolve({ error, docs }),
))
this.db.find({ showId, type: 'episode' }, (error, docs) => resolve({ error, docs })),
)

}

Expand Down
4 changes: 3 additions & 1 deletion app/api/Database/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export default from './Database'
import Database from './Database'

export default Database
29 changes: 26 additions & 3 deletions app/api/Metadata/MetadataAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import Database from 'api/Database'
import { MetadataProviderInterface } from './MetadataProviderInterface'
import TraktMetadataProvider from './TraktMetadataProvider'
import TmdbMetadataProvider from './TmdbMetadataProvider'
import type { MovieType } from './MetadataTypes'

export class MetadataAdapter implements MetadataProviderInterface {
export default class MetadataAdapter implements MetadataProviderInterface {

trakt: TraktMetadataProvider

Expand All @@ -22,6 +23,28 @@ export class MetadataAdapter implements MetadataProviderInterface {
)
})

}
updateMoviesWatched = (pctMovies: Array<MovieType>) => new Promise((resolve) => {
Database.watched.getMoviesWatched().then(({ docs }) => resolve(pctMovies.map(pctMovie => ({
...pctMovie,
watched: this.getMovieWatched(pctMovie, docs),
}))))
})

updateMovieWatched = (pctMovie: MovieType) => new Promise((resolve) => {
Database.watched.getMoviesWatched().then(({ docs }) => resolve({
...pctMovie,
watched: this.getMovieWatched(pctMovie, docs),
}))
})

export default MetadataAdapter
getMovieWatched = (movie, watchedMovies) => {
const movieWatched = watchedMovies.find(watchedMovie =>
watchedMovie.id === movie.id,
)

return {
complete: movieWatched ? movieWatched.percentage > 95 : false,
progress: movieWatched ? movieWatched.percentage : false,
}
}
}
5 changes: 4 additions & 1 deletion app/api/Metadata/MetadataTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ export type ContentType = {
export type MovieType = ContentType & {
certification: string,
trailer: string,
watched: boolean,
watched: {
complete: boolean,
progress: number,
},
torrents: {
'1080p': TorrentType,
'720p': TorrentType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export default class TmdbMetadataProvider implements MetadataProviderInterface {

return {
complete: episodeWatched ? episodeWatched.percentage > 95 : false,
progress: episodeWatched ? episodeWatched.percentage : false,
progress: episodeWatched ? episodeWatched.percentage : 0,
}
}

Expand Down
40 changes: 18 additions & 22 deletions app/api/Player/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { Props } from './PlayerTypes'

const log = debug('api:player')

export class Player extends ReduxClazz implements PlayerProviderInterface {
export default class extends ReduxClazz implements PlayerProviderInterface {

plyrAdapter: PlyrPlayerProvider

Expand All @@ -35,17 +35,21 @@ export class Player extends ReduxClazz implements PlayerProviderInterface {
constructor(...props) {
super(...props)

this.plyrAdapter = PlyrPlayerProvider
this.plyrAdapter = new PlyrPlayerProvider()
}

clazzWillReceiveProps = (nextProps) => {
const { action: oldAction, torrentStatus: oldTorrentStatus } = this.props
const { action: newAction, torrentStatus: newTorrentStatus } = nextProps
const { playerStatus: oldPlayerStatus, action: oldAction, torrentStatus: oldTorrentStatus } = this.props
const { playerStatus: newPlayerStatus, action: newAction, torrentStatus: newTorrentStatus } = nextProps

if (oldPlayerStatus !== newPlayerStatus && newPlayerStatus === PlayerConstants.STATUS_ENDED) {
this.destroy()
}

if (newTorrentStatus !== oldTorrentStatus) {
if ((newTorrentStatus === TorrentConstants.STATUS_BUFFERED
|| newTorrentStatus === TorrentConstants.STATUS_DOWNLOADED)
&& this.getStatus() !== PlayerConstants.STATUS_PAUSED) {
|| newTorrentStatus === TorrentConstants.STATUS_DOWNLOADED)
&& this.getStatus() === PlayerConstants.STATUS_NONE) {
const { uri, item } = nextProps

this.play({ uri, item })
Expand Down Expand Up @@ -82,8 +86,10 @@ export class Player extends ReduxClazz implements PlayerProviderInterface {

break

case PlayerConstants.ACTION_CONTINUE:
case PlayerConstants.ACTION_PAUSE:
this.pause()
this.getRightPlayer().togglePlay()

break

case PlayerConstants.ACTION_STOP:
Expand All @@ -105,22 +111,14 @@ export class Player extends ReduxClazz implements PlayerProviderInterface {
}
}

pause = () => {
if (this.getRightPlayer().isPlaying()) {
this.getRightPlayer().pause()
}
}

stop = () => {
if (this.getRightPlayer().status !== PlayerConstants.STATUS_NONE) {
this.getRightPlayer().stop()
this.getRightPlayer().destroy()
}
this.getRightPlayer().stop()
this.getRightPlayer().destroy()

this.destroy()
}

getStatus = () => this.props.playerStatus
getStatus = () => this.getRightPlayer().status

getRightPlayer = (): PlayerProviderInterface => {
const { provider } = this.props
Expand All @@ -144,13 +142,11 @@ export class Player extends ReduxClazz implements PlayerProviderInterface {
log('Destroy player')
Torrent.destroy()

if (this.lastPlayer) {
this.lastPlayer.destroy()
if (this.getRightPlayer()) {
this.getRightPlayer().destroy()

this.streamingProviders.map(provider => provider.destroy())
}
}

}

export default Player
Loading

0 comments on commit a9f3811

Please sign in to comment.