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

This commit is contained in:
Anton Dyudin 2015-08-24 13:28:04 -07:00
commit d78846c14e
12 changed files with 360 additions and 182 deletions

View File

@ -1,4 +1,13 @@
:: not implemented: set audience
:: also check if talk can add stations to something other than porch
:: it can't
:: maybe look into storing a "following" set
:: make most updates not rely on knowing about task (all but claim?)
:: should let non-owners suggest that owner cross-post to another
:: station
::
:: pretty-print in command-line interface
:: serialize %lax to json
:: bring up ~dozbud to test
::
::::
::
@ -24,28 +33,27 @@
::
|_ [bowl client connected=_|]
++ at
|= [claiming=? audience=(set station:talk) task]
=* tax +<+>
|= client-task
=| moves=(list move)
|%
++ abet
^- [(list move) _+>.$]
[(flop moves) +>.$(tasks (~(put by tasks) id +<.$))]
[(flop moves) +>.$(tasks (~(put by tasks) id.tax +<.$))]
::
++ abut
^- [(list move) _+>.$]
[(flop moves) +>.$]
::
++ send
|= action=duty:work-stuff:talk
++ send-audience
|= [to=(set station:talk) action=duty:work-stuff:talk]
^+ +>
%_ +>.$
eny (sham eny action)
moves
:_ ~
:_ moves
^- move
:* ost %poke
/sending/(scot %uv id)/(scot %ud version)
/sending/(scot %uv id.tax)/(scot %ud version.tax)
[our %talk]
%talk-command
^- command:talk
@ -54,36 +62,25 @@
:_ ~
:+ (shaf %task eny)
%- mo ^- (list ,[partner envelope delivery]:talk)
%+ turn (~(tap in audience))
%+ turn (~(tap in to))
|=(sat=station:talk [[%& sat] [*envelope %pending]])
[now *bouquet [%tax action]]
==
==
::
++ claim
%_ .
eny (sham eny %direct)
claiming &
moves
:_ ~
^- move
:* ost %poke
/claiming/(scot %uv id)
[our %talk]
%talk-command
^- command:talk
:- %publish
|- ^- (list thought)
:_ ~
:+ (shaf %task eny)
[[[%& owner (main owner)] [*envelope %pending]] ~ ~]
[now *bouquet [%tax %claim id]]
==
==
++ send
|= action=duty:work-stuff:talk
(send-audience audience action)
::
++ create %+ send %create
tax(date-created now, version 0, date-modified now)
++ send-update |*(* (send %update id +<))
++ claim
(send-audience(claiming &) [[owner.tax (main owner.tax)] ~ ~] %claim id.tax)
::
++ send-archive
|= to=(set station:talk)
(send-audience to %archive id.tax)
::
++ send-create (send %create tax)
++ send-update |*(* (send %update id.tax +<))
++ release |=([vers=@u her=@p] (send-update vers %release her))
++ accept |=(vers=@u (send-update vers %accept ~))
++ process-update
@ -103,13 +100,25 @@
%description (send-update vers %set-description +>.up)
%tags (send-update vers %set-tags +>.up)
%done (send-update vers %set-done +>.up)
%audience ~|(%not-implemented !!)
==
==
++ process-audience
|= to=(set station:talk)
^+ +>
=. +>.$ (send-archive (~(dif in audience) to))
=. +>.$ (send-audience (~(dif in to) audience) %create tax)
+>.$(audience to)
--
::
++ prep
|= [old=(unit (pair client ,_|))]
^- [(list move) _+>.$]
initialize(+<+ ?~(old +<+.+>.$ u.old))
::
++ initialize
^- [(list move) _.]
?: connected
[~ .]
:_ .(connected %&) :_ ~
[ost %peer /peering [our %talk] /f/(main our)/0]
::
@ -117,20 +126,22 @@
|= [when=@da her=ship from=(set station:talk) action=duty:work-stuff:talk]
^- [(list move) _+>.$]
=- =^ mof con mirror-to-web:con
[(welp mos mof) con]
[(welp mof mos) con]
^- [mos=(list move) con=_+>.$]
?- -.action
%create :: XX should verify ownership
%create
=+ existing-task=(~(get by tasks) id.tax.action)
~? ?& ?=(^ existing-task)
!=(tax.action task.u.existing-task)
?: ?& ?=(^ existing-task)
!=(tax.action tax.u.existing-task)
!archived.u.existing-task
==
:* %new-task-with-old-id
her=her
from=from
new-task=tax.action
existing-task=u.existing-task
==
~& :* %new-task-with-old-id
her=her
from=from
new-task=tax.action
existing-task=u.existing-task
==
[~ +>.$]
?. |(=(her owner.tax.action) =(%released status.tax.action))
~& :* %created-with-bad-owner
her=her
@ -139,17 +150,9 @@
existing-task=existing-task
==
[~ +>.$]
?. =(0 version.tax.action)
~& :* %new-task-version-not-zero
her=her
from=from
new-task=tax.action
existing-task=existing-task
==
[~ +>.$]
=. tasks
%^ ~(put by tasks) id.tax.action |
:_ tax.action
%^ ~(put by tasks) id.tax.action |
:- | :_ tax.action
?~ existing-task from
(~(uni in audience.u.existing-task) from)
=. sort ?^(existing-task sort [id.tax.action sort])
@ -157,14 +160,40 @@
::
%claim
=+ tax=(~(got by tasks) id.action)
?. &(=(our owner.task.tax) =(%announced status.task.tax))
?. &(=(our owner.tax.tax) =(%announced status.tax.tax))
~& :* %bad-claim
her=her
from=from
task=tax
==
[~ +>.$]
abet:(release:(at (~(got by tasks) id.action)) +(version.task.tax) her)
abet:(release:(at (~(got by tasks) id.action)) +(version.tax.tax) her)
::
%archive
=+ tax=(~(get by tasks) id.action)
?~ tax
~& :* %archive-for-nonexistent-task
her=her
from=from
action=action
==
[~ +>.$]
?: !=(her owner.tax.u.tax)
~& :* %archiver-not-owner
her=her
from=from
action=action
tax=tax
==
[~ +>.$]
=. tasks
%+ ~(put by tasks) id.action
:* claiming.u.tax
=(~ (~(dif in audience.u.tax) from))
(~(dif in audience.u.tax) from)
tax.u.tax
==
[~ +>.$]
::
%update
=+ tax=(~(get by tasks) id.action)
@ -175,7 +204,7 @@
action=action
==
[~ +>.$]
?. =(version.action +(version.task.u.tax))
?. =(version.action +(version.tax.u.tax))
~& :* %update-bad-version
her
from=from
@ -183,42 +212,47 @@
tax=tax
==
[~ +>.$]
=. tasks
%^ ~(put by tasks) id.action
?: ?=(%release -.meat.action)
|
claiming.u.tax
:- (~(uni in audience.u.tax) from)
?: ?& ?=(?(%announce %release %accept) -.meat.action)
!=(her owner.task.u.tax)
?: ?& ?=(?(%announce %release %accept) -.meat.action)
!=(her owner.tax.u.tax)
==
~& :* %not-owner
her=her
from=from
action=action
tax=tax
==
~& :* %not-owner
her=her
from=from
action=action
tax=tax
==
task.u.tax
=. version.task.u.tax version.action
=. date-modified.task.u.tax when
?- -.meat.action
%announce task.u.tax(status %announced)
%release task.u.tax(owner her.meat.action, status %released)
%accept task.u.tax(status %accepted)
%set-date-due task.u.tax(date-due wen.meat.action)
%set-tags task.u.tax(tags tag.meat.action)
%set-title task.u.tax(title til.meat.action)
%set-description task.u.tax(description des.meat.action)
%set-done task.u.tax(done ?.(don.meat.action ~ `when))
%add-comment
%= task.u.tax
discussion [[when her com.meat.action] discussion.task.u.tax]
[~ +>.$]
=. tasks
%+ ~(put by tasks) id.action
:* ?: ?=(%release -.meat.action)
|
claiming.u.tax
::
archived.u.tax
::
(~(uni in audience.u.tax) from)
::
=. version.tax.u.tax version.action
=. date-modified.tax.u.tax when
?- -.meat.action
%announce tax.u.tax(status %announced)
%release tax.u.tax(owner her.meat.action, status %released)
%accept tax.u.tax(status %accepted)
%set-date-due tax.u.tax(date-due wen.meat.action)
%set-tags tax.u.tax(tags tag.meat.action)
%set-title tax.u.tax(title til.meat.action)
%set-description tax.u.tax(description des.meat.action)
%set-done tax.u.tax(done ?.(don.meat.action ~ `when))
%add-comment
%= tax.u.tax
discussion [[when her com.meat.action] discussion.tax.u.tax]
==
==
==
?: ?& =([%release our] meat.action)
claiming.u.tax
==
abet:(accept:(at (~(got by tasks) id.action)) +(+(version.task.u.tax)))
abet:(accept:(at (~(got by tasks) id.action)) +(+(version.tax.u.tax)))
[~ +>.$]
==
::
@ -249,18 +283,20 @@
|= cod=command
?. =(our src)
~|([%wrong-user our=our src=src] !!)
=^ mos +>.$
?: connected
[~ +>.$]
initialize
=^ mof +>.$
?- -.cod
%new abut:create:(at [| - +]:+.cod)
%old =+ (at (~(got by tasks) id.cod))
abet:(process-update:- version.cod dif.cod)
%sort mirror-to-web(sort p.cod)
==
[(welp mos mof) +>.$]
?- -.cod
%sort mirror-to-web(sort p.cod)
%audience
=^ mow +>.$
abet:(process-audience:(at (~(got by tasks) id.cod)) to.cod)
=^ mov +>.$ mirror-to-web
[(welp mov mow) +>.$]
%old
=+ (at (~(got by tasks) id.cod))
abet:(process-update:- version.cod dif.cod)
%new
=. +>.cod +>.cod(date-created now, version 0, date-modified now)
abut:send-create:(at | | +.cod)
==
::
:: XX maybe need to check that we haven't received this message before
:: by keeping a counter of last message received

