Merge remote-tracking branch 'anton/talkfix' into pending

This commit is contained in:
Philip C Monk 2015-10-28 15:26:42 -04:00
commit 73371fd88a
8 changed files with 311 additions and 201 deletions

View File

@ -307,6 +307,7 @@
[['[' ']'] u.active.she]
=+ cha=(~(get by nik) q.rew)
?^ cha ~[u.cha ' ']
:: ~& [rew nik nak]
=+ por=~(te-prom te man.she q.rew)
(weld `tape`[p.p.rew por] `tape`[q.p.rew ' ' ~])
::
@ -1872,12 +1873,12 @@
|- ^- tang
=< ?+(. . [@ *] [.]~) ^- ?(tank tang) :: wrap single tanks
?+ -.sep [>sep<]~
%exp leaf/"# {(trip p.sep)}"
%exp palm/[~ "#" " " ~]^~[leaf/(trip p.sep)]
%lin leaf/"{?:(p.sep "" "@ ")}{(trip q.sep)}"
%non ~
%app rose/[": " ~ ~]^~[leaf/"[{(trip p.sep)}]" leaf/(trip q.sep)]
%tax leaf/(rend-work-duty p.sep)
%url leaf/"/ {(earf p.sep)}"
%url palm/[~ "/" " " ~]^~[leaf/(earf p.sep)]
%mor ?~(p.sep ~ (weld $(p.sep t.p.sep) $(sep i.p.sep)))
%fat (welp (tr-rend-tors p.sep) $(sep q.sep))
==
@ -1924,6 +1925,8 @@
:+ '/' '_'
=+ hok=r.p.p.p.sep
~! hok
=- (swag [(sub (max 64 (lent -)) 64) 64] -)
^- tape
=< ?~(-.hok (reel p.hok .) +:(scow %if p.hok))
|=([a=span b=tape] ?~(b (trip a) (welp b '.' (trip a))))
::

View File

@ -27,6 +27,13 @@
^- (unit (list ,_[(wonk *fel) (need *wit)]))
(zl (turn (~(tap by a)) (head-rush fel)))
::
++ ke :: callbacks
|* [gar=* sef=_|.(fist)]
|= jon=json
^- (unit ,_gar)
=- ~! gar ~! (need -) -
((sef) jon)
::
++ as :: array as set
:: |*(a=fist (cu sa (ar a))) :: XX types
|* a=fist
@ -69,20 +76,31 @@
%+ sear (soft passport)
;~((glue fas) sym urs:ab) :: XX [a-z0-9_]{1,15}
::
++ speeech ?(speech [%eval p=@t] [%mor p=(list speeech)])
++ eval
|= a=(trel ,@da bouquet ?(speech [%eval p=@t])) ^- statement
?. ?=(%eval -.r.a) a
=+ pax=[&1:% &2:% (scot %da p.a) |3:%]
=- a(r [%fat tank/- %exp p.r.a])
p:(mule |.([(sell (slap !>(..zuse) (rain pax p.r.a)))]~))
|= a=(trel ,@da bouquet speeech) ^- statement
%= a r ^- speech
|-
?: ?=(%mor -.r.a)
[%mor (turn p.r.a |=(b=speeech ^$(r.a b)))]
?. ?=(%eval -.r.a) r.a
=- [%fat tank/- %exp p.r.a]
=+ pax=[&1:% &2:% (scot %da p.a) |3:%]
p:(mule |.([(sell (slap !>(..zuse) (rain pax p.r.a)))]~))
==
::
++ stam
^- $+(json (unit statement))
%+ cu eval
=- (ot date/di bouquet/(as (ar so)) speech/(of -) ~)
(ot date/di bouquet/(as (ar so)) speech/spec ~)
::
++ spec
%+ ke *speeech |.
%- of
:~ lin/(ot say/bo txt/so ~)
url/(su aurf:urlp)
eval/so
mor/(ar spec)
:: exp/(cu |=(a=cord [a ~]) so)
:: inv/(ot ship/(su fed:ag) party/(su urs:ab) ~)
==

View File

@ -95,6 +95,7 @@
%tax (joba txt/(jape (rend-work-duty p.a)))
%app (jobe txt/[%s q.a] src/[%s p.a] ~)
%fat (jobe tor/(tors p.a) taf/$(a q.a) ~)
%mor a/(turn p.a spec)
:: %inv (jobe ship/(jope p.a) party/[%s q.a] ~)
==
::

