[Electron + Angular + TypeScript] Venobo Streaming App

Wess

BYPASSING OVERRIDE
Staff member
FindRetros Moderator
Messages
3,783
Likes
2,111
#21
Cleaned the thread and warned everyone who either insulted other users or started off-topic posting. This counts for both @Sentinel and @Aeternum - if any of you can't behave, I'll warn you for every single off-topic or insulting post, even if it are multiple on one thread. You're both good developers - help each other with constructive critism instead of slandering each other.
 
Messages
1,398
Likes
664
#22
This looks amazing, good luck :D
Thanks man!
 
After going through some simplicity with ReactJS, I must say I really enjoy this library, it especially makes Electron development 100 times easier.
Just gone through in my head what I want to do with the TMDb API, and decided to code some simple parts of it.
The current component is mostly just for trying out React, so it will most likely be improved a lot before production.
PHP:
import React from 'react'
import axios from 'axios'

export default class TMDb extends React.Component {

  constructor(props) {
    //super(props)

    this.tmdb = require(__dirname + '/../config.json').tmdb

    this.state = {
      api: `${this.tmdb.api}/${props.type}/${props.id}`,
      add: `?api_key=${this.tmdb.key}&language=${props.lang}`
    }
  }

  setApi(type, id) {
    this.setState({api: `${this.tmdb.api}/${type}/${id}`})
  }

  setAdd(lang) {
    this.setState({add: `?api_key=${this.tmdb.key}&language=${lang}`})
  }

  getSimilarMovies() {
    return this.tmdbGet(`/similar${this.state.add}&page=1`).data
  }

  getDetails() {
    let details = this.tmdbGet(`${this.state.add}`).data

    return details
  }

  tmdbGet(extra = '') {
    axios.get(`${this.state.api}${extra}`)
      .then((response) => {
        return response
      })
  }

}
 
Just a preview of the Window Component for all the curious folks
PHP:
import React from 'react'
const win = window.require('electron').remote.getCurrentWindow()

export default class Window extends React.Component {

  constructor(props) {
    super(props)

    this.handleClose = this.handleClose.bind(this)
    this.handleMinimize = this.handleMinimize.bind(this)
    this.handleMaximize = this.handleMaximize.bind(this)
  }

  handleClose() {
    win.close()
  }

  handleMinimize() {
    win.minimize()
  }

  handleMaximize() {
    if(!win.isMaximized()) {
        win.maximize()
    } else {
        win.unmaximize()
    }
  }

  render() {
    return (
      <div className="menu-window">
        <span className="menu-button close" onClick={this.handleClose}></span>
        <span className="menu-button minimize" onClick={this.handleMinimize}></span>
        {this.props.maximize ? (
          <span className="menu-button maximize" onClick={this.handleMaximize}></span>
        ) : (
          <span className="menu-button inactive"></span>
        )}
      </div>
    )
  }

}
There's sadly this thing with renders in ReactJS, that it can only return a single element. So let's say you got five different divs in the renderer, then you'd have to wrap them inside a div so that it only returns a single element. Possibly ruin of CSS styles
 
#UPDATES
Added the below components to the app
[ To view this link you must register here. ]
 
I've created a git repo for this project:
[ To view this link you must register here. ]
 

Wess

BYPASSING OVERRIDE
Staff member
FindRetros Moderator
Messages
3,783
Likes
2,111
#23
You're making some good progress with this. Looks really good so far.
 
Messages
1,398
Likes
664
#24
You're making some good progress with this. Looks really good so far.
Haha yeah, I've definitely put some time into this.
Didn't take a look at the time, so I went to bed at 6am, because I wanted to restructure the whole project.
Thanks for the feedback
 
#UPDATES
I've managed to code the app responsive.
I think I will get rid of that horrible scrollbar next.

 

griimnak

You're a slave to the money then you die
Messages
904
Likes
746
#25
Haha yeah, I've definitely put some time into this.
Didn't take a look at the time, so I went to bed at 6am, because I wanted to restructure the whole project.
Thanks for the feedback
 
#UPDATES
I've managed to code the app responsive.
I think I will get rid of that horrible scrollbar next.

Coming along nicely, looking forward to all the logical stuff like user view history, ect.
I'd probably start that stuff soon if i were you, i'd hate to see you put all the effort into the design then bail on the logic.
 
Messages
1,398
Likes
664
#26
Coming along nicely, looking forward to all the logical stuff like user view history, ect.
I'd probably start that stuff soon if i were you, i'd hate to see you put all the effort into the design then bail on the logic.
Same here, I've just not begun all the logical stuff on the app yet, since I need to understand React atleast 90% first.
 

Wess

BYPASSING OVERRIDE
Staff member
FindRetros Moderator
Messages
3,783
Likes
2,111
#30
How is that even close to being similar? That's just an app that you can play music from using SoundCloud's API.
I guess he's talking about the design, and I can see where he's coming from. But eventually everything will look like something else, as almost everything has already been done (atleast, if you want to keep it really minimalistic).
 
Messages
1,398
Likes
664
#31
I guess he's talking about the design, and I can see where he's coming from. But eventually everything will look like something else, as almost everything has already been done (atleast, if you want to keep it really minimalistic).
Oh yeah right, I suddenly got confused. Actually I got the design idea from this below.
 

griimnak

