mirror of
https://github.com/ilyakooo0/urbit.git
synced 2025-01-05 13:55:54 +03:00
work
This commit is contained in:
parent
9081b3a278
commit
743b0a632e
33
pub/work/fab/hymn.hook
Normal file
33
pub/work/fab/hymn.hook
Normal file
@ -0,0 +1,33 @@
|
||||
::
|
||||
::
|
||||
:::: /hook/hymn/fab/talk/pub/
|
||||
::
|
||||
|%
|
||||
++ cdnj
|
||||
|= a=wall ^- marl
|
||||
%+ turn a
|
||||
|= lib=tape
|
||||
;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/{lib}");
|
||||
--
|
||||
::
|
||||
::::
|
||||
::
|
||||
^- manx
|
||||
;html
|
||||
;head
|
||||
;meta(charset "utf-8");
|
||||
;* %- cdnj :~
|
||||
"jquery/2.1.1/jquery.js"
|
||||
"lodash.js/2.4.1/lodash.min.js"
|
||||
"react/0.13.1/react.js"
|
||||
==
|
||||
;meta(name "viewport", content "width=device-width, height=device-height, ".
|
||||
"initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0");
|
||||
;link(type "text/css", rel "stylesheet", href "/home/pub/work/src/css/main.css");
|
||||
;title: Talk
|
||||
==
|
||||
;body
|
||||
;div#c;
|
||||
;script(type "text/javascript", src "/home/pub/work/src/js/main.js");
|
||||
==
|
||||
==
|
84
pub/work/src/css/fonts.styl
Normal file
84
pub/work/src/css/fonts.styl
Normal file
@ -0,0 +1,84 @@
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau.woff");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-italic.woff");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-medium.woff");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-bold.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-super.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-superitalic.woff");
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-extralight.woff");
|
||||
font-weight: 200;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-light.woff");
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-regular.woff");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-medium.woff");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-bold.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-black.woff");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
235
pub/work/src/css/main.css
Normal file
235
pub/work/src/css/main.css
Normal file
@ -0,0 +1,235 @@
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau.woff");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-italic.woff");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-medium.woff");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-bold.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-super.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/bau-superitalic.woff");
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-extralight.woff");
|
||||
font-weight: 200;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-light.woff");
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-regular.woff");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-medium.woff");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-bold.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-black.woff");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
font-family: "bau";
|
||||
font-size: 18px;
|
||||
}
|
||||
#c {
|
||||
position: absolute;
|
||||
top: 0rem;
|
||||
left: 50%;
|
||||
width: 34rem;
|
||||
margin-left: -17rem;
|
||||
margin-bottom: 12rem;
|
||||
}
|
||||
h1 {
|
||||
font-weight: 500;
|
||||
}
|
||||
.items {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
.item {
|
||||
display: block;
|
||||
max-height: 3rem;
|
||||
margin-bottom: 1.5rem;
|
||||
width: 36rem;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
transition: max-height 200ms linear;
|
||||
}
|
||||
.item .comments {
|
||||
height: 0;
|
||||
}
|
||||
.item.expand {
|
||||
max-height: 16rem;
|
||||
transition: max-height 200ms linear;
|
||||
}
|
||||
.item .expand {
|
||||
margin-left: 2rem;
|
||||
cursor: pointer;
|
||||
transform-origin: 3px 12px;
|
||||
transition: transform 200ms linear;
|
||||
}
|
||||
.item.expand .expand {
|
||||
transform: rotate(90deg);
|
||||
transition: transform 200ms linear;
|
||||
}
|
||||
.item .sort,
|
||||
.item .title,
|
||||
.item .date,
|
||||
.item .tags,
|
||||
.item .comment {
|
||||
line-height: 2rem;
|
||||
}
|
||||
.item .sort,
|
||||
.item .date {
|
||||
font-family: 'scp';
|
||||
}
|
||||
.item .audience,
|
||||
.item .date {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
.item .audience,
|
||||
.item .sort {
|
||||
color: #ccc;
|
||||
}
|
||||
.item .audience {
|
||||
text-transform: uppercase;
|
||||
height: 1rem;
|
||||
letter-spacing: 0.07rem;
|
||||
margin-left: 2.2rem;
|
||||
}
|
||||
.item .done {
|
||||
width: 0.7rem;
|
||||
height: 0.7rem;
|
||||
margin-top: 0.5rem;
|
||||
border: 0.2rem solid #ccc;
|
||||
}
|
||||
.item .sort {
|
||||
font-size: 0.6rem;
|
||||
width: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.item .title {
|
||||
min-width: 16rem;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
.item .date {
|
||||
min-width: 6rem;
|
||||
}
|
||||
.item .tags {
|
||||
min-width: 6rem;
|
||||
}
|
||||
.item .description,
|
||||
.item .discussion {
|
||||
line-height: 2rem;
|
||||
margin: 0.5rem 0 0.5rem 2.3rem;
|
||||
}
|
||||
.item .description textarea {
|
||||
min-width: 20rem;
|
||||
min-height: 6rem;
|
||||
}
|
||||
.item .hr {
|
||||
height: 0.2rem;
|
||||
width: 6rem;
|
||||
}
|
||||
.item .comp {
|
||||
width: 3rem;
|
||||
opacity: 0;
|
||||
}
|
||||
.item .comp .a {
|
||||
display: block;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 500;
|
||||
line-height: 0.9rem;
|
||||
}
|
||||
.item:hover .comp {
|
||||
opacity: 1;
|
||||
}
|
||||
/* global */
|
||||
.top {
|
||||
vertical-align: top;
|
||||
}
|
||||
.ib {
|
||||
display: inline-block;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
.a {
|
||||
display: inline;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.input {
|
||||
outline: none;
|
||||
display: inline-block;
|
||||
padding: 0 0.3rem;
|
||||
background-color: #f9f9f9;
|
||||
border: 0;
|
||||
font: inherit;
|
||||
resize: none;
|
||||
}
|
||||
.input:focus {
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
.caret.left {
|
||||
border-left: 6px solid #000;
|
||||
border-top: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
margin-top: 0.4rem;
|
||||
}
|
158
pub/work/src/css/main.styl
Normal file
158
pub/work/src/css/main.styl
Normal file
@ -0,0 +1,158 @@
|
||||
//
|
||||
// fonts first
|
||||
//
|
||||
|
||||
@import 'fonts'
|
||||
|
||||
html
|
||||
body
|
||||
font-family "bau"
|
||||
font-size 18px
|
||||
|
||||
#c
|
||||
position absolute
|
||||
top 0rem
|
||||
left 50%
|
||||
width 34rem
|
||||
margin-left -17rem
|
||||
margin-bottom 12rem
|
||||
|
||||
h1
|
||||
font-weight 500
|
||||
|
||||
.items
|
||||
margin-top 4rem
|
||||
|
||||
.item
|
||||
display block
|
||||
max-height 3rem
|
||||
margin-bottom 1.5rem
|
||||
width 36rem
|
||||
overflow hidden
|
||||
background-color #fff
|
||||
transition max-height 200ms linear
|
||||
|
||||
.item .comments
|
||||
height 0
|
||||
|
||||
.item.expand
|
||||
max-height 16rem
|
||||
transition max-height 200ms linear
|
||||
|
||||
.item .expand
|
||||
margin-left 2rem
|
||||
cursor pointer
|
||||
transform-origin 3px 12px
|
||||
transition transform 200ms linear
|
||||
|
||||
.item.expand .expand
|
||||
transform rotate(90deg)
|
||||
transition transform 200ms linear
|
||||
|
||||
.item .sort
|
||||
.item .title
|
||||
.item .date
|
||||
.item .tags
|
||||
.item .comment
|
||||
line-height 2rem
|
||||
|
||||
.item .sort
|
||||
.item .date
|
||||
font-family 'scp'
|
||||
|
||||
.item .audience
|
||||
.item .date
|
||||
font-size .7rem
|
||||
|
||||
.item .audience
|
||||
.item .sort
|
||||
color #ccc
|
||||
|
||||
.item .audience
|
||||
text-transform uppercase
|
||||
height 1rem
|
||||
letter-spacing .07rem
|
||||
margin-left 2.2rem
|
||||
|
||||
.item .done
|
||||
width .7rem
|
||||
height .7rem
|
||||
margin-top .5rem
|
||||
border .2rem solid #ccc
|
||||
|
||||
.item .sort
|
||||
font-size .6rem
|
||||
width 2rem
|
||||
text-align center
|
||||
|
||||
.item .title
|
||||
min-width 16rem
|
||||
margin-left .5rem
|
||||
|
||||
.item .date
|
||||
min-width 6rem
|
||||
|
||||
.item .tags
|
||||
min-width 6rem
|
||||
|
||||
.item .description
|
||||
.item .discussion
|
||||
line-height 2rem
|
||||
margin .5rem 0 .5rem 2.3rem
|
||||
|
||||
.item .description textarea
|
||||
min-width 20rem
|
||||
min-height 6rem
|
||||
|
||||
.item .hr
|
||||
height .2rem
|
||||
width 6rem
|
||||
|
||||
|
||||
.item .comp
|
||||
width 3rem
|
||||
opacity 0
|
||||
|
||||
.item .comp .a
|
||||
display block
|
||||
font-size .7rem
|
||||
font-weight 500
|
||||
line-height .9rem
|
||||
|
||||
.item:hover .comp
|
||||
opacity 1
|
||||
|
||||
/* global */
|
||||
|
||||
.top
|
||||
vertical-align top
|
||||
|
||||
.ib
|
||||
display inline-block
|
||||
|
||||
.hidden
|
||||
display none
|
||||
|
||||
.a
|
||||
display inline
|
||||
cursor pointer
|
||||
text-decoration underline
|
||||
|
||||
.input
|
||||
outline none
|
||||
display inline-block
|
||||
padding 0 .3rem
|
||||
background-color #f9f9f9
|
||||
border 0
|
||||
font inherit
|
||||
resize none
|
||||
|
||||
.input:focus
|
||||
background-color #e6e6e6
|
||||
|
||||
.caret.left
|
||||
border-left 6px solid #000
|
||||
border-top 6px solid transparent
|
||||
border-right 6px solid transparent
|
||||
border-bottom 6px solid transparent
|
||||
margin-top .4rem
|
28
pub/work/src/js/actions/WorkActions.coffee
Normal file
28
pub/work/src/js/actions/WorkActions.coffee
Normal file
@ -0,0 +1,28 @@
|
||||
Dispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||
|
||||
module.exports =
|
||||
newItem: (index,list) ->
|
||||
Dispatcher.handleViewAction
|
||||
type:'newItem'
|
||||
index:index
|
||||
list:list
|
||||
|
||||
swapItems: (to,from,list) ->
|
||||
Dispatcher.handleViewAction
|
||||
type:'swapItem'
|
||||
from:from
|
||||
list:list
|
||||
to:to
|
||||
|
||||
removeItem: (index,list) ->
|
||||
Dispatcher.handleViewAction
|
||||
type:'removeItem'
|
||||
index:index
|
||||
list:list
|
||||
|
||||
addItem: (index,item,list) ->
|
||||
Dispatcher.handleViewAction
|
||||
type:'addItem'
|
||||
list:list
|
||||
index:index
|
||||
item:item
|
98
pub/work/src/js/components/ItemComponent.coffee
Normal file
98
pub/work/src/js/components/ItemComponent.coffee
Normal file
@ -0,0 +1,98 @@
|
||||
recl = React.createClass
|
||||
[div,textarea] = [React.DOM.div,React.DOM.textarea]
|
||||
|
||||
WorkActions = require '../actions/WorkActions.coffee'
|
||||
|
||||
module.exports = recl
|
||||
_dragStart: (e) ->
|
||||
$t = $(e.target)
|
||||
@dragged = $t.closest('.item')
|
||||
e.dataTransfer.effectAllowed = 'move'
|
||||
e.dataTransfer.setData 'text/html',e.currentTarget
|
||||
@props._dragStart e,@
|
||||
|
||||
_dragEnd: (e) -> @props._dragEnd e,@
|
||||
|
||||
_keyDown: (e) ->
|
||||
@props._keyDown e,@
|
||||
|
||||
kc = e.keyCode
|
||||
|
||||
switch kc
|
||||
# tab - expand
|
||||
when 9
|
||||
if @state.expand is false
|
||||
@setState {expand:true}
|
||||
# esc - collapse
|
||||
when 27
|
||||
@setState {expand:false}
|
||||
|
||||
if (kc is 9 and @state.expand is false) or (kc is 27)
|
||||
e.preventDefault()
|
||||
return
|
||||
|
||||
_focus: (e) -> @props._focus e,@
|
||||
|
||||
formatDate: (d) ->
|
||||
"#{d.getDate()}-#{(d.getMonth()+1)}-#{d.getFullYear()}"
|
||||
|
||||
getInitialState: -> {expand:false}
|
||||
|
||||
render: ->
|
||||
itemClass = 'item'
|
||||
if @state.expand then itemClass += ' expand'
|
||||
|
||||
(div {
|
||||
className:itemClass
|
||||
draggable:true
|
||||
'data-index':@props.index
|
||||
onDragStart:@_dragStart
|
||||
onDragEnd:@_dragEnd
|
||||
'data-index':@props.index
|
||||
}, [
|
||||
(div {className:'audience'},@props.item.audience.join(" "))
|
||||
(div {className:'sort ib top'},@props.index)
|
||||
(div {className:'done ib'},'')
|
||||
(div {className:'title ib top'},[
|
||||
(div {
|
||||
contentEditable:true
|
||||
onFocus:@_focus
|
||||
onKeyDown:@_keyDown
|
||||
className:'input'
|
||||
},@props.item.title)
|
||||
])
|
||||
(div {className:'date ib top'}, [
|
||||
(div {
|
||||
contentEditable:true
|
||||
className:'input'
|
||||
},@formatDate(@props.item['date-created']))
|
||||
])
|
||||
(div {className:'tags ib top'},[
|
||||
(div {
|
||||
contentEditable:true
|
||||
className:'input'
|
||||
},@props.item.tags.join(" "))
|
||||
])
|
||||
(div {
|
||||
className:'expand ib',
|
||||
onClick: (e) =>
|
||||
@setState {expand:!@state.expand}
|
||||
},[
|
||||
(div {className:'caret left'},"")
|
||||
])
|
||||
(div {className:"description"},[
|
||||
(textarea {
|
||||
className:'input'
|
||||
},@props.item.description)
|
||||
])
|
||||
(div {className:"hr"},"")
|
||||
(div {className:"discussion"},[
|
||||
(div {className:"comments"}, @props.item.discussion.map (slug) ->
|
||||
(div {className:'slug'}, slug)
|
||||
),
|
||||
(div {
|
||||
contentEditable:true
|
||||
className:'input comment'
|
||||
},"")
|
||||
])
|
||||
])
|
121
pub/work/src/js/components/ListComponent.coffee
Normal file
121
pub/work/src/js/components/ListComponent.coffee
Normal file
@ -0,0 +1,121 @@
|
||||
recl = React.createClass
|
||||
rece = React.createElement
|
||||
[div,h1,input,textarea] = [React.DOM.div,React.DOM.h1,React.DOM.input,React.DOM.textarea]
|
||||
|
||||
WorkStore = require '../stores/WorkStore.coffee'
|
||||
WorkActions = require '../actions/WorkActions.coffee'
|
||||
ItemComponent = require './ItemComponent.coffee'
|
||||
|
||||
module.exports = recl
|
||||
stateFromStore: -> {
|
||||
list:WorkStore.getList @props.list
|
||||
expand:false
|
||||
}
|
||||
|
||||
getInitialState: -> @stateFromStore()
|
||||
_onChangeStore: -> @setState @stateFromStore()
|
||||
|
||||
alias: ->
|
||||
@$el = $ @getDOMNode()
|
||||
@$items = @$el.find('.items').children()
|
||||
|
||||
_focus: (e,i) -> @setState {selected:Number(i.props.index)}
|
||||
|
||||
_dragStart: (e,i) -> @dragged = i.dragged
|
||||
|
||||
_dragEnd: (e,i) ->
|
||||
from = Number @dragged.attr('data-index')
|
||||
to = Number @over.attr('data-index')
|
||||
if from<to then to--
|
||||
if @drop is 'after' then to++
|
||||
WorkActions.swapItems to,from,@props.list
|
||||
@dragged.removeClass 'hidden'
|
||||
@placeholder.remove()
|
||||
|
||||
_dragOver: (e,i) ->
|
||||
e.preventDefault()
|
||||
$t = $(e.target).closest('.item')
|
||||
if $t.hasClass 'placeholder' then return
|
||||
if $t.length is 0 then return
|
||||
@over = $t
|
||||
if not @dragged.hasClass('hidden') then @dragged.addClass 'hidden'
|
||||
if (e.clientY - $t[0].offsetTop) < ($t[0].offsetHeight / 2)
|
||||
@drop = 'before'
|
||||
@placeholder.insertBefore $t
|
||||
else
|
||||
@drop = 'after'
|
||||
@placeholder.insertAfter $t
|
||||
|
||||
_keyDown: (e) ->
|
||||
kc = e.keyCode
|
||||
|
||||
switch kc
|
||||
# enter - add new
|
||||
when 13
|
||||
if window.getSelection().getRangeAt(0).endOffset is 0
|
||||
ins = @state.selected
|
||||
else
|
||||
ins = @state.selected+1
|
||||
@setState {selected:ins,select:true}
|
||||
WorkActions.newItem ins,@props.list
|
||||
# backspace - remove if at 0
|
||||
when 8
|
||||
if window.getSelection().getRangeAt(0).endOffset is 0 and
|
||||
e.target.innerText.length is 0
|
||||
if @state.selected isnt 0
|
||||
@setState {selected:@state.selected-1,select:"end"}
|
||||
WorkActions.removeItem @state.selected,@props.list
|
||||
e.preventDefault()
|
||||
# up
|
||||
when 38
|
||||
last = @state.selected-1
|
||||
if last<0 then last = @state.list.length-1
|
||||
@$items.eq(last).find('.title .input').focus()
|
||||
@setState {select:"end"}
|
||||
# down
|
||||
when 40
|
||||
next = @state.selected+1
|
||||
if next is @state.list.length then next = 0
|
||||
@$items.eq(next).find('.title .input').focus()
|
||||
@setState {select:"end"}
|
||||
|
||||
# cancel these
|
||||
if (kc is 13) or (kc is 38) or (kc is 40) then e.preventDefault()
|
||||
|
||||
componentDidMount: ->
|
||||
@placeholder = $ "<div class='item placeholder'><div class='sort'>x</div></div>"
|
||||
WorkStore.addChangeListener @_onChangeStore
|
||||
@alias()
|
||||
|
||||
componentDidUpdate: ->
|
||||
@alias()
|
||||
if @state.selected isnt undefined or @state.select
|
||||
$title = @$items.eq(@state.selected).find('.title .input')
|
||||
if @state.selected isnt undefined and @state.select
|
||||
$title.focus()
|
||||
if @state.select is "end"
|
||||
r = window.getSelection().getRangeAt(0)
|
||||
r.setStart $title[0],1
|
||||
r.setEnd $title[0],1
|
||||
s = window.getSelection()
|
||||
s.removeAllRanges()
|
||||
s.addRange r
|
||||
if @state.select
|
||||
@setState {select:false}
|
||||
|
||||
render: ->
|
||||
(div {}, [
|
||||
(div {
|
||||
className:'items'
|
||||
onDragOver:@_dragOver
|
||||
}, [
|
||||
_.map @state.list,(item,index) =>
|
||||
rece(ItemComponent,{
|
||||
item
|
||||
index
|
||||
@_focus
|
||||
@_keyDown
|
||||
@_dragStart
|
||||
@_dragEnd})
|
||||
])
|
||||
])
|
11
pub/work/src/js/components/WorkComponent.coffee
Normal file
11
pub/work/src/js/components/WorkComponent.coffee
Normal file
@ -0,0 +1,11 @@
|
||||
recl = React.createClass
|
||||
rece = React.createElement
|
||||
[div,input,textarea] = [React.DOM.div,React.DOM.input,React.DOM.textarea]
|
||||
|
||||
ListComponent = require './ListComponent.coffee'
|
||||
|
||||
module.exports = recl
|
||||
render: ->
|
||||
(div {}, [
|
||||
(rece(ListComponent,{list:'upcoming'}))
|
||||
])
|
13
pub/work/src/js/dispatcher/dispatcher.coffee
Normal file
13
pub/work/src/js/dispatcher/dispatcher.coffee
Normal file
@ -0,0 +1,13 @@
|
||||
Dispatcher = require('flux').Dispatcher
|
||||
|
||||
module.exports = _.merge new Dispatcher(), {
|
||||
handleServerAction: (action) ->
|
||||
@dispatch
|
||||
source: 'server'
|
||||
action: action
|
||||
|
||||
handleViewAction: (action) ->
|
||||
@dispatch
|
||||
source: 'view'
|
||||
action: action
|
||||
}
|
4
pub/work/src/js/main.coffee
Normal file
4
pub/work/src/js/main.coffee
Normal file
@ -0,0 +1,4 @@
|
||||
WorkComponent = require './components/WorkComponent.coffee'
|
||||
|
||||
$ ->
|
||||
React.render React.createElement(WorkComponent),$('#c')[0]
|
1192
pub/work/src/js/main.js
Normal file
1192
pub/work/src/js/main.js
Normal file
File diff suppressed because it is too large
Load Diff
17
pub/work/src/js/package.json
Normal file
17
pub/work/src/js/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "urbit-work",
|
||||
"version": "0.0.0",
|
||||
"repository": {
|
||||
"type":"git",
|
||||
"url":"https://github.com/urbit/urbit"
|
||||
},
|
||||
"description": "urbit work frontend",
|
||||
"main": "main.js",
|
||||
"dependencies": {
|
||||
"coffeeify": "~0.7.0",
|
||||
"flux": "~2.0.1",
|
||||
"lodash": "~2.4.1",
|
||||
"moment-timezone": "~0.2.4",
|
||||
"object-assign": "^1.0.0"
|
||||
}
|
||||
}
|
95
pub/work/src/js/stores/WorkStore.coffee
Normal file
95
pub/work/src/js/stores/WorkStore.coffee
Normal file
@ -0,0 +1,95 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
assign = require 'object-assign'
|
||||
Dispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||
|
||||
_upcoming = [
|
||||
id:0
|
||||
sort:0
|
||||
"date-created":new Date('2015-8-18')
|
||||
"date-modifed":new Date('2015-8-18')
|
||||
"date-due":null
|
||||
owner:"~talsur-todres"
|
||||
audience:["doznec/urbit-meta","doznec/tlon"]
|
||||
status:"working"
|
||||
tags:['food','office']
|
||||
title:'get groceries'
|
||||
description:'first go out the door, \n then walk down the block.'
|
||||
discussion:[]
|
||||
,
|
||||
id:1
|
||||
sort:1
|
||||
"date-created":new Date('2015-8-18')
|
||||
"date-modifed":new Date('2015-8-18')
|
||||
"date-due":null
|
||||
owner:"~talsur-todres"
|
||||
audience:["doznec/tlon"]
|
||||
status:"working"
|
||||
tags:['home','office']
|
||||
title:'eat'
|
||||
description:'dont forget about lunch.'
|
||||
discussion:[]
|
||||
,
|
||||
id:2
|
||||
sort:2
|
||||
"date-created":new Date('2015-8-18')
|
||||
"date-modifed":new Date('2015-8-18')
|
||||
"date-due":null
|
||||
owner:"~talsur-todres"
|
||||
audience:["doznec/tlon"]
|
||||
status:"working"
|
||||
tags:['home']
|
||||
title:'sleep'
|
||||
description:'go get some sleep.'
|
||||
discussion:[]
|
||||
]
|
||||
_following = {}
|
||||
_incoming = {}
|
||||
|
||||
lists =
|
||||
'upcoming':_upcoming
|
||||
'following':_following
|
||||
'incoming':_incoming
|
||||
|
||||
WorkStore = assign {},EventEmitter.prototype,{
|
||||
emitChange: -> @emit 'change'
|
||||
addChangeListener: (cb) -> @on 'change', cb
|
||||
removeChangeListener: (cb) -> @removeListener "change", cb
|
||||
|
||||
getList: (key) -> lists[key]
|
||||
|
||||
newItem: ({index,list}) ->
|
||||
list = lists[list]
|
||||
item =
|
||||
id:index
|
||||
sort:index
|
||||
"date-created":new Date()
|
||||
"date-modifed":new Date()
|
||||
"date-due":null
|
||||
owner:"~talsur-todres"
|
||||
status:null
|
||||
tags:[]
|
||||
title:''
|
||||
description:''
|
||||
discussion:[]
|
||||
list.splice index,0,item
|
||||
|
||||
swapItem: ({to,from,list}) ->
|
||||
list = lists[list]
|
||||
list.splice to,0,list.splice(from,1)[0]
|
||||
|
||||
removeItem: ({index,list}) ->
|
||||
list = lists[list]
|
||||
list.splice index,1
|
||||
|
||||
}
|
||||
|
||||
WorkStore.setMaxListeners 100
|
||||
|
||||
WorkStore.dispatchToken = Dispatcher.register (p) ->
|
||||
a = p.action
|
||||
|
||||
if WorkStore[a.type]
|
||||
WorkStore[a.type] a
|
||||
WorkStore.emitChange()
|
||||
|
||||
module.exports = WorkStore
|
Loading…
Reference in New Issue
Block a user