View File

@ -56,17 +56,30 @@ module.exports =
else if window.urb.util.isURL(message)
speech = url: message
_message =
ship:window.urb.ship
thought:
serial:serial
audience:_audi
statement:
bouquet:[]
speech:speech
date: Date.now()
speeches =
if speech.lin?.txt.length < 64
[speech]
else
{say,txt} = speech.lin
txt.match(/(.{0,64} |.{64}|.+$)/g).map (s)->
lin: {say, txt:
if s.slice -1 isnt " "
s
else s.slice 0,-1
}
MessageDispatcher.handleViewAction
type:"message-send"
message:_message
window.talk.MessagePersistence.sendMessage _message.thought
for speech in speeches
_message =
ship:window.urb.ship
thought:
serial:window.util.uuid32()
audience:_audi
statement:
bouquet:[]
speech:speech
date: Date.now()
MessageDispatcher.handleViewAction
type:"message-send"
message:_message
window.talk.MessagePersistence.sendMessage _message.thought

View File

@ -29,6 +29,15 @@ Message = recl
return if user.toLowerCase() is 'system'
@props._handlePm user
renderSpeech: (speech)-> switch
when (con = speech.lin) or (con = speech.app) or
(con = speech.exp) or (con = speech.tax)
con.txt
when (con = speech.url)
(a {href:con.txt,target:"_blank"}, con.txt)
when (con = speech.mor) then con.map @renderSpeech
else "Unknown speech type:" + (" %"+x for x of speech).join ''
render: ->
# pendingClass = if @props.pending isnt "received" then "pending" else ""
delivery = _.uniq _.pluck @props.thought.audience, "delivery"
@ -51,13 +60,7 @@ Message = recl
type = ['private','public']
type = type[Number(aude.indexOf(window.util.mainStationPath(window.urb.user)) is -1)]
mess = switch
when (con = speech.lin) or (con = speech.app) or
(con = speech.exp) or (con = speech.tax)
con.txt
when (con = speech.url)
(a {href:con.txt,target:"_blank"}, con.txt)
else "Unknown speech type:" + (" %"+x for x of speech).join ''
mess = @renderSpeech speech
klass += switch
when speech.app? then " say"
@ -77,6 +80,7 @@ Message = recl
]
module.exports = recl
displayName: "Messages"
pageSize: 50
paddingTop: 100
@ -122,7 +126,8 @@ module.exports = recl
sortedMessages: (messages) ->
_.sortBy messages, (_message) ->
_message.pending = _message.thought.audience[station]
_message.thought.statement.date
_message.key
#_message.thought.statement.date
componentDidMount: ->
MessageStore.addChangeListener @_onChangeStore

View File

