Merge branch 'apps' of https://github.com/urbit/urbit into work

This commit is contained in:
Philip C Monk 2015-08-19 18:37:22 -04:00
commit 0b8b8d3ef1
19 changed files with 2339 additions and 5 deletions

View File

@ -494,14 +494,14 @@
::
++ poke-test
%+ titl 'Poke'
;= ;button(onclick "urb.testPoke('/~/to/hi/txt.json')"): Hi anonymous
;button(onclick "urb.testPoke('/~/as/own/~/to/hi/txt.json')"): Hi
;= ;button(onclick "urb.testPoke('/~/to/hood/helm-hi.json')"): Hi anonymous
;button(onclick "urb.testPoke('/~/as/own/~/to/hood/helm-hi.json')"): Hi
;pre:code#err;
;script@"/~/at/~/auth.js";
;script:'''
show = function(t){err.innerText = ":) " + Date.now() + "\n" + t}
urb.testPoke = function(url){
req(url,{xyro:{test:true}}, show)
req(url,{wire:"/",xyro:'test'}, show)
}
'''
==
@ -748,7 +748,7 @@
$(tee q.tee, q.q.p.q.sih (add-json jon q.q.cay))
::
[%ha *]
:: ~& e/ford/hen
%- emule |. ^+ ..apex
?. ?=(%& -.q.sih)
(fail 404 p.sih p.q.sih)
=* cay p.q.sih

View File

@ -1047,7 +1047,10 @@
?. ?=(%2 -.q.raf)
(cope raf (flux |=(vax=vase (some [for vax]))))
=- ((slog 0 (flop `tang`-)) (flue cof))
?^ t.pax ~ :: error on top-level marks
=+ (lent t.pax)
?: ?~ - | :: error if level above built
(~(has by res) (tack i.pax (scag (dec -) t.pax)))
~
:_(q.q.raf leaf/"! {<`mark`for>} build failed, ignoring.")
--
::

64
mar/work/command.hoon Normal file
View File

@ -0,0 +1,64 @@
::
:::: /hoon/command/work/mar
::
/- *work
!:
::::
::
|_ mad=command
++ grab
|% ++ noun command
++ json
=> [jo ..command]
=< (corl need (cu |=(a=command a) coma))
|%
++ as
:: |*(a=fist (cu sa (ar a))) :: XX types
|* a=fist
%- cu :_ (ar a)
~(gas in *(set ,_(need *a)))
++ id (ci (slat %uv) so)
++ ship (su fed:ag)
++ coma (of new/task old/(ot id/id dif/uppd ~) sort/(ar id) ~)
++ task
%- ot :~
id/id date-created/di
version/ni date-modified/di
owner/ship status/(ci (soft status) so)
tags/(as so) due-date/(mu di) title/so
description/so discussion/(ar (ot date/di ship/ship body/so ~))
==
++ uppd
%- of :~
own/(of announce/ul claim/ul ~)
add/(of comment/(ot date/di body/so ~) ~)
:- %set
%- of :~
due-date/di
title/so
description/so
tags/(as so)
done/(mu di)
audience/(as (ot ship/ship span/so ~))
==
==
--
--
++ grow
|%
++ elem ;pre: {(zing `wall`(turn (wash 0^120 >mad<) |=(a=tape ['\0a' a])))}
--
--
:: {new: {
:: id:'0vaof.6df9u.2agc3.d0dp1',
:: date-created:1440011611215,
:: version:1,
:: date-modified:1440011611215,
:: owner:'fyr',
:: status:'gave',
:: tags:['tag'],
:: due-date:null,
:: title:'Test task',
:: description:'The converter owrks right?',
:: discussion:[{date:1440011611215,ship:'sondel',body:'hi'}]
:: } }

118
mar/work/task.hoon Normal file
View File

