项目作者: queenplay-associates

项目描述 :
A real-time collaborative screenplay text editor
高级语言: JavaScript
项目地址: git://github.com/queenplay-associates/coquill.git
创建时间: 2017-11-15T17:30:50Z
项目社区:https://github.com/queenplay-associates/coquill

开源协议:

下载


Coquill

Coquill is a real-time collaborative text editor for writing screenplays.
Based on your selection, the editor will automatically format your text and
provide text styling if need be. Once you have created a screenplay,
the editor will project colors on the page which map to the context of your text.
https://github.com/queenplay-associates/coquill

Created by ❤️ Eleni 💜 Samantha 💖 Christina 💙 Guang

Tech Stacks

*React, Redux, Firebase, Immutable.js, Webpack, Babel, React-hot-loader, Sentiment (in progress)*

Data Flow
  • Data from Coquill to Firebase 👆🏽🌪:
    • Typed words - - -> Redux (locally stored as a tree structure) - - > dispatched to Firebase (stored as a flat-ish list consisting of Redux actions, which carry the word character bits data)
    • Data from the Firebase to Coquill 🌧☟:
    • Database listens to each unique action key on change - - -> those listeners trigger Redux actions - - -> local state gets updated - - -> React component renders individually - Within the formatting toolbar, each formatting type generates an individual React component, this component also contains a reference key to its type (Action, Dialog, Scenes, etc) Ex: A screenplay might have 50+ rendered blocks, the State has potential fixed amount of child nodes. (Action, Dialog, Scene Headings, etc)
      The tree-like structure. The tree structure grows like that.
    • Each dispatched action with word content also carries writer’s info which is passed on from firebase Auth, when writing in Coquill, writer notice the other writer’s current editing place by pressing the ‘tab’ key.

Reducer sample

  1. export const setValue = (value, index, name) => ({
  2. type: SET_VALUE,
  3. value,
  4. componentKey: index,
  5. name
  6. })
  7. ...
  8. const reducer = (state = OrderedMap(), action) => {
  9. ...
  10. case INSERT_AFTER:
  11. itemsBefore = state.takeUntil(({key}) => key === action.afterKey)
  12. const after = state.get(action.afterKey)
  13. itemsAfter = state.skipUntil(({key}) => key === action.afterKey)
  14. .delete(action.afterKey)
  15. return itemsBefore
  16. .set(action.afterKey, after)
  17. .set(action.actionKey, {
  18. type: action.objectType,
  19. key: action.actionKey,
  20. })
  21. .merge(itemsAfter)
  22. ...
  23. case SET_VALUE:
  24. case CHANGE_TYPE:
  25. return state.update(action.componentKey, item => itemReducer(item, action))
  26. default: return state
  27. }
  28. }
  29. ...
  30. function itemReducer(item = {}, action) {
  31. const {type} = action
  32. if (type === SET_VALUE)
  33. return {...item, value: action.value, name: action.name}
  34. if (type === CHANGE_TYPE)
  35. return {...item, type: action.objectType}
  36. return item
  37. }

Firebase sample

  1. -Screenplays
  2. -L-Pdurudnr1DSlx08BO
  3. -actionKey: "-L-Pdurudnr1DSlx08BO"
  4. -componentKey: "-L-O8hlCEDLV_z3CPTYm" // each unqic action may share same componentKey
  5. -name: "SJ"
  6. -type: "SET_VALUE"
  7. -value: ""One of our biggest challenges was..."
  8. -Users
  9. -xOedKRr8zoVvKzhgby1xx0 //user's auth id
  10. -contributedScreenPlays: "Demo Day"
  11. -displayName: "Spike Jonze"
  12. -permissions
  13. -photoURL:

Get started:

  1. git clone git@github.com:queenplay-associates/coquill.git
  2. npm install
  3. npx firebase init
  4. npm start