@ -7,7 +7,70 @@ StationActions = require '../actions/StationActions.coffee'
StationStore = require '../stores/StationStore.coffee'
Member = require './MemberComponent.coffee'
SHIPSHAPE = ///
^~?( #preamble
[a-z]{3} # galaxy
| [a-z]{6}(-[a-z]{6}){0,3} # star - moon
| [a-z]{6}(-[a-z]{6}){3} # comet
(--[a-z]{6}(-[a-z]{6}){3})+ #
)$ #postamble
///
PO = '''
dozmarbinwansamlitsighidfidlissogdirwacsabwissib
rigsoldopmodfoglidhopdardorlorhodfolrintogsilmir
holpaslacrovlivdalsatlibtabhanticpidtorbolfosdot
losdilforpilramtirwintadbicdifrocwidbisdasmidlop
rilnardapmolsanlocnovsitnidtipsicropwitnatpanmin
ritpodmottamtolsavposnapnopsomfinfonbanporworsip
ronnorbotwicsocwatdolmagpicdavbidbaltimtasmallig
sivtagpadsaldivdactansidfabtarmonranniswolmispal
lasdismaprabtobrollatlonnodnavfignomnibpagsopral
bilhaddocridmocpacravripfaltodtiltinhapmicfanpat
taclabmogsimsonpinlomrictapfirhasbosbatpochactid
havsaplindibhosdabbitbarracparloddosbortochilmac
tomdigfilfasmithobharmighinradmashalraglagfadtop
mophabnilnosmilfopfamdatnoldinhatnacrisfotribhoc
nimlarfitwalrapsarnalmoslandondanladdovrivbacpol
laptalpitnambonrostonfodponsovnocsorlavmatmipfap
zodnecbudwessevpersutletfulpensytdurwepserwylsun
rypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnex
lunmeplutseppesdelsulpedtemledtulmetwenbynhexfeb
pyldulhetmevruttylwydtepbesdexsefwycburderneppur
rysrebdennutsubpetrulsynregtydsupsemwynrecmegnet
secmulnymtevwebsummutnyxrextebfushepbenmuswyxsym
selrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpel
syptermebsetdutdegtexsurfeltudnuxruxrenwytnubmed
lytdusnebrumtynseglyxpunresredfunrevrefmectedrus
bexlebduxrynnumpyxrygryxfeptyrtustyclegnemfermer
tenlusnussyltecmexpubrymtucfyllepdebbermughuttun
bylsudpemdevlurdefbusbeprunmelpexdytbyttyplevmyl
wedducfurfexnulluclennerlexrupnedlecrydlydfenwel
nydhusrelrudneshesfetdesretdunlernyrsebhulryllud
remlysfynwerrycsugnysnyllyndyndemluxfedsedbecmun
lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes
'''
Audience = recl
displayName: "Audience"
onKeyDown: (e) ->
if e.keyCode is 13
e.preventDefault()
setTimeout () ->
$('#writing').focus()
,0
return false
render: ->
div {
id:"audi"
className:"audi valid-#{@props.valid}"
contentEditable:true
@onKeyDown
onBlur:@props.onBlur
}, @props.audi.join(" ")
module.exports = recl
displayName: "Writing"
set: ->
if window.localStorage and @$writing then window.localStorage.setItem 'writing', @$writing.text()
@ -26,20 +89,21 @@ module.exports = recl
s.ludi = _.without s.ludi, window.util.mainStationPath window.urb.user
s
getInitialState: -> @stateFromStore()
getInitialState: -> _.extend @stateFromStore(), length:0, lengthy: false
typing: (state) ->
if @state.typing[@state.station] isnt state
StationActions.setTyping @state.station,state
_blur: ->
onBlur: ->
@$writing.text @$writing.text()
MessageActions.setTyping false
@typing false
_focus: ->
onFocus: ->
MessageActions.setTyping true
@typing true
@cursorAtEnd
addCC: (audi) ->
listening = @state.config[window.util.mainStation(window.urb.user)].sources
@ -61,23 +125,16 @@ module.exports = recl
else
audi = @state.audi
audi = @addCC audi
MessageActions.sendMessage @$writing.text().trim(),audi
@$length.text "0/62"
txt = @$writing.text().trim().replace(/\xa0/g,' ')
MessageActions.sendMessage txt,audi
@$writing.text('')
@setState length:0
@set()
@typing false
_audiKeyDown: (e) ->
if e.keyCode is 13
e.preventDefault()
setTimeout () ->
$('#writing').focus()
,0
return false
_writingKeyUp: (e) ->
onKeyUp: (e) ->
if not window.urb.util.isURL @$writing.text()
@$length.toggleClass('valid-false',(@$writing.text().length > 62))
@setState lengthy: (@$writing.text().length > 62)
# r = window.getSelection().getRangeAt(0).cloneRange()
# @$writing.text @$writing.text()
# setTimeout =>
@ -87,18 +144,17 @@ module.exports = recl
# console.log r
# ,0
_writingKeyDown: (e) ->
onKeyDown: (e) ->
if e.keyCode is 13
txt = @$writing.text()
e.preventDefault()
if ( (txt.length > 0 and txt.length < 63) or
window.urb.util.isURL @$writing.text() )
if txt.length > 0
@sendMessage()
return false
@_input()
@onInput()
@set()
_input: (e) ->
onInput: (e) ->
text = @$writing.text()
length = text.length
# geturl = new RegExp [
@ -113,11 +169,10 @@ module.exports = recl
# for url in urls
# length -= url.length
# length += 10
@$length.text "#{length}/62"
_setFocus: -> @$writing.focus()
@setState {length}
_validateAudiPart: (a) ->
a = a.trim()
# if a[0] isnt "~"
# return false
if a.indexOf("/") isnt -1
@ -127,9 +182,9 @@ module.exports = recl
ship = _a[0]
else
ship = a
if ship.length < 3
return false
return true
return (SHIPSHAPE.test ship) and
_.all (ship.match /[a-z]{3}/g), (a)-> -1 isnt PO.indexOf a
_validateAudi: ->
v = $('#audi').text()
@ -138,23 +193,17 @@ module.exports = recl
return true
if v.length < 5 # zod/a is shortest
return false
v = v.split " "
for a in v
a = a.trim()
valid = @_validateAudiPart(a)
valid
_.all (v.split /\ +/), @_validateAudiPart
_setAudi: ->
valid = @_validateAudi()
StationActions.setValidAudience valid
if valid is true
v = $('#audi').text()
if v.length is 0 then v = window.util.mainStationPath window.urb.user
v = v.split " "
for k,_v of v
if _v[0] isnt "~" then v[k] = "~#{_v}"
StationActions.setAudience v
v
stan = $('#audi').text() || window.util.mainStationPath window.urb.user
stan = (stan.split /\ +/).map (v)->
if v[0] is "~" then v else "~"+v
StationActions.setAudience stan
stan
else
false
@ -178,12 +227,11 @@ module.exports = recl
StationStore.addChangeListener @_onChangeStore
MessageStore.addChangeListener @_onChangeStore
@$el = $ @getDOMNode()
@$length = $('#length')
@$writing = $('#writing')
@$writing.focus()
if @get()
@$writing.text @get()
@_input()
@onInput()
@interval = setInterval =>
@$el.find('.time').text @getTime()
, 1000
@ -210,25 +258,14 @@ module.exports = recl
div {className:k}, [
(div {className:"attr"}, [
(React.createElement Member, iden)
(div {
id:"audi"
className:"audi valid-#{@state.valid}"
contentEditable:true
onKeyDown: @_audiKeyDown
onBlur:@_setAudi
}, audi.join(" "))
(React.createElement Audience, {audi,valid:@state.valid, onBlur:@_setAudi})
(div {className:"time"}, @getTime())
])
(div {
id:"writing"
contentEditable:true
onFocus: @_focus
onBlur: @_blur
onInput: @_input
onPaste: @_input
onKeyDown: @_writingKeyDown
onKeyUp: @_writingKeyUp
onFocus: @cursorAtEnd
onPaste: @onInput
@onInput, @onFocus, @onBlur, @onKeyDown, @onKeyUp
}, "")
div {id:"length"}, "0/62"
(div {id:"length"}, "#{@state.length}/64 (#{Math.ceil @state.length / 64})")
]