You're a slave to the money then you die
Messages
904
Likes
746
#32
Hmmm your project looks really familiar...

[ To view this link you must register here. ]
That's actually pretty dumb of you to say.

The only similarity I can honestly see here is the two column design with side bar, and black osx window frame.


Also, I'm pretty sure if @Sentinel ripped this exact project he would of kept the good design ideas like the top left player card and top right gear and the left/right navi next to window charms.


And from the looks of the code, @Sentinel is actually doing it more neater than cloudnode
 
Messages
1,398
Likes
664
#33
That's actually pretty dumb of you to say.

The only similarity I can honestly see here is the two column design with side bar, and black osx window frame.


Also, I'm pretty sure if @Sentinel ripped this exact project he would of kept the good design ideas like the top left player card and top right gear and the left/right navi next to window charms.


And from the looks of the code, @Sentinel is actually doing it more neater than cloudnode
Well I really do wish I had the experience to code a design like that, but unfortunately I don't.
I got my design ideas from [ To view this link you must register here. ]
 
Messages
362
Likes
162
#34
There's not much you can do with a streaming app either, i mean - spotify has a similar style to both of these - [ To view this link you must register here. ]
 
Messages
1,398
Likes
664
#35
There's not much you can do with a streaming app either, i mean - spotify has a similar style to both of these - [ To view this link you must register here. ]
Then it's good it's not an audio streaming app I'm developing :D
 
#UPDATES
If all goes as planned, there will be released a beta version of the app the weekend after this one.
Adding tons of movies is easy, but it's boring, so what I am planning to do, is make some sort of request page for the community, where people can vote for whatever movies or tv show they'd like to see added next. Also some users will be given a rank, so they have the opportunity to add new documents to the database, so that it becomes more community related.

Because of my school game development project this week, I haven't really found any energy to code on this when I get home, so the Git will first be updated on sunday.

I might also switch out React with some other front-end framework. In my opinion it really decreases your productivity, since there's a lot of stuff it doesnt allow/have the capability to work with.

Haven't found a decent name for the app. Primely seems way too unrelated and a lot of people I know are having problems pronouncing it (they're morons so probably why)
 
#UPDATES
Instead of writing all my updates, I will instead be posting videos on YouTube to show the progress.
Currently I've coded the quick search function

[ To view this link you must register here. ]
 
Well, I decided to ditch the other design as it was trash.
Here's some screens of the new:


Don't mind the working title.
 

griimnak

You're a slave to the money then you die
Messages
904
Likes
746
#36
This was beginning to look good: [ To view this link you must register here. ]
But now you ditched the design -.-
 
Messages
1,398
Likes
664
#39
Hmm it looks good, but it doesn't make me think movies or TV in general. It looks like a login but not for something of this nature. But that's just my 2 cents
Nah, you're definitely right.
Relevant or not, it still looks quite nice.
The design before just looked way too shady (and definitely illegal kinda)
 
#UPDATES
I've decided to code an offline mode aswell as a caching system to get faster performance.
Everytime a HTTP requests gets made, it caches the data for 1 hour otherwise it caches new data, or if the computer is offline, it'll just use the latest cache.
components/cache.js
PHP:
import config from '../../config'
import fs from 'fs'
import path from 'path'
import rimraf from 'rimraf'
import md5 from 'crypto-js/md5'

export default class Cache {

  static write(key, data, callback) {
    if(data instanceof String) data = data.toString()
    if(typeof data != "string") data = JSON.stringify(data)

    this.exists(key, (res) => {
      if(res) this.purgeSync(key)

      fs.writeFileSync(this.getPath(key), data, {flag: 'wx'})
      callback(data)
    })
  }

  static read(key, callback) {
    let data = fs.readFileSync(this.getPath(key))
    callback(data.toString())
  }

  static exists(key, callback) {
    fs.stat(this.getPath(key), (err, stat) => {
      callback(!err, stat)
    })
  }

  static isExpired(key, callback) {
    this.exists(key, (res, stat) => {
      if(!res) {
        callback(true)
      } else {
        let now = new Date().getTime(),
            endTime = new Date(stat.ctime).getTime() + 3600000

        callback(now > endTime)
      }
    })
  }

  static getPath(key) {
    return path.join(config.CACHE_PATH, md5(key) + '.js')
  }

  static purge(key, callback) {
    fs.unlink(this.getPath(key), callback)
  }

  static purgeSync(key) {
    return fs.unlinkSync(this.getPath(key))
  }

  static trash(callback) {
    rimraf(config.CACHE_PATH, callback)
  }

}
components/http.js
PHP:
import Cache from './cache'
import Axios from 'axios'

export default class HTTP {

  static get(url, callback) {
    if(navigator.onLine) {
      Axios.get(url)
        .then((res) => {
          Cache.isExpired(url, (is) => {
            if(!is) {
              Cache.read(url, callback)
            } else {
              Cache.write(url, res.data, callback)
            }
          })
        })
        .catch((err) => {
          console.log(err)
          this.parse(url, callback)
        })
    } else {
      this.parse(url, callback)
    }
  }

  static post() {

  }

  static parse(url, callback) {
    Cache.exists(url, (res) => {
      if(res) {
        Cache.read(url, callback)
      } else {
        console.log("something went wrong with get requests, and cache doesnt exist")
      }
    })
  }

}
Still need some fixes but close being there.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Top