@ -0,0 +1,118 @@
::
:::: /hoon/task/work/mar
::
/- *work
!:
::::
::
|%
++ rend
|= a=(list $|(char dime)) ^- cord
%- crip
|- ^- tape
?~ a ~
?@ i.a [i.a $(a t.a)]
(weld (scow i.a) $(a t.a))
::
++ indent |=(a=wain (turn a |=(b=cord (cat 3 ' ' b))))
::
++ undent
|* [a=wain b=$+(wain *)] ^+ [*b a]
=^ c a
|- ^- [c=wain a=wain]
?~ a [~ a]
?. =(' ' (end 3 2 i.a))
[~ a]
[[- c] a]:[(rsh 3 2 i.a) $(a t.a)]
[(b `wain`c) a]
++ keen |*(_[a=,* b=rule] |=(c=nail `(like a)`(b c)))
++ parse
|* [hed=?(~ $|(@tas tape)) tal=(pole)]
?~ hed (..$ tal)
?^ hed ;~(pfix (just (crip hed)) (..$ tal))
=- ?~(tal had ;~(plug had (..$ tal)))
=< had=(sear . nuck:so)
|= a=coin ^- (unit (odo:raid hed))
?. &(?=([%$ @ @] a) =(hed p.p.a)) ~
(some q.p.a)
::
++ advance
|* [a=wain b=_rule] ^+ [(wonk *b) a]
?~(a !! ~|(i.a [(rash i.a b) t.a]))
--
!:
::::
::
|_ taz=task
++ grab
|% ++ txt
|= a=wain ^+ taz
=+ ~[id=%uv "_" date-created=%da " " version=%ud date-modified=%da]
=^ b a (advance a ;~(plug (parse -) (punt (parse " " %da ~))))
=+ [-.b `due-date=(unit ,@da)`+.b]
=^ tags a (undent a ~(gas in *(set cord)))
=^ title a ?~(a !! a)
=^ b a (advance a (parse owner=%p "." status=%tas ~))
?> ?=(status.task status.b)
=+ b
=^ description a (undent a role)
:* id date-created version date-modified
owner status tags due-date title description
|- ^- (list comment)
?: =(~ a) ~
=^ b a (advance a (parse ship=%p " " date=%da ~))
=+ b
=^ body a (undent a role)
[[date ship body] $]
==
--
++ grow
|%
++ elem ;pre: {(zing `wall`(turn (wash 0^120 >taz<) |=(a=tape ['\0a' a])))}
++ mime [/text/x-task (taco (role txt))]
++ txt
=+ taz
=+ due=?~(due-date ~ ~[' ' da/u.due-date])
:- (rend uv/id '_' da/date-created ' ' ud/version da/date-modified due)
%+ welp (indent (sort (~(tap in tags)) aor))
:- title
:- (rend p/owner '.' tas/status ~)
%- zing ^- (list wain)
:- (indent (lore description))
%+ turn discussion
|= comment ^- wain
[(rend p/ship ' ' da/date ~) (indent (lore body))]
++ json
=+ taz
%- jobe :~ id/(jape <id>)
tags/[%a (turn (~(tap in tags)) |=(a=cord s/a))]
owner/(jape <owner>)
status/(jape <status>)
title/[%s title]
version/(jape <version>)
date-created/(jode date-created)
date-modified/(jode date-modified)
description/[%s description]
=< discussion/[%a (turn discussion .)]
|=(comment (jobe date/(jode date) ship/(jape <ship>) body/[%s body] ~))
due-date/?~(due-date ~ (jode u.due-date))
==
--
++ grad %txt
--
:: {id}_{date-created} {version}{date-modified}{|(" {due-date}" ~)}
:: {tag1}
:: {tag2}
:: ...
:: {title}
:: {owner}.{status}
:: {description}
:: {more description}
:: {ship1} {date}
:: {comment}
:: {more comment}
:: {more comment}
:: {ship2} {date}
:: {comment}
:: {more comment}
:: {more comment}

33
pub/work/fab/hymn.hook Normal file
View 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");
==
==

View 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
View 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
View 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

View 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

View 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'
},"")
])
])

View 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})
])
])

View 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'}))
])

View 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
}

View 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

File diff suppressed because it is too large Load Diff

View 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"
}
}

View 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

8
pub/work/test.work-task Normal file
View File

@ -0,0 +1,8 @@
0v0_~1999.1.1 2~1999.1.2 ~1999.5.20
Tagged!
Yoooo
~fyr.gave
Testin
~doznec ~2015.1.3
how long has
this been around?

52
sur/work.hoon Normal file
View File

@ -0,0 +1,52 @@
/- talk
|%
++ client
$: tasks=(map ,@uvH client-task)
sort=(list ,@uvH)
==
++ client-task
$: task=task
audience=(set station:talk)
==
++ task
$: id=@uvH
date-created=@da
version=@u
date-modified=@da
owner=@p
status=status
tags=(set ,@t)
due-date=(unit ,@da)
title=@t
description=@t
discussion=(list comment)
==
++ comment
$: date=@da
ship=@p
body=@t
==
++ status ?(%took %gave %left)
++ command
$% [%new task]
[%old id=@uvH dif=update]
[%sort p=(list ,@uvH)]
==
++ update
$% $: %set
$% [%due-date p=@da]
[%title p=@t]
[%description p=@t]
[%tags p=(set ,@t)]
[%done p=(unit ,@da)]
[%audience p=(set station:talk)]
== ==
$: %add
$% [%comment [@da @t]]
== ==
$: %own
$% [%announce ~]
[%claim ~]
== ==
==
--