View File

@ -37,7 +37,7 @@ module.exports = {
return window.talk.MessagePersistence.get(station, start, end);
},
sendMessage: function(message, audience) {
var _audi, _message, k, serial, speech, v;
var _audi, _message, i, k, len, ref, ref1, results, say, serial, speech, speeches, txt, v;
serial = window.util.uuid32();
audience = _.uniq(audience);
_audi = {};
@ -69,23 +69,36 @@ module.exports = {
url: message
};
}
_message = {
ship: window.urb.ship,
thought: {
serial: serial,
audience: _audi,
statement: {
bouquet: [],
speech: speech,
date: Date.now()
speeches = ((ref = speech.lin) != null ? ref.txt.length : void 0) < 64 ? [speech] : ((ref1 = speech.lin, say = ref1.say, txt = ref1.txt, ref1), txt.match(/(.{0,64} |.{64}|.+$)/g).map(function(s) {
return {
lin: {
say: say,
txt: s.slice(-1 !== " ") ? s : s.slice(0, -1)
}
}
};
MessageDispatcher.handleViewAction({
type: "message-send",
message: _message
});
return window.talk.MessagePersistence.sendMessage(_message.thought);
};
}));
results = [];
for (i = 0, len = speeches.length; i < len; i++) {
speech = speeches[i];
_message = {
ship: window.urb.ship,
thought: {
serial: window.util.uuid32(),
audience: _audi,
statement: {
bouquet: [],
speech: speech,
date: Date.now()
}
}
};
MessageDispatcher.handleViewAction({
type: "message-send",
message: _message
});
results.push(window.talk.MessagePersistence.sendMessage(_message.thought));
}
return results;
}
};
@ -261,8 +274,31 @@ Message = recl({
}
return this.props._handlePm(user);
},
renderSpeech: function(speech) {
var con, x;
switch (false) {
case !((con = speech.lin) || (con = speech.app) || (con = speech.exp) || (con = speech.tax)):
return con.txt;
case !(con = speech.url):
return a({
href: con.txt,
target: "_blank"
}, con.txt);
case !(con = speech.mor):
return con.map(this.renderSpeech);
default:
return "Unknown speech type:" + ((function() {
var results;
results = [];
for (x in speech) {
results.push(" %" + x);
}
return results;
})()).join('');
}
},
render: function() {
var attachments, aude, audi, con, delivery, klass, mess, name, ref1, speech, type, x;
var attachments, aude, audi, delivery, klass, mess, name, ref1, speech, type;
delivery = _.uniq(_.pluck(this.props.thought.audience, "delivery"));
klass = delivery.indexOf("received") !== -1 ? " received" : " pending";
speech = this.props.thought.statement.speech;
@ -295,26 +331,7 @@ Message = recl({
});
type = ['private', 'public'];
type = type[Number(aude.indexOf(window.util.mainStationPath(window.urb.user)) === -1)];
mess = (function() {
switch (false) {
case !((con = speech.lin) || (con = speech.app) || (con = speech.exp) || (con = speech.tax)):
return con.txt;
case !(con = speech.url):
return a({
href: con.txt,
target: "_blank"
}, con.txt);
default:
return "Unknown speech type:" + ((function() {
var results;
results = [];
for (x in speech) {
results.push(" %" + x);
}
return results;
})()).join('');
}
})();
mess = this.renderSpeech(speech);
klass += (function() {
switch (false) {
case speech.app == null:
@ -353,6 +370,7 @@ Message = recl({
});
module.exports = recl({
displayName: "Messages",
pageSize: 50,
paddingTop: 100,
stateFromStore: function() {
@ -402,7 +420,7 @@ module.exports = recl({
sortedMessages: function(messages) {
return _.sortBy(messages, function(_message) {
_message.pending = _message.thought.audience[station];
return _message.thought.statement.date;
return _message.key;
});
},
componentDidMount: function() {
@ -696,7 +714,7 @@ module.exports = recl({
},{"../actions/StationActions.coffee":2,"../stores/StationStore.coffee":20,"./MemberComponent.coffee":3}],6:[function(require,module,exports){
var Member, MessageActions, MessageStore, StationActions, StationStore, br, div, input, recl, ref, textarea;
var Audience, Member, MessageActions, MessageStore, PO, SHIPSHAPE, StationActions, StationStore, br, div, input, recl, ref, textarea;
recl = React.createClass;
@ -712,7 +730,34 @@ StationStore = require('../stores/StationStore.coffee');
Member = require('./MemberComponent.coffee');
SHIPSHAPE = /^~?([a-z]{3}|[a-z]{6}(-[a-z]{6}){0,3}|[a-z]{6}(-[a-z]{6}){3}(--[a-z]{6}(-[a-z]{6}){3})+)$/;
PO = 'dozmarbinwansamlitsighidfidlissogdirwacsabwissib\nrigsoldopmodfoglidhopdardorlorhodfolrintogsilmir\nholpaslacrovlivdalsatlibtabhanticpidtorbolfosdot\nlosdilforpilramtirwintadbicdifrocwidbisdasmidlop\nrilnardapmolsanlocnovsitnidtipsicropwitnatpanmin\nritpodmottamtolsavposnapnopsomfinfonbanporworsip\nronnorbotwicsocwatdolmagpicdavbidbaltimtasmallig\nsivtagpadsaldivdactansidfabtarmonranniswolmispal\nlasdismaprabtobrollatlonnodnavfignomnibpagsopral\nbilhaddocridmocpacravripfaltodtiltinhapmicfanpat\ntaclabmogsimsonpinlomrictapfirhasbosbatpochactid\nhavsaplindibhosdabbitbarracparloddosbortochilmac\ntomdigfilfasmithobharmighinradmashalraglagfadtop\nmophabnilnosmilfopfamdatnoldinhatnacrisfotribhoc\nnimlarfitwalrapsarnalmoslandondanladdovrivbacpol\nlaptalpitnambonrostonfodponsovnocsorlavmatmipfap\n\nzodnecbudwessevpersutletfulpensytdurwepserwylsun\nrypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnex\nlunmeplutseppesdelsulpedtemledtulmetwenbynhexfeb\npyldulhetmevruttylwydtepbesdexsefwycburderneppur\nrysrebdennutsubpetrulsynregtydsupsemwynrecmegnet\nsecmulnymtevwebsummutnyxrextebfushepbenmuswyxsym\nselrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpel\nsyptermebsetdutdegtexsurfeltudnuxruxrenwytnubmed\nlytdusnebrumtynseglyxpunresredfunrevrefmectedrus\nbexlebduxrynnumpyxrygryxfeptyrtustyclegnemfermer\ntenlusnussyltecmexpubrymtucfyllepdebbermughuttun\nbylsudpemdevlurdefbusbeprunmelpexdytbyttyplevmyl\nwedducfurfexnulluclennerlexrupnedlecrydlydfenwel\nnydhusrelrudneshesfetdesretdunlernyrsebhulryllud\nremlysfynwerrycsugnysnyllyndyndemluxfedsedbecmun\nlyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes';
Audience = recl({
displayName: "Audience",
onKeyDown: function(e) {
if (e.keyCode === 13) {
e.preventDefault();
setTimeout(function() {
return $('#writing').focus();
}, 0);
return false;
}
},
render: function() {
return div({
id: "audi",
className: "audi valid-" + this.props.valid,
contentEditable: true,
onKeyDown: this.onKeyDown,
onBlur: this.props.onBlur
}, this.props.audi.join(" "));
}
});
module.exports = recl({
displayName: "Writing",
set: function() {
if (window.localStorage && this.$writing) {
return window.localStorage.setItem('writing', this.$writing.text());
@ -738,21 +783,25 @@ module.exports = recl({
return s;
},
getInitialState: function() {
return this.stateFromStore();
return _.extend(this.stateFromStore(), {
length: 0,
lengthy: false
});
},
typing: function(state) {
if (this.state.typing[this.state.station] !== state) {
return StationActions.setTyping(this.state.station, state);
}
},
_blur: function() {
onBlur: function() {
this.$writing.text(this.$writing.text());
MessageActions.setTyping(false);
return this.typing(false);
},
_focus: function() {
onFocus: function() {
MessageActions.setTyping(true);
return this.typing(true);
this.typing(true);
return this.cursorAtEnd;
},
addCC: function(audi) {
var cc, i, len, listening, s;
@ -773,7 +822,7 @@ module.exports = recl({
return audi;
},
sendMessage: function() {
var audi;
var audi, txt;
if (this._validateAudi() === false) {
$('#audi').focus();
return;
@ -784,50 +833,46 @@ module.exports = recl({
audi = this.state.audi;
}
audi = this.addCC(audi);
MessageActions.sendMessage(this.$writing.text().trim(), audi);
this.$length.text("0/62");
txt = this.$writing.text().trim().replace(/\xa0/g, ' ');
MessageActions.sendMessage(txt, audi);
this.$writing.text('');
this.setState({
length: 0
});
this.set();
return this.typing(false);
},
_audiKeyDown: function(e) {
if (e.keyCode === 13) {
e.preventDefault();
setTimeout(function() {
return $('#writing').focus();
}, 0);
return false;
}
},
_writingKeyUp: function(e) {
onKeyUp: function(e) {
if (!window.urb.util.isURL(this.$writing.text())) {
return this.$length.toggleClass('valid-false', this.$writing.text().length > 62);
return this.setState({
lengthy: this.$writing.text().length > 62
});
}
},
_writingKeyDown: function(e) {
onKeyDown: function(e) {
var txt;
if (e.keyCode === 13) {
txt = this.$writing.text();
e.preventDefault();
if ((txt.length > 0 && txt.length < 63) || window.urb.util.isURL(this.$writing.text())) {
if (txt.length > 0) {
this.sendMessage();
}
return false;
}
this._input();
this.onInput();
return this.set();
},
_input: function(e) {
onInput: function(e) {
var length, text;
text = this.$writing.text();
length = text.length;
return this.$length.text(length + "/62");
},
_setFocus: function() {
return this.$writing.focus();
return this.setState({
length: length
});
},
_validateAudiPart: function(a) {
var _a, ship;
a = a.trim();
if (a.indexOf("/") !== -1) {
_a = a.split("/");
if (_a[1].length === 0) {
@ -837,13 +882,12 @@ module.exports = recl({
} else {
ship = a;
}
if (ship.length < 3) {
return false;
}
return true;
return (SHIPSHAPE.test(ship)) && _.all(ship.match(/[a-z]{3}/g), function(a) {
return -1 !== PO.indexOf(a);
});
},
_validateAudi: function() {
var a, i, len, v, valid;
var v;
v = $('#audi').text();
v = v.trim();
if (v.length === 0) {
@ -852,32 +896,23 @@ module.exports = recl({
if (v.length < 5) {
return false;
}
v = v.split(" ");
for (i = 0, len = v.length; i < len; i++) {
a = v[i];
a = a.trim();
valid = this._validateAudiPart(a);
}
return valid;
return _.all(v.split(/\ +/), this._validateAudiPart);
},
_setAudi: function() {
var _v, k, v, valid;
var stan, valid;
valid = this._validateAudi();
StationActions.setValidAudience(valid);
if (valid === true) {
v = $('#audi').text();
if (v.length === 0) {
v = window.util.mainStationPath(window.urb.user);
}
v = v.split(" ");
for (k in v) {
_v = v[k];
if (_v[0] !== "~") {
v[k] = "~" + _v;
stan = $('#audi').text() || window.util.mainStationPath(window.urb.user);
stan = (stan.split(/\ +/)).map(function(v) {
if (v[0] === "~") {
return v;
} else {
return "~" + v;
}
}
StationActions.setAudience(v);
return v;
});
StationActions.setAudience(stan);
return stan;
} else {
return false;
}
@ -905,12 +940,11 @@ module.exports = recl({
StationStore.addChangeListener(this._onChangeStore);
MessageStore.addChangeListener(this._onChangeStore);
this.$el = $(this.getDOMNode());
this.$length = $('#length');
this.$writing = $('#writing');
this.$writing.focus();
if (this.get()) {
this.$writing.text(this.get());
this._input();
this.onInput();
}
return this.interval = setInterval((function(_this) {
return function() {
@ -944,28 +978,25 @@ module.exports = recl({
div({
className: "attr"
}, [
React.createElement(Member, iden), div({
id: "audi",
className: "audi valid-" + this.state.valid,
contentEditable: true,
onKeyDown: this._audiKeyDown,
React.createElement(Member, iden), React.createElement(Audience, {
audi: audi,
valid: this.state.valid,
onBlur: this._setAudi
}, audi.join(" ")), div({
}), div({
className: "time"
}, this.getTime())
]), div({
id: "writing",
contentEditable: true,
onFocus: this._focus,
onBlur: this._blur,
onInput: this._input,
onPaste: this._input,
onKeyDown: this._writingKeyDown,
onKeyUp: this._writingKeyUp,
onFocus: this.cursorAtEnd
onPaste: this.onInput,
onInput: this.onInput,
onFocus: this.onFocus,
onBlur: this.onBlur,
onKeyDown: this.onKeyDown,
onKeyUp: this.onKeyUp
}, ""), div({
id: "length"
}, "0/62")
}, this.state.length + "/64 (" + (Math.ceil(this.state.length / 64)) + ")")
]);
}
});
@ -5898,11 +5929,12 @@ MessageStore = _.merge(new EventEmitter, {
return _messages[message.thought.serial] = message;
},
loadMessages: function(messages, last, get) {
var k, serial, v;
for (k in messages) {
v = messages[k];
var i, key, len, serial, v;
key = last;
for (i = 0, len = messages.length; i < len; i++) {
v = messages[i];
serial = v.thought.serial;
v.key = serial;
v.key = key++;
_messages[serial] = v;
}
if (last < _last || _last === null || get === true) {

View File

@ -52,9 +52,10 @@ MessageStore = _.merge new EventEmitter,{
_messages[message.thought.serial] = message
loadMessages: (messages,last,get) ->
for k,v of messages
key = last
for v in messages
serial = v.thought.serial
v.key = serial
v.key = key++
# always overwrite with new
_messages[serial] = v
_last = last if last < _last or _last is null or get is true