mirror of
https://github.com/urbit/shrub.git
synced 2024-12-13 16:03:36 +03:00
Merge remote-tracking branch 'anton/talkfix' into pending
This commit is contained in:
commit
73371fd88a
@ -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))))
|
||||
::
|
||||
|
@ -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
|
||||
|= 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:%]
|
||||
=- a(r [%fat tank/- %exp p.r.a])
|
||||
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) ~)
|
||||
==
|
||||
|
@ -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] ~)
|
||||
==
|
||||
::
|
||||
|
@ -56,10 +56,23 @@ module.exports =
|
||||
else if window.urb.util.isURL(message)
|
||||
speech = url: message
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
for speech in speeches
|
||||
_message =
|
||||
ship:window.urb.ship
|
||||
thought:
|
||||
serial:serial
|
||||
serial:window.util.uuid32()
|
||||
audience:_audi
|
||||
statement:
|
||||
bouquet:[]
|
||||
|
@ -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
|
||||
|
@ -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})")
|
||||
]
|
||||
|
@ -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,10 +69,21 @@ module.exports = {
|
||||
url: message
|
||||
};
|
||||
}
|
||||
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)
|
||||
}
|
||||
};
|
||||
}));
|
||||
results = [];
|
||||
for (i = 0, len = speeches.length; i < len; i++) {
|
||||
speech = speeches[i];
|
||||
_message = {
|
||||
ship: window.urb.ship,
|
||||
thought: {
|
||||
serial: serial,
|
||||
serial: window.util.uuid32(),
|
||||
audience: _audi,
|
||||
statement: {
|
||||
bouquet: [],
|
||||
@ -85,7 +96,9 @@ module.exports = {
|
||||
type: "message-send",
|
||||
message: _message
|
||||
});
|
||||
return window.talk.MessagePersistence.sendMessage(_message.thought);
|
||||
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;
|
||||
}
|
||||
}
|
||||
StationActions.setAudience(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(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) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user