mikeal / roll-call

📞 Free and reliable audio calls for everyone w/ browser p2p.
https://rollcall.audio
1.57k stars 111 forks source link

Move to React js ? #41

Closed sai-prasanna closed 7 years ago

sai-prasanna commented 8 years ago

As we start adding more features, and UI , I think it would be great if we move to React js + Redux ?

WebReflection commented 8 years ago

I'd rather use custom elements and make <roll-call> an element compatible with the entire Web, instead of locking it in already with one framework or another.

<roll-call-room> could also be used as container for multiple conferences, and used on the home page.

If interested, I'm up for a PR.

mikeal commented 8 years ago

I've actually been struggling with finding the best way to build re-usable HTML+CSS+JS components.

I agree with @WebReflection that we shouldn't rely on a vertically integrated framework like React. I'm +1 on custom elements, and we can use them without something like polymer because we don't have to worry about older browsers (they don't support WebRTC anyway).

I just still don't know the best way to structure code for components in a sane way. There's a lot of state that moves around the different components.

The best way to approach any structural changes like this would be to tackle the component for playing audio files first (the one that shows up if you drag and drop an audio file). It's the least statefully integrated with other components and would also be the easiest to test in isolation without the rest of Roll Call.

chromakode commented 8 years ago

For our UI code, I think it would be helpful to use a "props down, events up" style. This approach helps separate concerns and reduces statefulness/dependencies between view code. Ideally most of our UI code should be "dumb components", which only concern themselves with transforming data into DOM. This is a boon for OSS contributors, because this separation means you can hack on UI layout without understanding the audio underpinnings, and vice versa.

I'm not too versed in the specifics of Web Components -- it might be possible to implement this pattern using just DOM attributes and event handlers. However, a hybrid approach might be possible in which we expose Web Components for public reuse, and use a lightweight component library under the hood. Preact is very small, implements an API many potential roll-call contributors are familiar with, and has no sub-dependencies. DOM diffing is also a pretty big win for rapidly changing UIs like roll-call.

Since the UI code is pretty small, I think it'd be worthwhile to try rewriting the UI using something like Preact to get a feel for this.

chromakode commented 8 years ago

As for getting state into components, there's a lot of options here. Ideally, the audio and room state should be separate from the view code, in a way that views can subscribe to update when the room state changes.

For example: Redux accomplishes this by putting all your app state in a big top-level "store" object, which you connect to views. Changes to UI state are dispatched to the store, which updates its value, causing the connected views to update.

Mobx is another option. It provides a structure for observing changes to the state of your application with some neat optimizations because it understands fine-grained data dependencies for views.

There's a ton more choices, and many (including the above) are agnostic to how the views portion is implemented.

The key point I'd like to make is that we should think about modeling the state as an actual object (or observable) somewhere with a value. This makes it easier to write the view code because it only concerns itself with transforming that state value into DOM. It also makes it easier to think about the lifecycle and structure of code that updates that state, such as the room data handling and audio code.

sai-prasanna commented 8 years ago

@mikeal Is this project a reusable component or a product for users?

If its a open source product then I think going with React + State management with Redux will be one of the best ways to go forward. Because imho we should be making it easy to add new stuff in long run.

And with some work we can even make it a reusable container type thing which other projects can add , with wrapper API. But yeah still it will depend on React(or any other thing we use for state + view management).

WebReflection commented 8 years ago

Custom Elements != Web Components ... moreover, it's native.

It's faster than anything else and it's lighter 'cause it needs no library.

I don't understand how we reached this point on the Web where overengineering becomes the only way to move forward.

I hope this project will keep it simple and natively compatible for the entire Web, it'd be a shame if a website would have to introduce so many levels of indirection to simply stream a call (and the original goal would fade with such decision).

Best Regards

sarbbottam commented 8 years ago

Custom Elements != Web Components

I have always considered them as same until now.

For any one like me, hope the following helps:

Custom Elements are a subset of Web Components specification. All Custom Elements are Web Components but not all Web Components are Custom Elements.

I guess != is kind of misleading, it should have been ∈. Please excuse my ignorance.

WebReflection commented 8 years ago

yes, that symbol is better, just not on my keyboard so I've used != because Web developers still think to use Custom Elements you need to have Web Components.

<roll-call> is a Custom Element that doesn't need template, HTML imports, shadow DOM, and it's been polyfilled down to Android 2 and IE8.

It's native on Chrome, and it's landing natively on every other browser too.

polyfill for old V0 and new V1 APIs here

Best Regards

chromakode commented 8 years ago

Custom Elements != Web Components

Thanks for clarifying this. I haven't looked at these APIs in a while.