View File

@ -49,7 +49,11 @@
==
++ id (ci (slat %uv) so)
++ ship (su fed:ag)
++ coma (of new/task old/(ot id/id version/ni dif/uppd ~) sort/(ar id) ~)
++ coma
%- of :~
new/task old/(ot id/id version/ni dif/uppd ~)
sort/(ar id) audience/(ot id/id to/audi ~)
==
++ task
%- ot :~
audience/audi
@ -73,7 +77,6 @@
description/so
tags/(as so)
done/bo
audience/audi
==
==
--

View File

@ -13,7 +13,7 @@
sort/[%a (turn sort |=(a=@uv [%s (scot %uv a)]))]
=< tasks/(jobe (turn (~(tap by tasks)) .))
|= [@ client-task]
=+ task
=+ tax
:- (scot %uv id)
%- jobe :~ id/[%s (scot %uv id)]
tags/[%a (turn (~(tap in tags)) |=(a=cord s/a))]

View File

@ -124,6 +124,7 @@ h1.leader:after {
.ctrl .filter {
line-height: 2rem;
margin-right: 1rem;
vertical-align: middle;
}
.ctrl .sort {
background-color: transparent;
@ -144,6 +145,23 @@ h1.leader:after {
margin-right: 0.3rem;
cursor: pointer;
}
.input-bool {
opacity: 0.3;
}
.input-bool.true,
.input-bool.false {
opacity: 1;
}
.input-bool,
.item .done {
width: 0.7rem;
height: 0.7rem;
border: 0.2rem solid #ccc;
}
.input-bool.true,
.item .done-true {
background-color: #ccc;
}
.items {
margin-top: 2rem;
margin-left: -2rem;
@ -198,6 +216,9 @@ h1.leader:after {
.item .sort {
color: #ccc;
}
.item .done {
margin-top: 0.5rem;
}
.item .owner,
.item .audience,
.item .date,
@ -228,12 +249,6 @@ h1.leader:after {
.item .audience .input {
background-color: transparent;
}
.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;

View File

@ -46,6 +46,7 @@ h1.leader:after
.filter
line-height 2rem
margin-right 1rem
vertical-align middle
.sort
background-color transparent
@ -64,8 +65,24 @@ h1.leader:after
label
margin-right .3rem
cursor pointer
.input-bool
opacity .3
.input-bool.true
.input-bool.false
opacity 1
.input-bool
.item .done
width .7rem
height .7rem
border .2rem solid #ccc
.input-bool.true
.item .done-true
background-color #ccc
.items
margin-top 2rem
@ -120,6 +137,9 @@ h1.leader:after
.sort
color #ccc
.done
margin-top .5rem
.owner
.audience
@ -151,12 +171,6 @@ h1.leader:after
.audience .input
background-color transparent
.done
width .7rem
height .7rem
margin-top .5rem
border .2rem solid #ccc
.sort
font-size .6rem
width 2rem

View File

@ -34,7 +34,10 @@ module.exports =
version += 1
Persistence.put old:{id,version,dif:own:o}
addItem: ({id,version},val) ->
setAudience: ({id},val) ->
Persistence.put audience:{id,to:val}
addComment: ({id,version},val) ->
version += 1
Persistence.put old:{id,version,dif:add:comment:val}

View File

@ -3,12 +3,21 @@ rece = React.createElement
{div,h1,label} = React.DOM
module.exports = recl
_onKeyDown: (e) ->
onClick: (e) ->
switch @props.filters['done']
when null
b = true
when true
b = false
when false
b = null
@props.onChange 'done',b
onKeyDown: (e) ->
if e.keyCode is 13
e.stopPropagation()
e.preventDefault()
@change(e)
_onBlur: (e) -> @change(e)
onBlur: (e) -> @change(e)
change: (e) ->
$t = $(e.target).closest('.filter')
txt = $t.find('.input').text().trim()
@ -20,19 +29,26 @@ module.exports = recl
when 'tags' then txt = [txt]
@props.onChange key,txt
fields: [ {filter:'owned', key:'owner', title: 'Owner:'},
fields: [ {filter:'done', key:'done', title: ''},
{filter:'owned', key:'owner', title: 'Owner:'},
{filter:'tag', key:'tags', title: 'Tag:'},
{filter:'channel', key:'audience', title: 'Audience:'},
{filter:'status', key:'status', title: 'Status:'} ]
render: ->
(div {className:'filters'}, @fields.map ({filter,key,title})=>
input = (div {
contentEditable:true
className:'input ib'
@onKeyDown
@onBlur
},@props.filters[filter])
if filter is 'done'
input = (div {
className:'input-bool ib '+@props.filters[key],
@onClick
},"")
(div {key, 'data-key':key, className:"#{filter} filter ib"}, [
(label {}, title)
(div {
contentEditable:true
className:'input ib'
onKeyDown:@_onKeyDown
onBlur:@_onBlur
},@props.filters[filter])
input
]))

View File

@ -118,7 +118,8 @@ module.exports = recl
onFocus: (e) -> @props._focus e,@
_markDone: (e) -> WorkActions.setItem @props.item,'done',true
_markDone: (e) ->
WorkActions.setItem @props.item,'done',(not @props.item.done?)
_changeStatus: (e) ->
return if @props.item.status is 'released'
@ -130,13 +131,18 @@ module.exports = recl
WorkActions.ownItem @props.item,own
_submitComment: (e) ->
$t = $(e.target).closest('.item')
val = $t.find('.comment .input').text()
WorkActions.addItem @props.item,val
$input = $(e.target).closest('.item').find('.comment .input')
val = $input.text()
return if val.length is 0
WorkActions.addComment @props.item,val
$input.text('')
formatDate: (d) ->
formatDate: (d,l) ->
return "" if d is null
"~#{d.getFullYear()}.#{(d.getMonth()+1)}.#{d.getDate()}"
_d = "~#{d.getFullYear()}.#{(d.getMonth()+1)}.#{d.getDate()}"
if l
_d += "..#{d.getHours()}.#{d.getMinutes()}.#{d.getSeconds()}"
_d
formatOwner: (o) ->
return "" if o is null
@ -155,11 +161,20 @@ module.exports = recl
renderTopField: (key,props,format)->
_props = _.extend {className:"#{props.className ? key} top"}, props
@renderField key,_props,format
componentDidMount: ->
formatDate = @formatDate
setInterval ->
$('.new.comment .date').text formatDate (new Date()),true
, 1000
render: ->
itemClass = 'item'
if @state.expand then itemClass += ' expand'
discussion = _.clone @props.item.discussion
discussion.reverse()
action = ""
if @props.item.status is 'announced'
action = "claim"
@ -186,7 +201,7 @@ module.exports = recl
(@renderField 'audience', {}, @formatAudience)
])
(div {className:'sort ib top'}, @props.item.sort)
(div {className:'done ib', onClick:@_markDone}, '')
(div {className:'done ib done-'+@props.item.done?, onClick:@_markDone}, '')
(@renderTopField 'title', {@onFocus,@onKeyDown})
(@renderTopField 'date_due', {className:'date'}, @formatDate)
(@renderTopField 'tags', {}, (tags)-> tags.join(" "))
@ -199,18 +214,18 @@ module.exports = recl
(div {className:"hr"},"")
(div {className:"discussion"},[
(div {className:"comments"}, @props.item.discussion.map (slug) =>
(div {className:"comments"}, discussion.map (slug) =>
(div {className:'comment'}, [
(div {className:'hr2'},"")
(div {className:'ship ib'}, slug.ship)
(div {className:'date ib'}, @formatDate(slug.date))
(div {className:'date ib'}, @formatDate(slug.date,true))
(div {className:'body'}, slug.body)
])
),
(div {className:'new comment'},[
(div {className:'hr2'},"")
(div {className:'ship ib'}, window.urb.ship)
(div {className:'date ib'}, @formatDate(new Date()))
(div {className:'date ib'}, @formatDate(new Date(),true))
(div {
contentEditable:true,
className:'input'},"")

View File

@ -68,7 +68,17 @@ module.exports = {
}
});
},
addItem: function(arg, val) {
setAudience: function(arg, val) {
var id;
id = arg.id;
return Persistence.put({
audience: {
id: id,
to: val
}
});
},
addComment: function(arg, val) {
var id, version;
id = arg.id, version = arg.version;
version += 1;
@ -165,14 +175,28 @@ rece = React.createElement;
ref = React.DOM, div = ref.div, h1 = ref.h1, label = ref.label;
module.exports = recl({
_onKeyDown: function(e) {
onClick: function(e) {
var b;
switch (this.props.filters['done']) {
case null:
b = true;
break;
case true:
b = false;
break;
case false:
b = null;
}
return this.props.onChange('done', b);
},
onKeyDown: function(e) {
if (e.keyCode === 13) {
e.stopPropagation();
e.preventDefault();
return this.change(e);
}
},
_onBlur: function(e) {
onBlur: function(e) {
return this.change(e);
},
change: function(e) {
@ -198,6 +222,10 @@ module.exports = recl({
},
fields: [
{
filter: 'done',
key: 'done',
title: ''
}, {
filter: 'owned',
key: 'owner',
title: 'Owner:'
@ -220,20 +248,25 @@ module.exports = recl({
className: 'filters'
}, this.fields.map((function(_this) {
return function(arg) {
var filter, key, title;
var filter, input, key, title;
filter = arg.filter, key = arg.key, title = arg.title;
input = div({
contentEditable: true,
className: 'input ib',
onKeyDown: _this.onKeyDown,
onBlur: _this.onBlur
}, _this.props.filters[filter]);
if (filter === 'done') {
input = div({
className: 'input-bool ib ' + _this.props.filters[key],
onClick: _this.onClick
}, "");
}
return div({
key: key,
'data-key': key,
className: filter + " filter ib"
}, [
label({}, title), div({
contentEditable: true,
className: 'input ib',
onKeyDown: _this._onKeyDown,
onBlur: _this._onBlur
}, _this.props.filters[filter])
]);
}, [label({}, title), input]);
};
})(this)));
}
@ -424,7 +457,7 @@ module.exports = recl({
return this.props._focus(e, this);
},
_markDone: function(e) {
return WorkActions.setItem(this.props.item, 'done', true);
return WorkActions.setItem(this.props.item, 'done', this.props.item.done == null);
},
_changeStatus: function(e) {
var own;
@ -443,16 +476,25 @@ module.exports = recl({
return WorkActions.ownItem(this.props.item, own);
},
_submitComment: function(e) {
var $t, val;
$t = $(e.target).closest('.item');
val = $t.find('.comment .input').text();
return WorkActions.addItem(this.props.item, val);
var $input, val;
$input = $(e.target).closest('.item').find('.comment .input');
val = $input.text();
if (val.length === 0) {
return;
}
WorkActions.addComment(this.props.item, val);
return $input.text('');
},
formatDate: function(d) {
formatDate: function(d, l) {
var _d;
if (d === null) {
return "";
}
return "~" + (d.getFullYear()) + "." + (d.getMonth() + 1) + "." + (d.getDate());
_d = "~" + (d.getFullYear()) + "." + (d.getMonth() + 1) + "." + (d.getDate());
if (l) {
_d += ".." + (d.getHours()) + "." + (d.getMinutes()) + "." + (d.getSeconds());
}
return _d;
},
formatOwner: function(o) {
if (o === null) {
@ -493,12 +535,21 @@ module.exports = recl({
}, props);
return this.renderField(key, _props, format);
},
componentDidMount: function() {
var formatDate;
formatDate = this.formatDate;
return setInterval(function() {
return $('.new.comment .date').text(formatDate(new Date(), true));
}, 1000);
},
render: function() {
var action, itemClass;
var action, discussion, itemClass;
itemClass = 'item';
if (this.state.expand) {
itemClass += ' expand';
}
discussion = _.clone(this.props.item.discussion);
discussion.reverse();
action = "";
if (this.props.item.status === 'announced') {
action = "claim";
@ -531,7 +582,7 @@ module.exports = recl({
]), div({
className: 'sort ib top'
}, this.props.item.sort), div({
className: 'done ib',
className: 'done ib done-' + (this.props.item.done != null),
onClick: this._markDone
}, ''), this.renderTopField('title', {
onFocus: this.onFocus,
@ -560,7 +611,7 @@ module.exports = recl({
}, [
div({
className: "comments"
}, this.props.item.discussion.map((function(_this) {
}, discussion.map((function(_this) {
return function(slug) {
return div({
className: 'comment'
@ -571,7 +622,7 @@ module.exports = recl({
className: 'ship ib'
}, slug.ship), div({
className: 'date ib'
}, _this.formatDate(slug.date)), div({
}, _this.formatDate(slug.date, true)), div({
className: 'body'
}, slug.body)
]);
@ -585,7 +636,7 @@ module.exports = recl({
className: 'ship ib'
}, window.urb.ship), div({
className: 'date ib'
}, this.formatDate(new Date())), div({
}, this.formatDate(new Date(), true)), div({
contentEditable: true,
className: 'input'
}, ""), div({
@ -1419,6 +1470,7 @@ _list = ["0v0", "0v1", "0v2"];
_listening = [];
_filters = {
done: null,
owner: null,
tags: null,
audience: null,
@ -1426,10 +1478,10 @@ _filters = {
};
_sorts = {
sort: 0,
title: 0,
owner: 0,
date_due: 0,
sort: 0
date_due: 0
};
WorkStore = assign({}, EventEmitter.prototype, {
@ -1457,26 +1509,41 @@ WorkStore = assign({}, EventEmitter.prototype, {
})(this));
},
getList: function(key) {
var add, atr, c, i, id, k, len, list, task, v;
var _k, _v, add, c, i, id, k, len, list, task, v;
list = [];
for (i = 0, len = _list.length; i < len; i++) {
id = _list[i];
task = _tasks[id];
add = true;
for (atr in _filters) {
v = _filters[atr];
if (v === null) {
for (_k in _filters) {
_v = _filters[_k];
if (_v === null) {
continue;
}
c = task[atr];
if (typeof c === 'object') {
if (_.intersection(c, v).length === 0) {
add = false;
}
} else {
if (c !== v) {
add = false;
}
c = task[_k];
switch (_k) {
case 'tags' || 'audience':
if (_.intersection(c, _v).length === 0) {
add = false;
}
break;
case 'owner':
if (c !== _v.replace(/\~/g, "")) {
add = false;
}
break;
case 'done':
if (_v === true && !c) {
add = false;
}
if (_v === false && c) {
add = false;
}
break;
default:
if (c !== _v) {
add = false;
}
}
}
if (add === true) {

View File

@ -57,15 +57,16 @@ _tasks =
_list = ["0v0","0v1","0v2"]
_listening = []
_filters =
done:null
owner:null
tags:null
audience:null
status:null
_sorts =
sort:0
title:0
owner:0
date_due:0
sort:0
WorkStore = assign {},EventEmitter.prototype,{
emitChange: -> @emit 'change'
@ -84,13 +85,19 @@ WorkStore = assign {},EventEmitter.prototype,{
for id in _list
task = _tasks[id]
add = true
for atr,v of _filters
if v is null then continue
c = task[atr]
if typeof(c) is 'object'
if _.intersection(c,v).length is 0 then add = false
else
if c isnt v then add = false
for _k,_v of _filters
if _v is null then continue
c = task[_k]
switch _k
when 'tags' or 'audience'
if _.intersection(c,_v).length is 0 then add = false
when 'owner'
if c isnt _v.replace(/\~/g, "") then add = false
when 'done'
if _v is true and not c then add = false
if _v is false and c then add = false
else
if c isnt _v then add = false
if add is true
list.push task
if _.uniq(_.values(_sorts)).length > 0

View File

@ -83,6 +83,7 @@
++ duty ::
$% [%create tax=task] :: create new task
[%claim id=@uvH] :: claim task
[%archive id=@uvH] :: archive task
$: %update :: operate on task
id=@uvH :: which task
version=@u :: version

View File

@ -6,8 +6,9 @@
==
++ client-task
$: claiming=_|
archived=_|
audience=(set station:talk)
task=task
tax=task
==
++ task
$: id=@uvH
@ -33,6 +34,7 @@
$% [%new audience=(set station:talk) task]
[%old id=@uvH version=@u dif=update]
[%sort p=(list ,@uvH)]
[%audience id=@uvH to=(set station:talk)]
==
++ update
$% $: %set
@ -41,7 +43,6 @@
[%description p=@t]
[%tags p=(set ,@t)]
[%done p=?]
[%audience p=(set station:talk)]
== ==
$: %add
$% [%comment @t]