mirror of
https://github.com/urbit/shrub.git
synced 2024-12-14 11:08:45 +03:00
Merge branch 'kidsort-fixed', remote-tracking branches 'wilderr/master', 'anton/talk-offline' and 'curtis/trivial' into pending
kidsort-fixed is a fixed version of galen/kidsort. fixes #516
This commit is contained in:
commit
7b10fd3f47
@ -951,7 +951,6 @@
|
|||||||
::
|
::
|
||||||
++ bind :: %bind
|
++ bind :: %bind
|
||||||
|= [cha=char pan=(unit (set partner))] ^+ ..sh-work
|
|= [cha=char pan=(unit (set partner))] ^+ ..sh-work
|
||||||
~& bind/[cha pan nik nak]
|
|
||||||
?~ pan $(pan [~ ?~(active.she passive.she u.active.she)])
|
?~ pan $(pan [~ ?~(active.she passive.she u.active.she)])
|
||||||
=+ ole=(~(get by nik) u.pan)
|
=+ ole=(~(get by nik) u.pan)
|
||||||
?: =(ole [~ cha]) ..sh-work
|
?: =(ole [~ cha]) ..sh-work
|
||||||
@ -1102,7 +1101,8 @@
|
|||||||
(sh-slug lit)
|
(sh-slug lit)
|
||||||
=+ jub=(rust (tufa buf.say.she) sh-scad)
|
=+ jub=(rust (tufa buf.say.she) sh-scad)
|
||||||
?~ jub (sh-fact %bel ~)
|
?~ jub (sh-fact %bel ~)
|
||||||
=. +> (sh-work u.jub)
|
%. u.jub
|
||||||
|
=< sh-work
|
||||||
=+ buf=buf.say.she
|
=+ buf=buf.say.she
|
||||||
=^ cal say.she (~(transmit sole say.she) [%set ~])
|
=^ cal say.she (~(transmit sole say.she) [%set ~])
|
||||||
%- sh-fact
|
%- sh-fact
|
||||||
@ -1111,7 +1111,7 @@
|
|||||||
[%det cal]
|
[%det cal]
|
||||||
?. ?=([%';' *] buf) ~
|
?. ?=([%';' *] buf) ~
|
||||||
:_ ~
|
:_ ~
|
||||||
[%txt (weld "----------------| " (tufa buf))]
|
[%txt (runt [14 '-'] `tape`['|' ' ' (tufa buf)])]
|
||||||
==
|
==
|
||||||
::
|
::
|
||||||
++ sh-sole :: apply edit
|
++ sh-sole :: apply edit
|
||||||
@ -2040,7 +2040,8 @@
|
|||||||
^- (quip move +>)
|
^- (quip move +>)
|
||||||
?~ saw [~ +>]
|
?~ saw [~ +>]
|
||||||
%+ etch-friend [%friend way] |= [man=span cuz=station]
|
%+ etch-friend [%friend way] |= [man=span cuz=station]
|
||||||
~& [%reap-friend-fail man cuz u.saw]
|
=. u.saw [>%reap-friend-fail man cuz< u.saw]
|
||||||
|
%- (slog (flop u.saw))
|
||||||
ra-abet:(ra-quit:ra man cuz)
|
ra-abet:(ra-quit:ra man cuz)
|
||||||
::
|
::
|
||||||
++ quit-friend ::
|
++ quit-friend ::
|
||||||
|
33
lib/urb.js
33
lib/urb.js
@ -20,6 +20,7 @@ window.urb.req = function(method,url,params,json,cb) {
|
|||||||
if(params.wire) { _data.wire = params.wire; }
|
if(params.wire) { _data.wire = params.wire; }
|
||||||
if(cb) {
|
if(cb) {
|
||||||
xhr.onload = function() {
|
xhr.onload = function() {
|
||||||
|
var err,res
|
||||||
try {
|
try {
|
||||||
err = null
|
err = null
|
||||||
res = {
|
res = {
|
||||||
@ -36,8 +37,10 @@ window.urb.req = function(method,url,params,json,cb) {
|
|||||||
}
|
}
|
||||||
res = null
|
res = null
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
cb(err,res)
|
cb(err,res)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
xhr.onerror = function() {
|
xhr.onerror = function() {
|
||||||
cb({
|
cb({
|
||||||
status:this.status,
|
status:this.status,
|
||||||
@ -64,7 +67,7 @@ window.urb.qreq = function(method,url,params,json,cb) {
|
|||||||
walk = function() {
|
walk = function() {
|
||||||
qobj = {}
|
qobj = {}
|
||||||
qobj.oargs = window.urb.reqq[0]
|
qobj.oargs = window.urb.reqq[0]
|
||||||
qobj.nargs = [].slice.apply(qobj.oargs,[0,4])
|
qobj.nargs = [].slice.call(qobj.oargs,0,4)
|
||||||
qobj.nargs.push(function(){
|
qobj.nargs.push(function(){
|
||||||
if(this.oargs[4])
|
if(this.oargs[4])
|
||||||
this.oargs[4].apply(window.urb,arguments)
|
this.oargs[4].apply(window.urb,arguments)
|
||||||
@ -90,6 +93,7 @@ window.urb.send = function(data,params,cb) { // or send(data, cb)
|
|||||||
params.ship = params.ship || this.ship
|
params.ship = params.ship || this.ship
|
||||||
params.appl = params.appl || this.appl
|
params.appl = params.appl || this.appl
|
||||||
params.mark = params.mark || $send.mark
|
params.mark = params.mark || $send.mark
|
||||||
|
// params.seqn = params.seqn || $send.seqn
|
||||||
params.wire = params.wire || "/"
|
params.wire = params.wire || "/"
|
||||||
params.xyro = (typeof(params.data) === 'undefined') ? null : params.data
|
params.xyro = (typeof(params.data) === 'undefined') ? null : params.data
|
||||||
|
|
||||||
@ -100,17 +104,17 @@ window.urb.send = function(data,params,cb) { // or send(data, cb)
|
|||||||
url = ["to",params.appl,params.mark]
|
url = ["to",params.appl,params.mark]
|
||||||
url = "/~/"+url.join("/")
|
url = "/~/"+url.join("/")
|
||||||
|
|
||||||
$send.seqn++
|
// $send.seqn++
|
||||||
|
|
||||||
this.qreq('post',url,params,true,function(err,data) {
|
this.qreq('post',url,params,true,function(err,data) {
|
||||||
if(err) { $send.seqn--; }
|
/* if(err) { $send.seqn--; }
|
||||||
else if(data && data.data.fail && urb.wall !== false)
|
else */ if(data && data.data.fail && urb.wall !== false)
|
||||||
document.write("<pre>"+JSON.stringify(params.xyro)+"\n"
|
document.write("<pre>"+JSON.stringify(params.xyro)+"\n"
|
||||||
+data.data.mess+"</pre>") // XX
|
+data.data.mess+"</pre>") // XX
|
||||||
if(cb) { cb.apply(this,arguments); }
|
if(cb) { cb.apply(this,arguments); }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
window.urb.send.seqn = 0
|
// window.urb.send.seqn = 0
|
||||||
window.urb.send.mark = "json"
|
window.urb.send.mark = "json"
|
||||||
|
|
||||||
|
|
||||||
@ -139,6 +143,7 @@ window.urb.poll = function(params) {
|
|||||||
|
|
||||||
$this = this
|
$this = this
|
||||||
this.req("get",url,params,true,function(err,res) {
|
this.req("get",url,params,true,function(err,res) {
|
||||||
|
$this.poll.dely = params.dely || $this.poll.dely
|
||||||
if(res){
|
if(res){
|
||||||
if(res.data.beat)
|
if(res.data.beat)
|
||||||
return $this.poll(params)
|
return $this.poll(params)
|
||||||
@ -158,27 +163,25 @@ window.urb.poll = function(params) {
|
|||||||
default:
|
default:
|
||||||
throw new Error("Lost event %"+res.data.type)
|
throw new Error("Lost event %"+res.data.type)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dely = params.dely || $this.poll.dely
|
|
||||||
|
|
||||||
if(err)
|
|
||||||
dely = dely+Math.ceil(dely*.02)
|
|
||||||
else {
|
|
||||||
$this.poll.dely = 0
|
|
||||||
if(params.incs)
|
if(params.incs)
|
||||||
params.incs()
|
params.incs()
|
||||||
else
|
else
|
||||||
$this.poll.seqn++
|
$this.poll.seqn++
|
||||||
|
$this.poll.dely = 250
|
||||||
|
return $this.poll(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(err){
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$this.poll(params)
|
$this.poll(params)
|
||||||
},dely)
|
}, $this.poll.dely)
|
||||||
|
$this.poll.dely += Math.ceil($this.poll.dely*.2)
|
||||||
|
}
|
||||||
|
else throw "Neither error nor result on poll"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
window.urb.poll.seqn = 1
|
window.urb.poll.seqn = 1
|
||||||
window.urb.poll.dely = 0
|
window.urb.poll.dely = 250
|
||||||
|
|
||||||
window.urb.bind = function(path, params, cb, nicecb){ // or bind(path, cb)
|
window.urb.bind = function(path, params, cb, nicecb){ // or bind(path, cb)
|
||||||
if(!params || typeof params === "function")
|
if(!params || typeof params === "function")
|
||||||
|
@ -22,9 +22,9 @@ The main disadvantage of Hoon is that its syntax and semantics
|
|||||||
are unfamiliar. The syntax will remind too many of Perl, but
|
are unfamiliar. The syntax will remind too many of Perl, but
|
||||||
like most human languages (and unlike Perl) it combines a regular
|
like most human languages (and unlike Perl) it combines a regular
|
||||||
core structure with irregular variations. And Hoon's semantic
|
core structure with irregular variations. And Hoon's semantic
|
||||||
is bounded by the size of the compiler: type inference plus code
|
complexity is bounded by the size of the compiler: type inference plus code
|
||||||
generation are 2000 lines of Hoon. Most peoples' experience is
|
generation are 2000 lines of Hoon. Most peoples' experience is that the
|
||||||
that the language is much easier to learn than it looks.
|
language is much easier to learn than it looks.
|
||||||
|
|
||||||
> The name "Hoon" is from the Wallace Stevens poem, _Tea at the
|
> The name "Hoon" is from the Wallace Stevens poem, _Tea at the
|
||||||
Palaz of Hoon_. It also means "hooligan" in Australian.
|
Palaz of Hoon_. It also means "hooligan" in Australian.
|
||||||
@ -71,6 +71,19 @@ as the range of a mold function. This mold can also be used to
|
|||||||
validate or normalize untrusted, untyped data -- a common problem
|
validate or normalize untrusted, untyped data -- a common problem
|
||||||
in modern programming, because networks.
|
in modern programming, because networks.
|
||||||
|
|
||||||
|
> Sending a noun over the network is a good example of why Hoon
|
||||||
|
is different. In a normal modern language, you serialize and
|
||||||
|
deserialize a data type by extending your type to implement a
|
||||||
|
serialization interface. A really good language can process your
|
||||||
|
type definition and automatically generate this code. In Hoon,
|
||||||
|
we have one function `jam` that converts any noun to an atom,
|
||||||
|
and another `cue` that inverts `jam`. To validate, the receiver
|
||||||
|
applies its own mold to the cued noun, and we've sent typed data
|
||||||
|
over the network without any attack surface (except `jam` and
|
||||||
|
`cue`, which fit on a page). No custom serialization code,
|
||||||
|
manual or generated, is required. The mold itself is not sent;
|
||||||
|
protocol agreement is out of band.
|
||||||
|
|
||||||
Hoon's inference algorithm is dumber than the unification
|
Hoon's inference algorithm is dumber than the unification
|
||||||
algorithms (Hindley-Milner) used in most typed functional
|
algorithms (Hindley-Milner) used in most typed functional
|
||||||
languages. Hoon thinks only forward, not backward. Eg, Haskell
|
languages. Hoon thinks only forward, not backward. Eg, Haskell
|
||||||
@ -78,26 +91,19 @@ can infer the result type of a function from its argument
|
|||||||
(forward), or the argument type from the result (backward).
|
(forward), or the argument type from the result (backward).
|
||||||
Hoon can do the first but not the second.
|
Hoon can do the first but not the second.
|
||||||
|
|
||||||
So Hoon needs more manual typecasts, which you usually want
|
So Hoon needs more manual annotations, which you usually want
|
||||||
anyway for prosaic software-engineering reasons. Otherwise its
|
anyway for prosaic software-engineering reasons. Otherwise its
|
||||||
typesystem solves more or less the same job, including
|
typesystem solves more or less the same job, including
|
||||||
pattern-matching, genericity / typeclasses, etc.
|
pattern-matching, genericity / typeclasses, etc.
|
||||||
|
|
||||||
> Sending a noun over the network is a good example of why Hoon
|
> A good test of a static higher-order typesystem is whether it can
|
||||||
is different. In a normal modern language, you serialize and
|
infer the product type of a grammar defined as a combinator
|
||||||
deserialize a data type by extending your type to implement a
|
parser. The Hoon parser passes this test; when it typechecks,
|
||||||
serialization interface. In Hoon, any value is just a noun, so
|
the parser's range nests within the span of the expression mold.
|
||||||
we have one function (`jam`) that converts any noun to an atom,
|
|
||||||
and another (`cue`) that is its inverse. To validate, the
|
|
||||||
receiver runs its own mold on the cued noun, and we've sent typed
|
|
||||||
data over the network without any attack surface (except `jam`
|
|
||||||
and `cue`, which fit on a page). No custom serialization methods
|
|
||||||
are required, and the mold itself is never sent; protocol
|
|
||||||
agreement is out of band.
|
|
||||||
|
|
||||||
## Let's make some nouns
|
## Let's make some nouns
|
||||||
|
|
||||||
Nouns aren't even slightly hard. Let's make a noun:
|
Let's make a noun:
|
||||||
```
|
```
|
||||||
~tasfyn-partyv:dojo> 42
|
~tasfyn-partyv:dojo> 42
|
||||||
```
|
```
|
||||||
@ -106,7 +112,7 @@ You'll see the expression you entered, then the result:
|
|||||||
> 42
|
> 42
|
||||||
42
|
42
|
||||||
```
|
```
|
||||||
Let's try a different value:
|
Let's try a different noun. Or is it different?
|
||||||
```
|
```
|
||||||
~tasfyn-partyv:dojo> 0x2a
|
~tasfyn-partyv:dojo> 0x2a
|
||||||
```
|
```
|
||||||
@ -138,11 +144,11 @@ Let's make some cells. Try these on your own urbit:
|
|||||||
We observe that cells associate right: `[a b c]` is just another
|
We observe that cells associate right: `[a b c]` is just another
|
||||||
way of writing `[a [b c]]`.
|
way of writing `[a [b c]]`.
|
||||||
|
|
||||||
> Lisp veterans beware: Hoon `[a b]` is Lisp `(a . b)`, Lisp
|
Lisp masters beware: Hoon `[a b]` is Lisp `(a . b)`, Lisp
|
||||||
`(a b)` is Hoon `[a b ~]`(`~` represents nil, with a value of
|
`(a b)` is Hoon `[a b ~]`. `~` means nil, with value zero. Lisp
|
||||||
atom `0`). Lisp and Hoon are both pair-oriented languages down
|
and Hoon are both pair-oriented languages down below, but Lisp
|
||||||
below, but Lisp has a layer of sugar that makes it look
|
has a layer of sugar that makes it look list-oriented. Hoon
|
||||||
list-oriented. Hoon loves its "improper lists," ie, tuples.
|
loves its "improper lists," ie, tuples.
|
||||||
|
|
||||||
## Looking at spans
|
## Looking at spans
|
||||||
|
|
||||||
@ -169,15 +175,17 @@ type food chain.
|
|||||||
|
|
||||||
## Looking at spans, part 2
|
## Looking at spans, part 2
|
||||||
|
|
||||||
Good style in Hoon is concrete style. When a Hoon programmer
|
Usually, good style in Hoon is concrete style. When a Hoon
|
||||||
defines an abstract semantic value in terms of a noun, we rarely
|
programmer defines an abstract semantic value in terms of a noun,
|
||||||
put a conceptual layer of abstraction between value and noun. We
|
we rarely put a conceptual layer of abstraction between value and
|
||||||
think of the semantic value as an interpretation of the
|
noun. We think of the value as an interpretation of the noun.
|
||||||
concrete noun, and often we just think of the noun.
|
We don't think of the noun as an implementation of the noun.
|
||||||
|
|
||||||
With the `?` command, we *do* use an abstract layer, by printing
|
But rules are made to be broken. With the `?` command, we *do*
|
||||||
our span noun in a custom syntax. But we can also look at the
|
use an abstract layer, by printing our span noun in that custom
|
||||||
span noun directly, with the `??` command.
|
syntax. But we can also look at the span noun directly, with the
|
||||||
|
`??` command. As we'll see, `??` is mainly for newbies, but
|
||||||
|
newbies love it.
|
||||||
|
|
||||||
```
|
```
|
||||||
~tasfyn-partyv:dojo> ?? 42
|
~tasfyn-partyv:dojo> ?? 42
|
||||||
@ -228,12 +236,12 @@ numbers we've just been using, and make them constants:
|
|||||||
%42
|
%42
|
||||||
```
|
```
|
||||||
|
|
||||||
> Spans are an exception to the concrete style, because we use
|
> Why `??`? Spans are an exception to concrete style, because they
|
||||||
"manual laziness" to define recursive structures. A recursive
|
use "manual laziness" to define logically recursive structures.
|
||||||
span contains Hoon code which is evaluated to apply it. In
|
A recursive span contains Hoon code which is evaluated to apply
|
||||||
practice, it often contains the entire Urbit kernel, so you
|
it. In practice, this noun often contains the entire Urbit
|
||||||
wouldn't want to try to print it in the dojo. If you find
|
kernel, so you wouldn't want to try to print it in the dojo. If
|
||||||
`??` taking a weirdly long time, this may have happened; just
|
you find `??` taking a weirdly long time, this may have happened;
|
||||||
press ^C.
|
press ^C.
|
||||||
|
|
||||||
## Our first mold
|
## Our first mold
|
||||||
|
@ -62,7 +62,7 @@ And hit return. Don't worry, no one but you will see this. The
|
|||||||
|
|
||||||
It's boring to post to yourself. Let's join a station:
|
It's boring to post to yourself. Let's join a station:
|
||||||
|
|
||||||
~fintud-macrep: ;join /urbit-meta
|
~fintud-macrep: ;join ~doznec/urbit-meta
|
||||||
|
|
||||||
(`/urbit-meta` is a federal station, meaning it's hosted by your
|
(`/urbit-meta` is a federal station, meaning it's hosted by your
|
||||||
star (for `~fintud-macrep`, `~doznec`). The `/` notation is just
|
star (for `~fintud-macrep`, `~doznec`). The `/` notation is just
|
||||||
|
@ -591,6 +591,15 @@ a {
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
body:not(.offline) #offline {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#offline {
|
||||||
|
transition: color 0.25s ease;
|
||||||
|
}
|
||||||
|
#offline.error {
|
||||||
|
color: #f00;
|
||||||
|
}
|
||||||
@media only screen and (min-width: 1024px) {
|
@media only screen and (min-width: 1024px) {
|
||||||
#station-container:hover {
|
#station-container:hover {
|
||||||
max-height: 30rem;
|
max-height: 30rem;
|
||||||
|
@ -549,4 +549,17 @@ a
|
|||||||
font-size .8rem
|
font-size .8rem
|
||||||
text-transform uppercase
|
text-transform uppercase
|
||||||
|
|
||||||
|
//
|
||||||
|
// offline
|
||||||
|
//
|
||||||
|
|
||||||
|
body:not(.offline) #offline
|
||||||
|
display none
|
||||||
|
|
||||||
|
#offline
|
||||||
|
transition: color 0.25s ease
|
||||||
|
|
||||||
|
#offline.error
|
||||||
|
color: red
|
||||||
|
|
||||||
@import 'mobile'
|
@import 'mobile'
|
||||||
|
@ -1,33 +1,26 @@
|
|||||||
MessageDispatcher = require '../dispatcher/Dispatcher.coffee'
|
Dispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||||
|
|
||||||
module.exports =
|
_persistence = require '../persistence/MessagePersistence.coffee'
|
||||||
loadMessages: (grams,get) ->
|
|
||||||
MessageDispatcher.handleServerAction
|
Persistence = _persistence MessageActions: module.exports =
|
||||||
type:"messages-load"
|
loadMessages: (messages,last,get) ->
|
||||||
messages:grams.tele
|
Dispatcher.handleServerAction {messages,last,get,type:"messages-load"}
|
||||||
last:grams.num
|
|
||||||
get:get
|
|
||||||
|
|
||||||
listenStation: (station,date) ->
|
listenStation: (station,date) ->
|
||||||
if not date then date = window.urb.util.toDate(new Date())
|
if not date then date = window.urb.util.toDate(new Date())
|
||||||
window.talk.MessagePersistence.listenStation station,date
|
Persistence.listenStation station,date
|
||||||
|
|
||||||
listeningStation: (station) ->
|
listeningStation: (station) ->
|
||||||
MessageDispatcher.handleViewAction
|
Dispatcher.handleViewAction {station,type:"messages-listen"}
|
||||||
type:"messages-listen"
|
|
||||||
station:station
|
|
||||||
|
|
||||||
setTyping: (state) ->
|
setTyping: (state) ->
|
||||||
MessageDispatcher.handleViewAction
|
Dispatcher.handleViewAction {state,type:"messages-typing"}
|
||||||
type:"messages-typing"
|
|
||||||
state:state
|
|
||||||
|
|
||||||
getMore: (station,start,end) ->
|
getMore: (station,start,end) ->
|
||||||
MessageDispatcher.handleViewAction
|
Dispatcher.handleViewAction type:"messages-fetch"
|
||||||
type:"messages-fetch"
|
Persistence.get station,start,end
|
||||||
window.talk.MessagePersistence.get station,start,end
|
|
||||||
|
|
||||||
sendMessage: (message,audience) ->
|
sendMessage: (txt,audience) ->
|
||||||
serial = window.util.uuid32()
|
serial = window.util.uuid32()
|
||||||
|
|
||||||
# audience.push window.util.mainStationPath window.urb.user
|
# audience.push window.util.mainStationPath window.urb.user
|
||||||
@ -41,20 +34,17 @@ module.exports =
|
|||||||
sender:null
|
sender:null
|
||||||
delivery:"pending"
|
delivery:"pending"
|
||||||
|
|
||||||
speech =
|
speech = lin: {txt, say:true}
|
||||||
lin:
|
|
||||||
say:true
|
|
||||||
txt:message
|
|
||||||
|
|
||||||
if message[0] is "@"
|
if txt[0] is "@"
|
||||||
speech.lin.txt = speech.lin.txt.slice(1).trim()
|
speech.lin.txt = speech.lin.txt.slice(1).trim()
|
||||||
speech.lin.say = false
|
speech.lin.say = false
|
||||||
|
|
||||||
else if message[0] is "#"
|
else if txt[0] is "#"
|
||||||
speech = eval: speech.lin.txt.slice(1).trim()
|
speech = eval: speech.lin.txt.slice(1).trim()
|
||||||
|
|
||||||
else if window.urb.util.isURL(message)
|
else if window.urb.util.isURL(txt)
|
||||||
speech = url: message
|
speech = url: txt
|
||||||
|
|
||||||
speeches =
|
speeches =
|
||||||
if not (speech.lin?.txt.length > 64)
|
if not (speech.lin?.txt.length > 64)
|
||||||
@ -70,7 +60,7 @@ module.exports =
|
|||||||
}
|
}
|
||||||
|
|
||||||
for speech in speeches
|
for speech in speeches
|
||||||
_message =
|
message =
|
||||||
ship:window.urb.ship
|
ship:window.urb.ship
|
||||||
thought:
|
thought:
|
||||||
serial:window.util.uuid32()
|
serial:window.util.uuid32()
|
||||||
@ -80,8 +70,6 @@ module.exports =
|
|||||||
speech:speech
|
speech:speech
|
||||||
date: Date.now()
|
date: Date.now()
|
||||||
|
|
||||||
MessageDispatcher.handleViewAction
|
Dispatcher.handleViewAction {message,type:"message-send"}
|
||||||
type:"message-send"
|
Persistence.sendMessage message.thought
|
||||||
message:_message
|
|
||||||
window.talk.MessagePersistence.sendMessage _message.thought
|
|
||||||
|
|
||||||
|
@ -1,76 +1,31 @@
|
|||||||
StationDispatcher = require '../dispatcher/Dispatcher.coffee'
|
Dispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||||
|
serverAction = (f)-> ()-> Dispatcher.handleServerAction f.apply this,arguments
|
||||||
|
viewAction = (f)-> ()-> Dispatcher.handleViewAction f.apply this,arguments
|
||||||
|
|
||||||
module.exports =
|
_persistence = require '../persistence/StationPersistence.coffee'
|
||||||
loadConfig: (station,config) ->
|
|
||||||
StationDispatcher.handleServerAction
|
|
||||||
type: "config-load"
|
|
||||||
station:station
|
|
||||||
config:config
|
|
||||||
|
|
||||||
loadGlyphs: (glyphs) ->
|
Persistence = _persistence StationActions: module.exports =
|
||||||
StationDispatcher.handleServerAction
|
loadGlyphs: serverAction (glyphs) -> {glyphs,type:"glyphs-load"}
|
||||||
type: "glyphs-load"
|
loadMembers: serverAction (members) -> {members,type:"members-load"}
|
||||||
station:station
|
loadStations: serverAction (stations) -> {stations,type:"stations-load"}
|
||||||
glyphs:glyphs
|
loadConfig: serverAction (station,config) -> {station,config,type:"config-load"}
|
||||||
|
|
||||||
switchStation: (station) ->
|
setTyping: viewAction (station,state) -> {station,state,type:"typing-set"}
|
||||||
StationDispatcher.handleViewAction
|
setAudience: viewAction (audience) -> {audience,type:"station-set-audience"}
|
||||||
type:"station-switch"
|
setValidAudience: viewAction (valid) -> {valid,type:"station-set-valid-audience"}
|
||||||
station:station
|
toggleAudience: viewAction (station) -> {station,type:"station-audience-toggle"}
|
||||||
|
switchStation: viewAction (station) -> {station,type:"station-switch"}
|
||||||
setAudience: (audience) ->
|
listeningStation: viewAction (station) -> {station,type:"station-listen"}
|
||||||
StationDispatcher.handleViewAction
|
|
||||||
type:"station-set-audience"
|
|
||||||
audience:audience
|
|
||||||
|
|
||||||
setValidAudience: (valid) ->
|
|
||||||
StationDispatcher.handleViewAction
|
|
||||||
type:"station-set-valid-audience"
|
|
||||||
valid:valid
|
|
||||||
|
|
||||||
toggleAudience: (station) ->
|
|
||||||
StationDispatcher.handleViewAction
|
|
||||||
type:"station-audience-toggle"
|
|
||||||
station:station
|
|
||||||
|
|
||||||
removeStation: (station) ->
|
|
||||||
window.talk.StationPersistence.removeStation station
|
|
||||||
|
|
||||||
setSources: (station,sources) ->
|
|
||||||
window.talk.StationPersistence.setSources station,window.urb.ship,sources
|
|
||||||
|
|
||||||
createStation: (name) ->
|
|
||||||
window.talk.StationPersistence.createStation name
|
|
||||||
|
|
||||||
listenStation: (station) ->
|
|
||||||
window.talk.StationPersistence.listenStation station
|
|
||||||
|
|
||||||
listeningStation: (station) ->
|
|
||||||
StationDispatcher.handleViewAction
|
|
||||||
type:"station-listen"
|
|
||||||
station:station
|
|
||||||
|
|
||||||
setTyping: (station,state) ->
|
|
||||||
StationDispatcher.handleViewAction
|
|
||||||
type:"typing-set"
|
|
||||||
station:station
|
|
||||||
state:state
|
|
||||||
|
|
||||||
ping: (_ping) ->
|
|
||||||
window.talk.StationPersistence.ping _ping
|
|
||||||
|
|
||||||
loadStations: (stations) ->
|
|
||||||
StationDispatcher.handleServerAction
|
|
||||||
type:"stations-load"
|
|
||||||
stations:stations
|
|
||||||
|
|
||||||
loadMembers: (members) ->
|
|
||||||
StationDispatcher.handleServerAction
|
|
||||||
type:"members-load"
|
|
||||||
members:members
|
|
||||||
|
|
||||||
createStation: (station) ->
|
createStation: (station) ->
|
||||||
StationDispatcher.handleViewAction
|
Dispatcher.handleViewAction {station,type: "station-create"}
|
||||||
type: "station-create"
|
Persistence.createStation station
|
||||||
station: station
|
|
||||||
window.talk.StationPersistence.createStation station
|
listen: () -> Persistence.listen()
|
||||||
|
ping: (_ping) -> Persistence.ping _ping
|
||||||
|
removeStation: (station) -> Persistence.removeStation station
|
||||||
|
listenStation: (station) -> Persistence.listenStation station
|
||||||
|
createStation: (name) -> Persistence.createStation name
|
||||||
|
|
||||||
|
setSources: (station,sources) ->
|
||||||
|
Persistence.setSources station,window.urb.ship,sources
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
recl = React.createClass
|
recl = React.createClass
|
||||||
[div,input,textarea,h1,a] = [
|
{div,style,input,textarea,h1,a} = React.DOM
|
||||||
React.DOM.div,
|
|
||||||
React.DOM.input,
|
|
||||||
React.DOM.textarea,
|
|
||||||
React.DOM.h1,
|
|
||||||
React.DOM.a
|
|
||||||
]
|
|
||||||
|
|
||||||
StationStore = require '../stores/StationStore.coffee'
|
StationStore = require '../stores/StationStore.coffee'
|
||||||
StationActions = require '../actions/StationActions.coffee'
|
StationActions = require '../actions/StationActions.coffee'
|
||||||
Member = require './MemberComponent.coffee'
|
Member = require './MemberComponent.coffee'
|
||||||
|
|
||||||
module.exports = recl
|
module.exports = recl
|
||||||
|
displayName: "Station"
|
||||||
stateFromStore: -> {
|
stateFromStore: -> {
|
||||||
audi:StationStore.getAudience()
|
audi:StationStore.getAudience()
|
||||||
members:StationStore.getMembers()
|
members:StationStore.getMembers()
|
||||||
@ -88,7 +83,7 @@ module.exports = recl
|
|||||||
else
|
else
|
||||||
members = ""
|
members = ""
|
||||||
|
|
||||||
sourceInput = [(input {className:"join",onKeyUp:@_keyUp,placeholder:"+"}, "")]
|
sourceInput = [(input {className:"join",onKeyUp:@_keyUp,placeholder:"+"})]
|
||||||
sourceCtrl = div {className:"sour-ctrl"},sourceInput
|
sourceCtrl = div {className:"sour-ctrl"},sourceInput
|
||||||
|
|
||||||
sources = []
|
sources = []
|
||||||
@ -103,21 +98,19 @@ module.exports = recl
|
|||||||
else
|
else
|
||||||
sources = ""
|
sources = ""
|
||||||
|
|
||||||
head = (div {id:"head"},
|
(div {id:"station",onClick:@_toggleOpen},
|
||||||
[ (div {id:"who"},[
|
(div {id:"head"},
|
||||||
(div {className:"sig"},"")
|
(div {id:"who"},
|
||||||
(div {className:"ship"},"#{window.urb.user}")
|
div {className:"sig"}
|
||||||
])
|
div {className:"ship"},"#{window.urb.user}"
|
||||||
(div {id:"where"},[
|
)
|
||||||
(div {className:"slat"},"talk")
|
(div {id:"where"},
|
||||||
(div {className:"path"},"") #window.util.mainStation(window.urb.user))
|
div {className:"slat"},"talk"
|
||||||
(div {className:"caret"},"")
|
div {className:"path"} #, window.util.mainStation(window.urb.user))
|
||||||
])
|
div {className:"caret"}
|
||||||
]
|
)
|
||||||
|
div {id:"offline"}, "Warning: no connection to server."
|
||||||
|
)
|
||||||
|
div {id:"stations"}, (h1 {}, "Listening to"),(div {},sources),sourceCtrl
|
||||||
|
div {id:"audience"}, div {}, (h1 {}, "Talking to"),(div {id:"members"},members)
|
||||||
)
|
)
|
||||||
|
|
||||||
parts.push head
|
|
||||||
parts.push (div {id:"stations"}, [(h1 {}, "Listening to"),(div {},sources),sourceCtrl])
|
|
||||||
parts.push (div {id:"audience"}, (div {},[(h1 {}, "Talking to"),(div {id:"members"},members)]))
|
|
||||||
|
|
||||||
div {id:"station",onClick:@_toggleOpen},parts
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
recl = React.createClass
|
recl = React.createClass
|
||||||
{div,br,input,textarea} = React.DOM
|
{div,br,input,textarea} = React.DOM
|
||||||
|
|
||||||
|
husl = require 'husl'
|
||||||
|
|
||||||
MessageActions = require '../actions/MessageActions.coffee'
|
MessageActions = require '../actions/MessageActions.coffee'
|
||||||
MessageStore = require '../stores/MessageStore.coffee'
|
MessageStore = require '../stores/MessageStore.coffee'
|
||||||
StationActions = require '../actions/StationActions.coffee'
|
StationActions = require '../actions/StationActions.coffee'
|
||||||
@ -149,7 +151,13 @@ module.exports = recl
|
|||||||
txt = @$writing.text()
|
txt = @$writing.text()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if txt.length > 0
|
if txt.length > 0
|
||||||
|
if window.talk.online
|
||||||
@sendMessage()
|
@sendMessage()
|
||||||
|
else
|
||||||
|
#@errHue = ((@errHue || 0) + (Math.random() * 300) + 30) % 360
|
||||||
|
#$('#offline').css color: husl.toHex @errHue, 90, 50
|
||||||
|
$('#offline').addClass('error').one 'transitionend',
|
||||||
|
-> $('#offline').removeClass 'error'
|
||||||
return false
|
return false
|
||||||
@onInput()
|
@onInput()
|
||||||
@set()
|
@set()
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
$(() ->
|
$(() ->
|
||||||
StationActions = require './actions/StationActions.coffee'
|
StationActions = require './actions/StationActions.coffee' #start poll
|
||||||
|
|
||||||
rend = React.render
|
rend = React.render
|
||||||
|
|
||||||
window.talk = {}
|
window.talk = {}
|
||||||
window.talk.MessagePersistence = require './persistence/MessagePersistence.coffee'
|
window.talk.online = yes
|
||||||
window.talk.StationPersistence = require './persistence/StationPersistence.coffee'
|
|
||||||
|
setInterval (->
|
||||||
|
window.talk.online = window.urb.poll.dely < 500
|
||||||
|
if window.talk.online
|
||||||
|
$('body').removeClass 'offline'
|
||||||
|
else $('body').addClass 'offline'
|
||||||
|
), 300
|
||||||
|
|
||||||
require './util.coffee'
|
require './util.coffee'
|
||||||
require './move.coffee'
|
require './move.coffee'
|
||||||
@ -17,7 +23,8 @@ $(() ->
|
|||||||
# $('#nav').removeClass 'scrolling'
|
# $('#nav').removeClass 'scrolling'
|
||||||
# setInterval checkScroll, 500
|
# setInterval checkScroll, 500
|
||||||
|
|
||||||
window.talk.StationPersistence.listen()
|
|
||||||
|
StationActions.listen()
|
||||||
|
|
||||||
StationComponent = require './components/StationComponent.coffee'
|
StationComponent = require './components/StationComponent.coffee'
|
||||||
MessagesComponent = require './components/MessagesComponent.coffee'
|
MessagesComponent = require './components/MessagesComponent.coffee'
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
|||||||
require './util.coffee'
|
|
||||||
require './move.coffee'
|
|
||||||
|
|
||||||
window.talk =
|
|
||||||
Component: require './components/TalkComponent.coffee'
|
|
||||||
MessagePersistence: require './persistence/MessagePersistence.coffee'
|
|
||||||
StationPersistence: require './persistence/StationPersistence.coffee'
|
|
||||||
init: (el) ->
|
|
||||||
@StationPersistence.listen()
|
|
@ -11,6 +11,7 @@
|
|||||||
"classnames": "^2.2.0",
|
"classnames": "^2.2.0",
|
||||||
"coffeeify": "~0.7.0",
|
"coffeeify": "~0.7.0",
|
||||||
"flux": "~2.0.1",
|
"flux": "~2.0.1",
|
||||||
|
"husl": "^6.0.1",
|
||||||
"lodash": "~2.4.1",
|
"lodash": "~2.4.1",
|
||||||
"moment-timezone": "~0.2.4"
|
"moment-timezone": "~0.2.4"
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
MessageActions = require '../actions/MessageActions.coffee'
|
|
||||||
|
|
||||||
window.urb.appl = "talk"
|
window.urb.appl = "talk"
|
||||||
send = (data,cb)-> window.urb.send data, {mark:"talk-command"}, cb
|
send = (data,cb)-> window.urb.send data, {mark:"talk-command"}, cb
|
||||||
module.exports =
|
|
||||||
|
module.exports = ({MessageActions}) ->
|
||||||
listenStation: (station,since) ->
|
listenStation: (station,since) ->
|
||||||
console.log 'listen station'
|
console.log 'listen station'
|
||||||
console.log arguments
|
console.log arguments
|
||||||
@ -19,7 +18,8 @@ module.exports =
|
|||||||
if res.data.ok is true
|
if res.data.ok is true
|
||||||
MessageActions.listeningStation station
|
MessageActions.listeningStation station
|
||||||
if res.data?.grams?.tele
|
if res.data?.grams?.tele
|
||||||
MessageActions.loadMessages res.data.grams
|
{tele,num} = res.data?.grams
|
||||||
|
MessageActions.loadMessages tele, num
|
||||||
|
|
||||||
get: (station,start,end) ->
|
get: (station,start,end) ->
|
||||||
end = window.urb.util.numDot end
|
end = window.urb.util.numDot end
|
||||||
@ -32,7 +32,8 @@ module.exports =
|
|||||||
console.log '/f/ /e/s'
|
console.log '/f/ /e/s'
|
||||||
console.log res
|
console.log res
|
||||||
if res.data?.grams?.tele
|
if res.data?.grams?.tele
|
||||||
MessageActions.loadMessages res.data.grams,true
|
{tele,num} = res.data?.grams
|
||||||
|
MessageActions.loadMessages tele,num,true
|
||||||
window.urb.drop "/f/#{station}/#{end}/#{start}", (err,res) ->
|
window.urb.drop "/f/#{station}/#{end}/#{start}", (err,res) ->
|
||||||
console.log 'done'
|
console.log 'done'
|
||||||
console.log res
|
console.log res
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
StationActions = require '../actions/StationActions.coffee'
|
|
||||||
|
|
||||||
window.urb.appl = "talk"
|
window.urb.appl = "talk"
|
||||||
send = (data,cb)-> window.urb.send data, {mark:"talk-command"}, cb
|
send = (data,cb)-> window.urb.send data, {mark:"talk-command"}, cb
|
||||||
design = (party,config,cb)-> send {design:{party,config}}, cb
|
design = (party,config,cb)-> send {design:{party,config}}, cb
|
||||||
module.exports =
|
module.exports = ({StationActions})->
|
||||||
createStation: (name,cb) ->
|
createStation: (name,cb) ->
|
||||||
design name, {
|
design name, {
|
||||||
sources:[]
|
sources:[]
|
||||||
|
@ -11,20 +11,34 @@ module.exports = query {kids: {body:'r', meta:'j'}}, recl
|
|||||||
if @props.dataType then klass += " #{@props.dataType}"
|
if @props.dataType then klass += " #{@props.dataType}"
|
||||||
|
|
||||||
sorted = true
|
sorted = true
|
||||||
_keys = []
|
keyed = {}
|
||||||
for k,v of @props.kids
|
for k,v of @props.kids
|
||||||
if @props.sortBy
|
if @props.sortBy
|
||||||
if @props.sortBy is 'date'
|
if @props.sortBy is 'date'
|
||||||
if not v.meta?.date? then sorted = false
|
if not v.meta?.date?
|
||||||
_k = Number v.meta.date.slice(1).replace /\./g,""
|
sorted = false
|
||||||
_keys[_k] = k
|
continue
|
||||||
|
d = v.meta.date.slice(1).split "."
|
||||||
|
if d.length < 3
|
||||||
|
sorted = false
|
||||||
|
continue
|
||||||
|
str = "#{d[0]}-#{d[1]}-#{d[2]}"
|
||||||
|
if d.length > 3
|
||||||
|
str += " #{d[3]}:#{d[4]}:#{d[5]}"
|
||||||
|
_k = Number(new Date(str))
|
||||||
|
keyed[_k] = k
|
||||||
else
|
else
|
||||||
if not v.meta?.sort? then sorted = false
|
if not v.meta?.sort? then sorted = false
|
||||||
_keys[Number(v.meta?.sort)] = k
|
keyed[Number(v.meta?.sort)] = k
|
||||||
|
|
||||||
|
if sorted isnt true
|
||||||
|
_keys = _.keys(@props.kids).sort()
|
||||||
|
else
|
||||||
|
_keys = _.keys(keyed).sort()
|
||||||
|
|
||||||
if @props.sortBy is 'date' then _keys.reverse()
|
if @props.sortBy is 'date' then _keys.reverse()
|
||||||
if sorted isnt true then _keys = _.keys(@props.kids).sort()
|
|
||||||
|
|
||||||
div {className:klass},
|
div {className:klass},
|
||||||
for item in _.values _keys
|
for item in _keys
|
||||||
elem = @props.kids[item]
|
elem = @props.kids[keyed[item]]
|
||||||
[(div {key:item}, reactify elem.body), (hr {},"")]
|
[(div {key:item}, reactify elem.body), (hr {},"")]
|
||||||
|
@ -676,13 +676,13 @@ module.exports = query({
|
|||||||
}, recl({
|
}, recl({
|
||||||
displayName: "Kids",
|
displayName: "Kids",
|
||||||
render: function() {
|
render: function() {
|
||||||
var _k, _keys, elem, item, k, klass, ref1, ref2, ref3, ref4, sorted, v;
|
var _k, _keys, d, elem, item, k, keyed, klass, ref1, ref2, ref3, ref4, sorted, str, v;
|
||||||
klass = "kids";
|
klass = "kids";
|
||||||
if (this.props.dataType) {
|
if (this.props.dataType) {
|
||||||
klass += " " + this.props.dataType;
|
klass += " " + this.props.dataType;
|
||||||
}
|
}
|
||||||
sorted = true;
|
sorted = true;
|
||||||
_keys = [];
|
keyed = {};
|
||||||
ref1 = this.props.kids;
|
ref1 = this.props.kids;
|
||||||
for (k in ref1) {
|
for (k in ref1) {
|
||||||
v = ref1[k];
|
v = ref1[k];
|
||||||
@ -690,32 +690,43 @@ module.exports = query({
|
|||||||
if (this.props.sortBy === 'date') {
|
if (this.props.sortBy === 'date') {
|
||||||
if (((ref2 = v.meta) != null ? ref2.date : void 0) == null) {
|
if (((ref2 = v.meta) != null ? ref2.date : void 0) == null) {
|
||||||
sorted = false;
|
sorted = false;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
_k = Number(v.meta.date.slice(1).replace(/\./g, ""));
|
d = v.meta.date.slice(1).split(".");
|
||||||
_keys[_k] = k;
|
if (d.length < 3) {
|
||||||
|
sorted = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
str = d[0] + "-" + d[1] + "-" + d[2];
|
||||||
|
if (d.length > 3) {
|
||||||
|
str += " " + d[3] + ":" + d[4] + ":" + d[5];
|
||||||
|
}
|
||||||
|
_k = Number(new Date(str));
|
||||||
|
keyed[_k] = k;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (((ref3 = v.meta) != null ? ref3.sort : void 0) == null) {
|
if (((ref3 = v.meta) != null ? ref3.sort : void 0) == null) {
|
||||||
sorted = false;
|
sorted = false;
|
||||||
}
|
}
|
||||||
_keys[Number((ref4 = v.meta) != null ? ref4.sort : void 0)] = k;
|
keyed[Number((ref4 = v.meta) != null ? ref4.sort : void 0)] = k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sorted !== true) {
|
||||||
|
_keys = _.keys(this.props.kids).sort();
|
||||||
|
} else {
|
||||||
|
_keys = _.keys(keyed).sort();
|
||||||
|
}
|
||||||
if (this.props.sortBy === 'date') {
|
if (this.props.sortBy === 'date') {
|
||||||
_keys.reverse();
|
_keys.reverse();
|
||||||
}
|
}
|
||||||
if (sorted !== true) {
|
|
||||||
_keys = _.keys(this.props.kids).sort();
|
|
||||||
}
|
|
||||||
return div({
|
return div({
|
||||||
className: klass
|
className: klass
|
||||||
}, (function() {
|
}, (function() {
|
||||||
var i, len, ref5, results;
|
var i, len, results;
|
||||||
ref5 = _.values(_keys);
|
|
||||||
results = [];
|
results = [];
|
||||||
for (i = 0, len = ref5.length; i < len; i++) {
|
for (i = 0, len = _keys.length; i < len; i++) {
|
||||||
item = ref5[i];
|
item = _keys[i];
|
||||||
elem = this.props.kids[item];
|
elem = this.props.kids[keyed[item]];
|
||||||
results.push([
|
results.push([
|
||||||
div({
|
div({
|
||||||
key: item
|
key: item
|
||||||
|
Loading…
Reference in New Issue
Block a user