It looks like we could readily implement "props down, events up" using custom elements with bel/funky for templates. The fact that custom elements work naturally inside a bel template is a big win. Probably worth completing the yo-yo and pulling in morphdom because dom-diffing makes deeply nesting components faster and easier to write (since components persist over re-renders).

I think Preact is also worth considering for two benefits: it implements dom-diffing (w/ shouldComponentUpdate for easy perf wins) and it offers an API that will be familiar to a lot of contributors. It's 3kb of readable code and works with hyperx. It also looks like there's an easy way to make custom elements out of Preact components.

WebReflection commented 8 years ago

I'm not sure I understood anything you wrote but just to add some info, Custom Elements can be easily integrated and consumed/used/created in React, Angular, YouNameIt ^_^

bmathews commented 8 years ago

This weekend I started a branch that uses Inferno for the view and a single EventEmitter store for the 'props down, events up' data flow. Since all the view is 100% decoupled from the store, switching to something like custom elements would probably only take an hour or two on my branch.

You all moved pretty quickly over the weekend so this got out of date pretty quickly, but here's the current work in progress state of it: https://github.com/bmathews/roll-call/blob/reorg/store.js with views looking like: https://github.com/bmathews/roll-call/blob/reorg/views/remoteAudio.js

I don't know if I'll be able to finish it while keeping up with the speed things are changing here, so I'm not concerned if none of that code gets used, but I'm glad to see we're all in agreement that there needs to be a bit more structure in the UI and data flow.

sai-prasanna commented 8 years ago

@WebReflection

"In reality, there isn’t a reliable project that accomplishes this. This problem also gets more complicated as we add some important additional requirements.

People in countries that sanction censorship and block services should be able to access it reliably. Third parties (like Governments) should not be able to track users or listen to calls. Users should be able to record calls to produce new media like podcasts."

So its not just streaming stuff, it plans to be a opensource skype like software, and it is not over engineering as much as not reinventing the wheel.

Predictable State management, and UI will allow lots of features to be added fast with little overhead.

mikeal commented 8 years ago

I think that we should all jump on a call to discuss this. We can record it using Roll Call and publish for other people to listen and learn from as well :)

marvinrichter commented 8 years ago

I think this discussion mixes up two different types of UI components.

One is the functional type, another is the presentational type.

For the functional types I totally agree with @WebReflection that they should be implemented in framework agnostic model (maybe even in a separate module/repo like roll-call-elements). Custom Elements would be the best way to go here.

For the actual site providing the first implementation of a roll-call service I would create another module/repo like roll-call-site which uses React, Redux and roll-call-elements.

For information about Custom Elements I highly suggest reading The Case for Custom Elements from Rob Dodson

mikeal commented 8 years ago

A single embeddable custom element with no react/redux dependency would be a good first step though, I think. I can't think of anything that would be roll-call-site specific.

We're not too far away from this now. It would essentially be everything in <div id="audio-container"> turned into a Web Component and the dependencies on semantic-ui removed or in-lined.

marvinrichter commented 8 years ago

Of course the functional elements would be the first step. Hiding everything related to a roll-call inside it's implementation would not be the best approach though. Imagine some site wants to show the list of participants on the left, some wants it on the right, another doesn't want to show it at all.

Sure it could be done with CSS floating but that would break a11y stuff like tab order, focus and so on.

I would suggest something more component oriented and maybe provide an opinionated element like <roll-simple-call />.

marvinrichter commented 8 years ago

We're not too far away from this now. It would essentially be everything in <div id="audio-container"> turned into a Web Component and the dependencies on semantic-ui removed or in-lined.

I could do that :)

mikeal commented 8 years ago

@marvinrichter I'd love to see that PR :) you should also check out @bmathews' branch.

marvinrichter commented 8 years ago

I'll jump right on it :)

bmathews commented 8 years ago

Eventing and exposing key state could solve that in an easier way, potentially.

<roll-call room="party" />

const rc = document.querySelector('roll-call')
rc.addEventListener('onUpdate', (room) => {
  document.getElementById('my-user-list').innerHTML = room.users.map(u => u.name).join(', ');
});
bmathews commented 8 years ago

Ah, I misunderstood what you were getting at actually, which is moving existing internal components around. Carry on!

marvinrichter commented 8 years ago

exactly :)

mikeal commented 8 years ago

If we tried to do a call at 4pm PT today on this, who would be able to join?

WebReflection commented 8 years ago

not me :-(

chromakode commented 8 years ago

Can't make it then, sorry :(

mikeal commented 8 years ago

Let's try this again, when can people meet :) http://www.needtomeet.com/meeting?id=48tykfcpV

mikeal commented 7 years ago

New version uses raw WebComponents. Much better for embedability and modularity than React.