mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-13 08:38:43 +03:00
moved talk, example module
This commit is contained in:
parent
e2924c2396
commit
e5b8d19274
@ -18,8 +18,8 @@
|
||||
;head
|
||||
;title: Bootstrap Test - ~2016.1
|
||||
;meta(name "viewport", content "width=device-width, initial-scale=1");
|
||||
;link(rel "stylesheet", href "/home/lib/fonts.css");
|
||||
;link(rel "stylesheet", href "/home/lib/bootstrap.css");
|
||||
;link(rel "stylesheet", href "/home/lib/css/fonts.css");
|
||||
;link(rel "stylesheet", href "/home/lib/css/bootstrap.css");
|
||||
;script(src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js");
|
||||
==
|
||||
;body
|
||||
|
6
pub/module/main.js
Normal file
6
pub/module/main.js
Normal file
@ -0,0 +1,6 @@
|
||||
main = {
|
||||
mount: function() { console.log('mount.') },
|
||||
unmount: function() { console.log('unmount.') }
|
||||
}
|
||||
|
||||
window.tree.modules.talk = main
|
1
pub/module/mod.md
Normal file
1
pub/module/mod.md
Normal file
@ -0,0 +1 @@
|
||||
<module path="/home/pub/module/main.js" name="talk" />
|
@ -31,10 +31,10 @@
|
||||
"lodash.js/2.4.1/lodash.min.js"
|
||||
"react/0.13.1/react.js"
|
||||
==
|
||||
;script(type "text/javascript", src "{?:(aut "/~~" "")}/~/at/home/lib/urb.js");
|
||||
;script(type "text/javascript", src "{?:(aut "/~~" "")}/~/at/home/lib/js/urb.js");
|
||||
;meta(name "viewport", content "width=device-width, height=device-height, ".
|
||||
"initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0");
|
||||
;link(type "text/css", rel "stylesheet", href "/home/pub/talk/src/css/main.css");
|
||||
;link(type "text/css", rel "stylesheet", href "/home/pub/talk/main.css");
|
||||
;title: Talk
|
||||
==
|
||||
;body
|
||||
@ -45,6 +45,6 @@
|
||||
;div#scrolling: BOTTOM
|
||||
==
|
||||
;script: window.talk = {(pojo (joba 'mainStation' s/man))}
|
||||
;script(type "text/javascript", src "/home/pub/talk/src/js/main.js");
|
||||
;script(type "text/javascript", src "/home/pub/talk/main.js");
|
||||
==
|
||||
==
|
||||
|
@ -1,84 +0,0 @@
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("//storage.googleapis.com/urbit-extra/bau.woff");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("//storage.googleapis.com/urbit-extra/bau-italic.woff");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("//storage.googleapis.com/urbit-extra/bau-medium.woff");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("//storage.googleapis.com/urbit-extra/bau-mediumitalic.woff");
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("//storage.googleapis.com/urbit-extra/bau-bold.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("//storage.googleapis.com/urbit-extra/bau-bolditalic.woff");
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("//storage.googleapis.com/urbit-extra/bau-super.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "bau";
|
||||
src: url("//storage.googleapis.com/urbit-extra/bau-superitalic.woff");
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("//storage.googleapis.com/urbit-extra/scp-extralight.woff");
|
||||
font-weight: 200;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("//storage.googleapis.com/urbit-extra/scp-light.woff");
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("//storage.googleapis.com/urbit-extra/scp-regular.woff");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("//storage.googleapis.com/urbit-extra/scp-medium.woff");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("//storage.googleapis.com/urbit-extra/scp-bold.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("//storage.googleapis.com/urbit-extra/scp-black.woff");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
@ -1,565 +0,0 @@
|
||||
//
|
||||
// fonts first
|
||||
//
|
||||
|
||||
@import 'fonts'
|
||||
|
||||
html
|
||||
body
|
||||
height 100%
|
||||
font-family "bau"
|
||||
|
||||
.type
|
||||
font-family "scp"
|
||||
|
||||
input
|
||||
font-size 1rem
|
||||
-webkit-appearance none
|
||||
border-radius 0
|
||||
font-family "bau"
|
||||
|
||||
#length
|
||||
.time
|
||||
letter-spacing 0
|
||||
|
||||
.time
|
||||
font-weight 200
|
||||
letter-spacing .1rem
|
||||
color #555
|
||||
|
||||
#length
|
||||
.audi
|
||||
.time
|
||||
.station
|
||||
#audience .iden
|
||||
font-size .8rem
|
||||
line-height 1rem
|
||||
|
||||
#length
|
||||
letter-spacing .1rem
|
||||
|
||||
#writing-container:focus #length
|
||||
display inline
|
||||
|
||||
// input.join
|
||||
// .iden
|
||||
// .audi
|
||||
// #station
|
||||
// font-size .7rem
|
||||
|
||||
.ship
|
||||
text-transform uppercase
|
||||
letter-spacing .05rem
|
||||
|
||||
html
|
||||
body
|
||||
font-size 18px
|
||||
|
||||
//
|
||||
// containers
|
||||
//
|
||||
|
||||
body
|
||||
background-color #fefefe
|
||||
padding 0
|
||||
margin 0
|
||||
|
||||
.hidden
|
||||
display none
|
||||
|
||||
#c
|
||||
position absolute
|
||||
top 0rem
|
||||
left 50%
|
||||
width 58rem
|
||||
margin-left -29rem
|
||||
margin-bottom 6rem
|
||||
|
||||
#station-container
|
||||
position fixed
|
||||
width 58rem
|
||||
max-height 4rem
|
||||
background-color rgba(255,255,255,.95)
|
||||
color #555
|
||||
overflow hidden
|
||||
z-index 10
|
||||
border-bottom 1px solid #ddd
|
||||
-webkit-transition max-height .2s
|
||||
|
||||
#station #station-container
|
||||
padding-top 1rem
|
||||
min-width 30rem
|
||||
text-align right
|
||||
|
||||
#writing-container
|
||||
margin-top 2rem
|
||||
margin-bottom 1rem
|
||||
|
||||
#messages-container
|
||||
vertical-align top
|
||||
margin-top 5rem
|
||||
|
||||
//
|
||||
// components
|
||||
//
|
||||
|
||||
.caret
|
||||
.circle
|
||||
display inline-block
|
||||
|
||||
.caret
|
||||
width 0
|
||||
height 0
|
||||
border-top 6px solid transparent
|
||||
border-right 6px solid transparent
|
||||
border-bottom 6px solid transparent
|
||||
border-left 6px solid #000
|
||||
margin-top 2px
|
||||
|
||||
.circle
|
||||
width 6px
|
||||
height 6px
|
||||
border 3px solid black
|
||||
border-radius 6px
|
||||
margin-top 2px
|
||||
|
||||
//
|
||||
// station
|
||||
//
|
||||
|
||||
#station-container #where .caret
|
||||
-webkit-transform rotate(0deg)
|
||||
-webkit-transform-origin 0 50%
|
||||
-webkit-transition -webkit-transform .2s
|
||||
|
||||
#station-container #where .caret
|
||||
margin-top 9px
|
||||
border-top 9px solid transparent
|
||||
border-right 9px solid transparent
|
||||
border-bottom 9px solid transparent
|
||||
border-left 9px solid white
|
||||
-webkit-transition border-left-color .2s
|
||||
|
||||
#head
|
||||
width 100%
|
||||
height 4rem
|
||||
color #333
|
||||
border-bottom 1px solid #ddd
|
||||
|
||||
#station-container h1
|
||||
display none
|
||||
color #555
|
||||
font-weight 400
|
||||
font-size 1rem
|
||||
letter-spacing .06rem
|
||||
display inline-block
|
||||
line-height 1.2rem
|
||||
|
||||
#station-container h1:after
|
||||
content "—"
|
||||
margin-left .6rem
|
||||
|
||||
#station-container .audi
|
||||
#station-container .iden > div
|
||||
background-color transparent
|
||||
|
||||
#who
|
||||
width 16rem
|
||||
|
||||
#stations
|
||||
width 15rem
|
||||
padding-bottom 1rem
|
||||
border-left 16rem solid transparent
|
||||
|
||||
#station-container #head .ship
|
||||
font-size .9rem
|
||||
font-weight 400
|
||||
|
||||
#station-container:hover #where
|
||||
color white
|
||||
-webkit-transition color .2s
|
||||
|
||||
#station-container:hover #where
|
||||
color rgb(240,73,65)
|
||||
-webkit-transition color .2s
|
||||
|
||||
#station-container:hover #where .caret
|
||||
border-left-color rgb(240,73,65)
|
||||
-webkit-transition border-left-color .2s
|
||||
|
||||
#stations
|
||||
#audience
|
||||
#head > div
|
||||
#where > div
|
||||
display inline-block
|
||||
vertical-align top
|
||||
|
||||
#where > div
|
||||
margin-right 1rem
|
||||
text-transform capitalize
|
||||
letter-spacing .05rem
|
||||
font-size 1.6rem
|
||||
|
||||
#where .slat
|
||||
font-weight 500
|
||||
|
||||
#where .slat:after
|
||||
margin-left 1rem
|
||||
content "—"
|
||||
|
||||
#head > div
|
||||
height 2rem
|
||||
line-height 2rem
|
||||
margin-top 1rem
|
||||
|
||||
#where .caret
|
||||
border-left-color white
|
||||
|
||||
#who > div
|
||||
vertical-align middle
|
||||
|
||||
#members
|
||||
margin-bottom 1rem
|
||||
|
||||
#members > div
|
||||
display block
|
||||
max-width 24rem
|
||||
overflow hidden
|
||||
white-space nowrap
|
||||
|
||||
#members > div:hover
|
||||
white-space normal
|
||||
|
||||
#members > div div
|
||||
display inline-block
|
||||
vertical-align bottom
|
||||
|
||||
#members .audi
|
||||
margin-right .3rem
|
||||
margin-top 0
|
||||
|
||||
#members .iden
|
||||
min-width 10rem
|
||||
|
||||
.station div
|
||||
display inline-block
|
||||
|
||||
.station .path
|
||||
text-transform uppercase
|
||||
|
||||
.station .remove
|
||||
opacity 0
|
||||
cursor pointer
|
||||
width .6rem
|
||||
margin-left .6rem
|
||||
line-height 1rem
|
||||
font-size 1.2rem
|
||||
font-weight 500
|
||||
color #ff0000
|
||||
vertical-align top
|
||||
|
||||
.station:hover .remove
|
||||
opacity 1
|
||||
|
||||
// add source
|
||||
.sour-ctrl input
|
||||
color #555
|
||||
background-color transparent
|
||||
border none
|
||||
font-size .8rem
|
||||
line-height 1.2rem
|
||||
letter-spacing .05rem
|
||||
margin-top .6rem
|
||||
font-weight 300
|
||||
text-align left
|
||||
outline none
|
||||
cursor pointer
|
||||
text-transform uppercase
|
||||
border-bottom 2px solid transparent
|
||||
|
||||
.sour-ctrl input:focus
|
||||
border-bottom 2px solid #fff
|
||||
|
||||
.sour-ctrl input::-webkit-input-placeholder
|
||||
font-weight 400
|
||||
font-size 1.2rem
|
||||
margin-left .6rem
|
||||
color #555
|
||||
|
||||
.sour-ctrl input:focus::-webkit-input-placeholder
|
||||
color transparent
|
||||
|
||||
//
|
||||
// messages
|
||||
//
|
||||
|
||||
.message
|
||||
padding-top .3rem
|
||||
margin-bottom .6rem
|
||||
|
||||
#messages .message .time
|
||||
#messages .message .audi
|
||||
opacity 0
|
||||
margin-left 2rem
|
||||
|
||||
#messages .message:hover .time
|
||||
#messages .message:hover .audi
|
||||
opacity 1
|
||||
|
||||
#messages .message .attr
|
||||
position absolute
|
||||
overflow hidden
|
||||
max-height 1.6rem
|
||||
white-space nowrap
|
||||
|
||||
// #writing-container
|
||||
// #messages .message.first
|
||||
// border-top 1px solid #ededed
|
||||
|
||||
#writing-container
|
||||
padding-top .3rem
|
||||
|
||||
#messages .message.first
|
||||
|
||||
#messages .message.same .audi
|
||||
margin-top 0
|
||||
|
||||
#messages .message.same .type
|
||||
opacity 0
|
||||
|
||||
#messages .message.same .iden
|
||||
display none
|
||||
|
||||
#messages .message:hover .type
|
||||
color rgb(240,73,65)
|
||||
|
||||
#messages .message.attr
|
||||
max-height 2rem
|
||||
-webkit-transition max-height 2s, color .1s linear
|
||||
|
||||
#messages .message:hover .attr
|
||||
max-height 6rem
|
||||
padding-bottom 1rem
|
||||
z-index 3
|
||||
-webkit-transition max-height .2s, color .1s linear
|
||||
|
||||
#messages .message:hover .attr > div
|
||||
max-width 48rem
|
||||
|
||||
#messages .message .ship
|
||||
#messages .message .audi > div
|
||||
cursor pointer
|
||||
|
||||
#messages .message.new
|
||||
border-top 1px solid #e5e5e5
|
||||
|
||||
.member
|
||||
width 12rem
|
||||
margin .3rem .6rem .3rem 0
|
||||
|
||||
#messages
|
||||
height auto
|
||||
|
||||
.message.pending
|
||||
color #ccc
|
||||
|
||||
.message.say .mess
|
||||
font-style italic
|
||||
|
||||
.message.exp .mess
|
||||
font-family monospace
|
||||
|
||||
a
|
||||
text-decoration underline
|
||||
color inherit
|
||||
|
||||
.sig
|
||||
.type
|
||||
margin-left 1rem
|
||||
float left
|
||||
width 1rem
|
||||
|
||||
.type
|
||||
height 2rem
|
||||
|
||||
.sig
|
||||
font-size 2rem
|
||||
margin-left .7rem
|
||||
margin-right .3rem
|
||||
|
||||
.sig:before
|
||||
content "~"
|
||||
|
||||
.type.private:before
|
||||
content attr(data-glyph)
|
||||
font-size 1rem
|
||||
line-height 1.1rem
|
||||
|
||||
.type.public:before
|
||||
content attr(data-glyph)
|
||||
font-size .8rem
|
||||
line-height 1.2rem
|
||||
|
||||
.mess
|
||||
.iden
|
||||
#station .member div
|
||||
#writing
|
||||
display inline-block
|
||||
|
||||
.mess
|
||||
#writing
|
||||
#length
|
||||
vertical-align top
|
||||
|
||||
.attr > div
|
||||
line-height 1.4rem
|
||||
max-width 16rem
|
||||
|
||||
.attr
|
||||
text-align left
|
||||
display inline-block
|
||||
max-height 1.2rem
|
||||
margin-right .3rem
|
||||
min-width 16rem
|
||||
background-color white
|
||||
|
||||
.attr .iden
|
||||
line-hieght 1.4rem
|
||||
|
||||
.audi
|
||||
.station .path
|
||||
white-space nowrap
|
||||
overflow hidden
|
||||
text-transform uppercase
|
||||
letter-spacing .05rem
|
||||
|
||||
.audi
|
||||
margin-top 1rem
|
||||
background-color #fff
|
||||
|
||||
.audi > div
|
||||
margin-right .3rem
|
||||
max-width 16rem
|
||||
display block
|
||||
|
||||
.iden > div
|
||||
max-width 11rem
|
||||
display inline-block
|
||||
font-size .9rem
|
||||
|
||||
.iden > div
|
||||
.audi > div
|
||||
background-color white
|
||||
overflow hidden
|
||||
white-space nowrap
|
||||
text-overflow ellipsis
|
||||
-webkit-transition max-width .2s
|
||||
|
||||
.audi > div:last-child
|
||||
margin-right 0
|
||||
|
||||
.iden > div:hover
|
||||
.audi > div:hover
|
||||
position relative
|
||||
-webkit-transition max-width .2s
|
||||
|
||||
.mess
|
||||
letter-spacing .03rem
|
||||
word-wrap break-word
|
||||
margin-left 16.3rem
|
||||
|
||||
.mess
|
||||
#writing
|
||||
.iden > div:hover
|
||||
.audi > div:hover
|
||||
max-width 42rem
|
||||
|
||||
.iden > div:hover
|
||||
padding-right 3rem
|
||||
|
||||
.mess
|
||||
#writing
|
||||
font-size 1.2rem
|
||||
|
||||
//
|
||||
// writing
|
||||
//
|
||||
|
||||
#writing
|
||||
min-height 1.6rem
|
||||
min-width 1.3rem
|
||||
max-width 32rem
|
||||
line-height 2rem
|
||||
outline none
|
||||
padding .3rem .1rem
|
||||
margin-top -.3rem
|
||||
border-bottom 3px solid #555
|
||||
|
||||
.writing
|
||||
padding-top .3rem
|
||||
|
||||
.writing #length
|
||||
display inline
|
||||
margin-left 1rem
|
||||
margin-top 1.2rem
|
||||
|
||||
.writing .attr
|
||||
line-height 1.6rem
|
||||
vertical-align top
|
||||
margin-left 2rem
|
||||
min-width 14rem
|
||||
|
||||
.writing .iden
|
||||
display block
|
||||
width 100%
|
||||
|
||||
.writing .iden .ship
|
||||
margin-right .3rem
|
||||
|
||||
#audi
|
||||
display inline-block
|
||||
margin-right -.2rem
|
||||
margin-bottom .3rem
|
||||
outline none
|
||||
overflow hidden
|
||||
max-width 12rem
|
||||
min-width 1rem
|
||||
padding .3rem .1rem .1rem 0
|
||||
border-bottom 2px solid #555
|
||||
|
||||
.valid-false
|
||||
color #ff2f2f !important
|
||||
|
||||
//
|
||||
// scrolling
|
||||
//
|
||||
|
||||
#scrolling
|
||||
display none
|
||||
|
||||
.scrolling #scrolling
|
||||
position fixed
|
||||
bottom 3rem
|
||||
left 2rem
|
||||
height 1rem
|
||||
padding 1rem
|
||||
height 2rem
|
||||
background-color #f9f9f9
|
||||
font-weight 500
|
||||
font-size .8rem
|
||||
text-transform uppercase
|
||||
|
||||
//
|
||||
// offline
|
||||
//
|
||||
|
||||
body:not(.offline) #offline
|
||||
display none
|
||||
|
||||
#offline
|
||||
transition: color 0.25s ease
|
||||
|
||||
#offline.error
|
||||
color: red
|
||||
|
||||
@import 'mobile'
|
@ -1,91 +0,0 @@
|
||||
/* computers --------*/
|
||||
@media only screen and (min-width: 1024px)
|
||||
#station-container:hover
|
||||
max-height 30rem
|
||||
height auto
|
||||
-webkit-transition max-height .2s
|
||||
|
||||
#station-container:hover #where .caret
|
||||
transform rotate(90deg)
|
||||
transform-origin 0 50%
|
||||
-webkit-transform rotate(90deg)
|
||||
-webkit-transition -webkit-transform .2s
|
||||
|
||||
/* laptops / small screens ----------- */
|
||||
@media only screen and (max-width: 1170px)
|
||||
#station-container.open
|
||||
max-height 30rem
|
||||
height auto
|
||||
-webkit-transition max-height .2s
|
||||
|
||||
#station-container.open #where .caret
|
||||
transform rotate(90deg)
|
||||
transform-origin 0 50%
|
||||
-webkit-transform rotate(90deg)
|
||||
-webkit-transition -webkit-transform .2s
|
||||
|
||||
#c
|
||||
#station-container
|
||||
width 96%
|
||||
left 0
|
||||
margin-left 2%
|
||||
margin-right 2%
|
||||
|
||||
.mess
|
||||
#writing
|
||||
max-width 60%
|
||||
line-height 1.6rem
|
||||
|
||||
.attr
|
||||
#stations
|
||||
#where
|
||||
width 20%
|
||||
min-width 20%
|
||||
|
||||
#audience
|
||||
#who
|
||||
width 60%
|
||||
|
||||
#writing
|
||||
padding .1rem
|
||||
|
||||
#station-container.m-down
|
||||
#station-container.m-up
|
||||
position absolute
|
||||
|
||||
#station-container.m-down.m-fixed
|
||||
position fixed
|
||||
top 0
|
||||
|
||||
/* tablets + phones ----------- */
|
||||
// @media only screen and (min-width: 320px) and (max-width: 1024px)
|
||||
|
||||
/* phones portrait and landscape ----------- */
|
||||
@media only screen and (min-device-width: 320px) and (max-device-width: 480px)
|
||||
.mess
|
||||
#writing
|
||||
max-width 70%
|
||||
line-height 1.2rem
|
||||
|
||||
#stations
|
||||
#audience
|
||||
width 96%
|
||||
|
||||
#stations
|
||||
#audience
|
||||
.sour-ctrl input
|
||||
text-align left
|
||||
|
||||
#station
|
||||
cursor pointer
|
||||
|
||||
#station-container.open
|
||||
max-height 30rem
|
||||
height auto
|
||||
-webkit-transition max-height .2s
|
||||
|
||||
#station-container.open #where .caret
|
||||
transform rotate(90deg)
|
||||
transform-origin 0 50%
|
||||
-webkit-transform rotate(90deg)
|
||||
-webkit-transition -webkit-transform .2s
|
@ -1,75 +0,0 @@
|
||||
Dispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||
|
||||
_persistence = require '../persistence/MessagePersistence.coffee'
|
||||
|
||||
Persistence = _persistence MessageActions: module.exports =
|
||||
loadMessages: (messages,last,get) ->
|
||||
Dispatcher.handleServerAction {messages,last,get,type:"messages-load"}
|
||||
|
||||
listenStation: (station,date) ->
|
||||
if not date then date = window.urb.util.toDate(new Date())
|
||||
Persistence.listenStation station,date
|
||||
|
||||
listeningStation: (station) ->
|
||||
Dispatcher.handleViewAction {station,type:"messages-listen"}
|
||||
|
||||
setTyping: (state) ->
|
||||
Dispatcher.handleViewAction {state,type:"messages-typing"}
|
||||
|
||||
getMore: (station,start,end) ->
|
||||
Dispatcher.handleViewAction type:"messages-fetch"
|
||||
Persistence.get station,start,end
|
||||
|
||||
sendMessage: (txt,audience) ->
|
||||
serial = window.util.uuid32()
|
||||
|
||||
# audience.push window.util.mainStationPath window.urb.user
|
||||
audience = _.uniq audience
|
||||
|
||||
_audi = {}
|
||||
for k,v of audience
|
||||
_audi[v] =
|
||||
envelope:
|
||||
visible:true
|
||||
sender:null
|
||||
delivery:"pending"
|
||||
|
||||
speech = lin: {txt, say:true}
|
||||
|
||||
if txt[0] is "@"
|
||||
speech.lin.txt = speech.lin.txt.slice(1).trim()
|
||||
speech.lin.say = false
|
||||
|
||||
else if txt[0] is "#"
|
||||
speech = eval: speech.lin.txt.slice(1).trim()
|
||||
|
||||
else if window.urb.util.isURL(txt)
|
||||
speech = url: txt
|
||||
|
||||
speeches =
|
||||
if not (speech.lin?.txt.length > 64)
|
||||
[speech]
|
||||
else
|
||||
{say,txt} = speech.lin
|
||||
txt.match(/(.{1,64}$|.{0,64} |.{64}|.+$)/g).map (s,i)->
|
||||
say ||= i isnt 0
|
||||
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:window.util.uuid32()
|
||||
audience:_audi
|
||||
statement:
|
||||
bouquet:[]
|
||||
speech:speech
|
||||
date: Date.now()
|
||||
|
||||
Dispatcher.handleViewAction {message,type:"message-send"}
|
||||
Persistence.sendMessage message.thought
|
||||
|
@ -1,31 +0,0 @@
|
||||
Dispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||
serverAction = (f)-> ()-> Dispatcher.handleServerAction f.apply this,arguments
|
||||
viewAction = (f)-> ()-> Dispatcher.handleViewAction f.apply this,arguments
|
||||
|
||||
_persistence = require '../persistence/StationPersistence.coffee'
|
||||
|
||||
Persistence = _persistence StationActions: module.exports =
|
||||
loadGlyphs: serverAction (glyphs) -> {glyphs,type:"glyphs-load"}
|
||||
loadMembers: serverAction (members) -> {members,type:"members-load"}
|
||||
loadStations: serverAction (stations) -> {stations,type:"stations-load"}
|
||||
loadConfig: serverAction (station,config) -> {station,config,type:"config-load"}
|
||||
|
||||
setTyping: viewAction (station,state) -> {station,state,type:"typing-set"}
|
||||
setAudience: viewAction (audience) -> {audience,type:"station-set-audience"}
|
||||
setValidAudience: viewAction (valid) -> {valid,type:"station-set-valid-audience"}
|
||||
toggleAudience: viewAction (station) -> {station,type:"station-audience-toggle"}
|
||||
switchStation: viewAction (station) -> {station,type:"station-switch"}
|
||||
listeningStation: viewAction (station) -> {station,type:"station-listen"}
|
||||
|
||||
createStation: (station) ->
|
||||
Dispatcher.handleViewAction {station,type: "station-create"}
|
||||
Persistence.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,12 +0,0 @@
|
||||
recl = React.createClass
|
||||
{div,input,textarea} = React.DOM
|
||||
|
||||
module.exports = recl
|
||||
render: ->
|
||||
if @props.ship[0] is "~" then @props.ship = @props.ship.slice(1)
|
||||
k = "ship"
|
||||
k+= " #{@props.presence}" if @props.presence
|
||||
div {className:"iden"}, [
|
||||
# div {}, @props.glyph || "*"
|
||||
div {className:k}, @props.ship
|
||||
]
|
@ -1,213 +0,0 @@
|
||||
moment = require 'moment-timezone'
|
||||
clas = require 'classnames'
|
||||
|
||||
recl = React.createClass
|
||||
{div,pre,br,span,input,textarea,a} = React.DOM
|
||||
|
||||
MessageActions = require '../actions/MessageActions.coffee'
|
||||
MessageStore = require '../stores/MessageStore.coffee'
|
||||
StationActions = require '../actions/StationActions.coffee'
|
||||
StationStore = require '../stores/StationStore.coffee'
|
||||
Member = require './MemberComponent.coffee'
|
||||
|
||||
Message = recl
|
||||
displayName: "Message"
|
||||
lz: (n) -> if n<10 then "0#{n}" else "#{n}"
|
||||
|
||||
convTime: (time) ->
|
||||
d = new Date time
|
||||
h = @lz d.getHours()
|
||||
m = @lz d.getMinutes()
|
||||
s = @lz d.getSeconds()
|
||||
"~#{h}.#{m}.#{s}"
|
||||
|
||||
_handleAudi: (e) ->
|
||||
audi = _.map $(e.target).closest('.audi').find('div'), (div) -> return "~"+$(div).text()
|
||||
@props._handleAudi audi
|
||||
|
||||
_handlePm: (e) ->
|
||||
return if not @props._handlePm
|
||||
user = $(e.target).closest('.iden').text()
|
||||
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 = clas pending: @props.pending isnt "received"
|
||||
delivery = _.uniq _.pluck @props.thought.audience, "delivery"
|
||||
speech = @props.thought.statement.speech
|
||||
attachments = []
|
||||
while speech.fat?
|
||||
attachments.push pre {}, speech.fat.tor.tank.join("\n")
|
||||
speech = speech.fat.taf # XX
|
||||
if !speech? then return;
|
||||
|
||||
name = if @props.name then @props.name else ""
|
||||
aude = _.keys @props.thought.audience
|
||||
audi = window.util.clipAudi(aude).map (_audi) -> (div {}, _audi.slice(1))
|
||||
|
||||
mainStation = window.util.mainStationPath(window.urb.user)
|
||||
type = if mainStation in aude then 'private' else 'public'
|
||||
|
||||
className = clas {message:true},
|
||||
(if @props.sameAs then "same" else "first"),
|
||||
(if delivery.indexOf("received") isnt -1 then "received" else "pending"),
|
||||
{say: speech.lin?.say is false, url: speech.url, 'new': @props.unseen},
|
||||
switch
|
||||
when speech.app? then "say"
|
||||
when speech.exp? then "exp"
|
||||
|
||||
div {className}, [
|
||||
(div {className:"attr"}, [
|
||||
div {className:"type #{type}", "data-glyph": @props.glyph || "*"}
|
||||
(div {onClick:@_handlePm},
|
||||
(React.createElement Member,{ship:@props.ship,glyph:@props.glyph}))
|
||||
div {onClick:@_handleAudi,className:"audi"}, audi
|
||||
div {className:"time"}, @convTime @props.thought.statement.date
|
||||
])
|
||||
|
||||
div {className:"mess"},
|
||||
(@renderSpeech speech)
|
||||
if attachments.length
|
||||
div {className:"fat"}, attachments
|
||||
]
|
||||
|
||||
module.exports = recl
|
||||
displayName: "Messages"
|
||||
pageSize: 50
|
||||
paddingTop: 100
|
||||
|
||||
stateFromStore: -> {
|
||||
messages:MessageStore.getAll()
|
||||
last:MessageStore.getLast()
|
||||
fetching:MessageStore.getFetching()
|
||||
listening:MessageStore.getListening()
|
||||
station:window.talk.mainStation
|
||||
stations:StationStore.getStations()
|
||||
configs:StationStore.getConfigs()
|
||||
typing:MessageStore.getTyping()
|
||||
glyphs:StationStore.getGlyphMap()
|
||||
}
|
||||
|
||||
getInitialState: -> @stateFromStore()
|
||||
|
||||
_blur: ->
|
||||
@focussed = false
|
||||
@lastSeen = @last
|
||||
|
||||
_focus: ->
|
||||
@focussed = true
|
||||
@lastSeen = null
|
||||
$('.message.new').removeClass 'new'
|
||||
document.title = document.title.replace /\ \([0-9]*\)/, ""
|
||||
|
||||
checkMore: ->
|
||||
if $(window).scrollTop() < @paddingTop &&
|
||||
@state.fetching is false &&
|
||||
this.state.last &&
|
||||
this.state.last > 0
|
||||
end = @state.last-@pageSize
|
||||
end = 0 if end < 0
|
||||
@lastLength = @length
|
||||
MessageActions.getMore @state.station,(@state.last+1),end
|
||||
|
||||
setAudience: ->
|
||||
return if not @last
|
||||
if _.keys(@last.thought.audience).length > 0 and @state.typing is false and
|
||||
_.difference(_.keys(@last.thought.audience),@state.audi).length is 0
|
||||
StationActions.setAudience _.keys(@last.thought.audience)
|
||||
|
||||
sortedMessages: (messages) ->
|
||||
_.sortBy messages, (_message) ->
|
||||
_message.pending = _message.thought.audience[station]
|
||||
_message.key
|
||||
#_message.thought.statement.date
|
||||
|
||||
componentDidMount: ->
|
||||
MessageStore.addChangeListener @_onChangeStore
|
||||
StationStore.addChangeListener @_onChangeStore
|
||||
if @state.station and
|
||||
@state.listening.indexOf(@state.station) is -1
|
||||
MessageActions.listenStation @state.station
|
||||
checkMore = @checkMore
|
||||
$(window).on 'scroll', checkMore
|
||||
@focussed = true
|
||||
$(window).on 'blur', @_blur
|
||||
$(window).on 'focus', @_focus
|
||||
window.util.setScroll()
|
||||
|
||||
componentDidUpdate: ->
|
||||
$window = $(window)
|
||||
if @lastLength
|
||||
st = $window.height()
|
||||
$window.scrollTop st
|
||||
@lastLength = null
|
||||
else
|
||||
if not window.util.isScrolling()
|
||||
window.util.setScroll()
|
||||
else
|
||||
console.log 'scrolling'
|
||||
|
||||
if @focussed is false and @last isnt @lastSeen
|
||||
_messages = @sortedMessages @state.messages
|
||||
d = _messages.length-_messages.indexOf(@lastSeen)-1
|
||||
t = document.title
|
||||
if document.title.match(/\([0-9]*\)/)
|
||||
document.title = document.title.replace /\([0-9]*\)/, "(#{d})"
|
||||
else
|
||||
document.title = document.title + " (#{d})"
|
||||
|
||||
componentWillUnmount: ->
|
||||
MessageStore.removeChangeListener @_onChangeStore
|
||||
StationStore.removeChangeListener @_onChangeStore
|
||||
|
||||
_onChangeStore: -> @setState @stateFromStore()
|
||||
|
||||
_handlePm: (user) ->
|
||||
audi = [window.util.mainStationPath(user)]
|
||||
if user is window.urb.user then audi.pop()
|
||||
StationActions.setAudience audi
|
||||
|
||||
_handleAudi: (audi) -> StationActions.setAudience audi
|
||||
|
||||
render: ->
|
||||
station = @state.station
|
||||
_station = "~"+window.urb.ship+"/"+station
|
||||
sources = _.clone @state.configs[@state.station]?.sources ? []
|
||||
sources.push _station
|
||||
_messages = @sortedMessages @state.messages
|
||||
|
||||
@last = _messages[_messages.length-1]
|
||||
if @last?.ship && @last.ship is window.urb.user then @lastSeen = @last
|
||||
@length = _messages.length
|
||||
|
||||
setTimeout =>
|
||||
@checkMore() if length < @pageSize
|
||||
, 1
|
||||
|
||||
lastIndex = if @lastSeen then _messages.indexOf(@lastSeen)+1 else null
|
||||
lastSaid = null
|
||||
|
||||
div {id: "messages"}, _messages.map (_message,k) =>
|
||||
nowSaid = [_message.ship,_message.thought.audience]
|
||||
glyph = window.util.getGlyph @state.glyphs, _.keys _message.thought.audience
|
||||
{station} = @state
|
||||
mess = {
|
||||
glyph, station, @_handlePm, @_handleAudi,
|
||||
unseen: lastIndex and lastIndex is k
|
||||
sameAs: _.isEqual lastSaid, nowSaid
|
||||
}
|
||||
lastSaid = nowSaid
|
||||
|
||||
if _message.thought.statement.speech?.app
|
||||
mess.ship = "system"
|
||||
|
||||
React.createElement Message, (_.extend {}, _message, mess)
|
@ -1,119 +0,0 @@
|
||||
recl = React.createClass
|
||||
{div,style,input,textarea,h1,a} = React.DOM
|
||||
|
||||
StationStore = require '../stores/StationStore.coffee'
|
||||
StationActions = require '../actions/StationActions.coffee'
|
||||
Member = require './MemberComponent.coffee'
|
||||
|
||||
module.exports = recl
|
||||
displayName: "Station"
|
||||
stateFromStore: -> {
|
||||
audi:StationStore.getAudience()
|
||||
members:StationStore.getMembers()
|
||||
station:window.talk.mainStation
|
||||
stations:StationStore.getStations()
|
||||
configs:StationStore.getConfigs()
|
||||
typing:StationStore.getTyping()
|
||||
listening:StationStore.getListening()
|
||||
}
|
||||
|
||||
getInitialState: -> @stateFromStore()
|
||||
|
||||
componentDidMount: ->
|
||||
@$el = $(@getDOMNode())
|
||||
@$input = @$el.find('input')
|
||||
|
||||
StationStore.addChangeListener @_onChangeStore
|
||||
if @state.listening.indexOf(@state.station) is -1
|
||||
StationActions.listenStation @state.station
|
||||
|
||||
componentWillUnmount: ->
|
||||
StationStore.removeChangeListener @_onChangeStore
|
||||
|
||||
|
||||
_onChangeStore: ->
|
||||
@setState @stateFromStore()
|
||||
|
||||
_toggleOpen: (e) ->
|
||||
if $(e.target).closest('.sour-ctrl').length > 0
|
||||
return
|
||||
$("#station-container").toggleClass 'open'
|
||||
|
||||
validateSource: (s) ->
|
||||
if @state.configs[@state.station].sources.indexOf(s) isnt -1
|
||||
return false
|
||||
if s.length < 5
|
||||
return false
|
||||
if s[0] isnt "~"
|
||||
return false
|
||||
if s.indexOf("/") is -1
|
||||
return false
|
||||
return true
|
||||
|
||||
_keyUp: (e) ->
|
||||
$('.sour-ctrl .join').removeClass 'valid-false'
|
||||
if e.keyCode is 13
|
||||
v = @$input.val().toLowerCase()
|
||||
if v[0] isnt "~" then v = "~#{v}"
|
||||
if @validateSource v
|
||||
_sources = _.clone @state.configs[@state.station].sources
|
||||
_sources.push v
|
||||
StationActions.setSources @state.station,_sources
|
||||
@$input.val('')
|
||||
@$input.blur()
|
||||
else
|
||||
$('.sour-ctrl .join').addClass 'valid-false'
|
||||
|
||||
_remove: (e) ->
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
_station = $(e.target).attr "data-station"
|
||||
_sources = _.clone @state.configs[@state.station].sources
|
||||
_sources.splice _sources.indexOf(_station),1
|
||||
StationActions.setSources @state.station,_sources
|
||||
|
||||
render: ->
|
||||
if window.urb.user isnt window.urb.ship #foreign
|
||||
return div {id:"station"}
|
||||
|
||||
parts = []
|
||||
members = []
|
||||
|
||||
if @state.station and @state.members
|
||||
members = _.map @state.members, (stations,member) ->
|
||||
audi = _.map stations,(presence,station) -> (div {className:"audi"}, station.slice(1))
|
||||
(div {}, [(React.createElement Member, {ship:member}),audi])
|
||||
else
|
||||
members = ""
|
||||
|
||||
sourceInput = [(input {className:"join",onKeyUp:@_keyUp,placeholder:"+"})]
|
||||
sourceCtrl = div {className:"sour-ctrl"},sourceInput
|
||||
|
||||
sources = []
|
||||
if @state.station and @state.configs[@state.station]
|
||||
_remove = @_remove
|
||||
_sources = _.clone @state.configs[@state.station].sources
|
||||
sources = _.map _sources,(source) =>
|
||||
(div {className:"station"}, [
|
||||
(div {className:"path"}, source.slice(1))
|
||||
(div {className:"remove",onClick:_remove,"data-station":source},"×"),
|
||||
])
|
||||
else
|
||||
sources = ""
|
||||
|
||||
(div {id:"station",onClick:@_toggleOpen},
|
||||
(div {id:"head"},
|
||||
(div {id:"who"},
|
||||
div {className:"sig"}
|
||||
div {className:"ship"},"#{window.urb.user}"
|
||||
)
|
||||
(div {id:"where"},
|
||||
div {className:"slat"},"talk"
|
||||
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)
|
||||
)
|
@ -1,61 +0,0 @@
|
||||
recl = React.createClass
|
||||
{div,input} = React.DOM
|
||||
|
||||
StationStore = require '../stores/StationStore.coffee'
|
||||
StationActions = require '../actions/StationActions.coffee'
|
||||
|
||||
module.exports = recl
|
||||
stateFromStore: -> {
|
||||
stations: StationStore.getStations()
|
||||
station: "~zod/court"
|
||||
}
|
||||
|
||||
getInitialState: -> @stateFromStore()
|
||||
|
||||
componentDidMount: ->
|
||||
@$el = $ @getDOMNode()
|
||||
@$add = $ '#stations .add'
|
||||
@$input = @$el.find 'input'
|
||||
StationStore.addChangeListener @_onChangeStore
|
||||
|
||||
componentWillUnmount: ->
|
||||
StationStore.removeChangeListener @_onChangeStore
|
||||
|
||||
_onChangeStore: -> @setState @stateFromStore()
|
||||
|
||||
_click: (e) ->
|
||||
s = $(e.target).closest('.station').find('.name').text()
|
||||
window.location.hash = "/#{s.toLowerCase()}"
|
||||
|
||||
_keyUp: (e) ->
|
||||
if e.keyCode is 13
|
||||
v = @$input.val().toLowerCase()
|
||||
if @state.stations.indexOf(v) is -1
|
||||
StationActions.createStation v
|
||||
@$input.val('')
|
||||
@$input.blur()
|
||||
|
||||
_remove: (e) ->
|
||||
_station = $(e.target).parent().find('.name').text()
|
||||
_stations = _.without @state.stations,_station
|
||||
StationActions.removeStation _station,_stations
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
||||
render: ->
|
||||
station = @state.station
|
||||
_click = @_click
|
||||
_remove = @_remove
|
||||
stations = @state.stations.map (_station) ->
|
||||
k = "station"
|
||||
parts = [(div {className:"name"}, _station.name)]
|
||||
if _station.name isnt window.util.mainStation()
|
||||
parts.push (div {className:"remove",onClick:_remove,dataStation:_station.name},"×")
|
||||
div {className:k,onClick:_click},parts
|
||||
|
||||
div {id:"stations"}, [
|
||||
div {className:"stations"},stations
|
||||
div {className:"join-ctrl"}, [
|
||||
input {className:"join",onKeyUp:@_keyUp,placeholder:"+"}, ""
|
||||
]
|
||||
]
|
@ -1,15 +0,0 @@
|
||||
recl = React.createClass
|
||||
recf = React.createFactory
|
||||
{div} = React.DOM
|
||||
|
||||
StationComponent = recf require './StationComponent.coffee'
|
||||
MessagesComponent = recf require './MessagesComponent.coffee'
|
||||
WritingComponent = recf require './WritingComponent.coffee'
|
||||
|
||||
module.exports = recl
|
||||
render: ->
|
||||
(div {}, [
|
||||
(div {id:"station-container"}, (StationComponent {}))
|
||||
(div {id:"messages-container"}, (MessagesComponent {}))
|
||||
(div {id:"writing-container"}, (WritingComponent {}))
|
||||
])
|
@ -1,284 +0,0 @@
|
||||
recl = React.createClass
|
||||
{div,br,input,textarea} = React.DOM
|
||||
|
||||
husl = require 'husl'
|
||||
|
||||
MessageActions = require '../actions/MessageActions.coffee'
|
||||
MessageStore = require '../stores/MessageStore.coffee'
|
||||
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()
|
||||
|
||||
get: ->
|
||||
if window.localStorage then window.localStorage.getItem 'writing'
|
||||
|
||||
stateFromStore: ->
|
||||
s =
|
||||
audi:StationStore.getAudience()
|
||||
ludi:MessageStore.getLastAudience()
|
||||
config:StationStore.getConfigs()
|
||||
members:StationStore.getMembers()
|
||||
typing:StationStore.getTyping()
|
||||
valid:StationStore.getValidAudience()
|
||||
s.audi = _.without s.audi, window.util.mainStationPath window.urb.user
|
||||
s.ludi = _.without s.ludi, window.util.mainStationPath window.urb.user
|
||||
s
|
||||
|
||||
getInitialState: -> _.extend @stateFromStore(), length:0, lengthy: false
|
||||
|
||||
typing: (state) ->
|
||||
if @state.typing[@state.station] isnt state
|
||||
StationActions.setTyping @state.station,state
|
||||
|
||||
onBlur: ->
|
||||
@$writing.text @$writing.text()
|
||||
MessageActions.setTyping false
|
||||
@typing false
|
||||
|
||||
onFocus: ->
|
||||
MessageActions.setTyping true
|
||||
@typing true
|
||||
@cursorAtEnd
|
||||
|
||||
addCC: (audi) ->
|
||||
if window.urb.user isnt window.urb.ship #foreign
|
||||
return audi
|
||||
listening = @state.config[window.util.mainStation(window.urb.user)]?.sources ? []
|
||||
cc = false
|
||||
for s in audi
|
||||
if listening.indexOf(s) is -1
|
||||
cc = true
|
||||
if listening.length is 0 then cc = true
|
||||
if cc is true
|
||||
audi.push window.util.mainStationPath(window.urb.user)
|
||||
audi
|
||||
|
||||
sendMessage: ->
|
||||
if @_validateAudi() is false
|
||||
$('#audi').focus()
|
||||
return
|
||||
if @state.audi.length is 0 and $('#audi').text().trim().length > 0
|
||||
audi = if @_setAudi() then @_setAudi() else @state.ludi
|
||||
else
|
||||
audi = @state.audi
|
||||
audi = @addCC audi
|
||||
txt = @$writing.text().trim().replace(/\xa0/g,' ')
|
||||
MessageActions.sendMessage txt,audi
|
||||
@$writing.text('')
|
||||
@setState length:0
|
||||
@set()
|
||||
@typing false
|
||||
|
||||
onKeyUp: (e) ->
|
||||
if not window.urb.util.isURL @$writing.text()
|
||||
@setState lengthy: (@$writing.text().length > 62)
|
||||
# r = window.getSelection().getRangeAt(0).cloneRange()
|
||||
# @$writing.text @$writing.text()
|
||||
# setTimeout =>
|
||||
# s = window.getSelection()
|
||||
# s.removeAllRanges()
|
||||
# s.addRange r
|
||||
# console.log r
|
||||
# ,0
|
||||
|
||||
onKeyDown: (e) ->
|
||||
if e.keyCode is 13
|
||||
txt = @$writing.text()
|
||||
e.preventDefault()
|
||||
if txt.length > 0
|
||||
if window.talk.online
|
||||
@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
|
||||
@onInput()
|
||||
@set()
|
||||
|
||||
onInput: (e) ->
|
||||
text = @$writing.text()
|
||||
length = text.length
|
||||
# geturl = new RegExp [
|
||||
# '(^|[ \t\r\n])((ftp|http|https|gopher|mailto|'
|
||||
# 'news|nntp|telnet|wais|file|prospero|aim|webcal'
|
||||
# '):(([A-Za-z0-9$_.+!*(),;/?:@&~=-])|%[A-Fa-f0-9]{2}){2,}'
|
||||
# '(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*(),;/?:@&~=%-]*))?'
|
||||
# '([A-Za-z0-9$_+!*();/?:~-]))'
|
||||
# ].join() , "g"
|
||||
# urls = text.match(geturl)
|
||||
# if urls isnt null and urls.length > 0
|
||||
# for url in urls
|
||||
# length -= url.length
|
||||
# length += 10
|
||||
@setState {length}
|
||||
|
||||
_validateAudiPart: (a) ->
|
||||
a = a.trim()
|
||||
# if a[0] isnt "~"
|
||||
# return false
|
||||
if a.indexOf("/") isnt -1
|
||||
_a = a.split("/")
|
||||
if _a[1].length is 0
|
||||
return false
|
||||
ship = _a[0]
|
||||
else
|
||||
ship = a
|
||||
|
||||
return (SHIPSHAPE.test ship) and
|
||||
_.all (ship.match /[a-z]{3}/g), (a)-> -1 isnt PO.indexOf a
|
||||
|
||||
_validateAudi: ->
|
||||
v = $('#audi').text()
|
||||
v = v.trim()
|
||||
if v.length is 0
|
||||
return true
|
||||
if v.length < 5 # zod/a is shortest
|
||||
return false
|
||||
_.all (v.split /\ +/), @_validateAudiPart
|
||||
|
||||
_setAudi: ->
|
||||
valid = @_validateAudi()
|
||||
StationActions.setValidAudience valid
|
||||
if valid is true
|
||||
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
|
||||
|
||||
getTime: ->
|
||||
d = new Date()
|
||||
seconds = d.getSeconds()
|
||||
if seconds < 10
|
||||
seconds = "0" + seconds
|
||||
"~"+d.getHours() + "." + d.getMinutes() + "." + seconds
|
||||
|
||||
cursorAtEnd: ->
|
||||
range = document.createRange()
|
||||
range.selectNodeContents @$writing[0]
|
||||
range.collapse(false)
|
||||
selection = window.getSelection()
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
|
||||
componentDidMount: ->
|
||||
window.util.sendMessage = @sendMessage
|
||||
StationStore.addChangeListener @_onChangeStore
|
||||
MessageStore.addChangeListener @_onChangeStore
|
||||
@$el = $ @getDOMNode()
|
||||
@$writing = $('#writing')
|
||||
@$writing.focus()
|
||||
if @get()
|
||||
@$writing.text @get()
|
||||
@onInput()
|
||||
@interval = setInterval =>
|
||||
@$el.find('.time').text @getTime()
|
||||
, 1000
|
||||
|
||||
componentWillUnmount: ->
|
||||
StationStore.removeChangeListener @_onChangeStore
|
||||
clearInterval @interval
|
||||
|
||||
_onChangeStore: -> @setState @stateFromStore()
|
||||
|
||||
render: ->
|
||||
# if window.urb.user isnt window.urb.ship #foreign
|
||||
# return div {className:"writing"}
|
||||
|
||||
user = "~"+window.urb.user
|
||||
iden = StationStore.getMember(user)
|
||||
ship = if iden then iden.ship else user
|
||||
name = if iden then iden.name else ""
|
||||
|
||||
audi = if @state.audi.length is 0 then @state.ludi else @state.audi
|
||||
audi = window.util.clipAudi audi
|
||||
for k,v of audi
|
||||
audi[k] = v.slice(1)
|
||||
|
||||
k = "writing"
|
||||
|
||||
div {className:k}, [
|
||||
(div {className:"attr"}, [
|
||||
(React.createElement Member, iden)
|
||||
(React.createElement Audience, {audi,valid:@state.valid, onBlur:@_setAudi})
|
||||
(div {className:"time"}, @getTime())
|
||||
])
|
||||
(div {
|
||||
id:"writing"
|
||||
contentEditable:true
|
||||
onPaste: @onInput
|
||||
@onInput, @onFocus, @onBlur, @onKeyDown, @onKeyUp
|
||||
}, "")
|
||||
(div {id:"length"}, "#{@state.length}/64 (#{Math.ceil @state.length / 64})")
|
||||
]
|
File diff suppressed because one or more lines are too long
@ -1,13 +0,0 @@
|
||||
Dispatcher = require('flux').Dispatcher
|
||||
|
||||
module.exports = _.merge new Dispatcher(), {
|
||||
handleServerAction: (action) ->
|
||||
@dispatch
|
||||
source: 'server'
|
||||
action: action
|
||||
|
||||
handleViewAction: (action) ->
|
||||
@dispatch
|
||||
source: 'view'
|
||||
action: action
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
$(() ->
|
||||
StationActions = require './actions/StationActions.coffee' #start poll
|
||||
|
||||
rend = React.render
|
||||
|
||||
window.talk.online = yes
|
||||
|
||||
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 './move.coffee'
|
||||
|
||||
# checkScroll = ->
|
||||
# if $(window).scrollTop() > 20
|
||||
# $('#nav').addClass 'scrolling'
|
||||
# else
|
||||
# $('#nav').removeClass 'scrolling'
|
||||
# setInterval checkScroll, 500
|
||||
|
||||
|
||||
StationActions.listen()
|
||||
|
||||
StationComponent = require './components/StationComponent.coffee'
|
||||
MessagesComponent = require './components/MessagesComponent.coffee'
|
||||
WritingComponent = require './components/WritingComponent.coffee'
|
||||
|
||||
$c = $('#c')
|
||||
|
||||
# clean = -> # ??
|
||||
# React.unmountComponentAtNode $('#station-container')[0]
|
||||
# React.unmountComponentAtNode $('#messages-container')[0]
|
||||
# React.unmountComponentAtNode $('#writing-container')[0]
|
||||
|
||||
rend (React.createElement(StationComponent, {})),$('#station-container')[0]
|
||||
rend (React.createElement(MessagesComponent, {})),$('#messages-container')[0]
|
||||
rend (React.createElement(WritingComponent, {})),$('#writing-container')[0]
|
||||
)
|
File diff suppressed because it is too large
Load Diff
@ -1,66 +0,0 @@
|
||||
so = {}
|
||||
so.ls = $(window).scrollTop()
|
||||
so.cs = $(window).scrollTop()
|
||||
so.w = null
|
||||
so.$d = $('#nav > div')
|
||||
setSo = ->
|
||||
so.$n = $('#station-container')
|
||||
so.w = $(window).width()
|
||||
so.h = $(window).height()
|
||||
so.dh = $("#c").height()
|
||||
so.nh = so.$n.outerHeight(true)
|
||||
setSo()
|
||||
setInterval setSo,200
|
||||
|
||||
$(window).on 'resize', (e) ->
|
||||
if so.w > 1170
|
||||
so.$n.removeClass 'm-up m-down m-fixed'
|
||||
|
||||
ldy = 0
|
||||
|
||||
$(window).on 'scroll', (e) ->
|
||||
so.cs = $(window).scrollTop()
|
||||
|
||||
if so.w > 1170
|
||||
so.$n.removeClass 'm-up m-down m-fixed'
|
||||
if so.w < 1170
|
||||
dy = so.ls-so.cs
|
||||
|
||||
if so.cs <= 0
|
||||
so.$n.removeClass 'm-up'
|
||||
so.$n.addClass 'm-down m-fixed'
|
||||
return
|
||||
|
||||
if so.cs+so.h > so.dh then return
|
||||
|
||||
if so.$n.hasClass 'm-fixed' and
|
||||
so.w < 1024
|
||||
so.$n.css left:-1*$(window).scrollLeft()
|
||||
|
||||
if dy > 0 and ldy > 0
|
||||
if not so.$n.hasClass 'm-down'
|
||||
so.$n.removeClass('m-up').addClass 'm-down'
|
||||
top = so.cs-so.nh
|
||||
if top < 0 then top = 0
|
||||
so.$n.offset top:top
|
||||
if so.$n.hasClass('m-down') and
|
||||
not so.$n.hasClass('m-fixed') and
|
||||
so.$n.offset().top >= so.cs
|
||||
so.$n.addClass 'm-fixed'
|
||||
so.$n.attr {style:''}
|
||||
|
||||
if dy < 0 and ldy < 0
|
||||
if not so.$n.hasClass 'm-up'
|
||||
so.$n.removeClass 'open'
|
||||
so.$n.removeClass('m-down m-fixed').addClass 'm-up'
|
||||
so.$n.attr {style:''}
|
||||
top = so.cs
|
||||
sto = so.$n.offset().top
|
||||
if top < 0 then top = 0
|
||||
if top > sto and top < sto+so.nh then top = sto
|
||||
so.$n.offset top:top
|
||||
|
||||
ldy = dy
|
||||
so.ls = so.cs
|
||||
|
||||
$(window).on 'scroll', window.util.checkScroll
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "urbit-talk",
|
||||
"version": "0.0.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/urbit/urbit"
|
||||
},
|
||||
"description": "urbit talk frontend",
|
||||
"main": "main.js",
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.0",
|
||||
"coffeeify": "~0.7.0",
|
||||
"flux": "~2.0.1",
|
||||
"husl": "^6.0.1",
|
||||
"lodash": "~2.4.1",
|
||||
"moment-timezone": "~0.2.4"
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
window.urb.appl = "talk"
|
||||
send = (data,cb)-> window.urb.send data, {mark:"talk-command"}, cb
|
||||
|
||||
module.exports = ({MessageActions}) ->
|
||||
listenStation: (station,since) ->
|
||||
console.log 'listen station'
|
||||
console.log arguments
|
||||
$this = this
|
||||
window.urb.bind "/f/#{station}/#{since}", (err,res) ->
|
||||
if err or not res.data
|
||||
console.log '/f/ err!'
|
||||
console.log err
|
||||
console.log res
|
||||
$this.listenStation station,since
|
||||
return
|
||||
console.log('/f/')
|
||||
console.log(res.data)
|
||||
if res.data.ok is true
|
||||
MessageActions.listeningStation station
|
||||
if res.data?.grams?.tele
|
||||
{tele,num} = res.data?.grams
|
||||
MessageActions.loadMessages tele, num
|
||||
|
||||
get: (station,start,end) ->
|
||||
end = window.urb.util.numDot end
|
||||
start = window.urb.util.numDot start
|
||||
window.urb.bind "/f/#{station}/#{end}/#{start}", (err,res) ->
|
||||
if err or not res.data
|
||||
console.log '/f/ /e/s err'
|
||||
console.log err
|
||||
return
|
||||
console.log '/f/ /e/s'
|
||||
console.log res
|
||||
if res.data?.grams?.tele
|
||||
{tele,num} = res.data?.grams
|
||||
MessageActions.loadMessages tele,num,true
|
||||
window.urb.drop "/f/#{station}/#{end}/#{start}", (err,res) ->
|
||||
console.log 'done'
|
||||
console.log res
|
||||
|
||||
sendMessage: (message,cb) ->
|
||||
send {publish: [message]}, (err,res) ->
|
||||
console.log 'sent'
|
||||
console.log arguments
|
||||
cb(err,res) if cb
|
@ -1,55 +0,0 @@
|
||||
window.urb.appl = "talk"
|
||||
send = (data,cb)-> window.urb.send data, {mark:"talk-command"}, cb
|
||||
design = (party,config,cb)-> send {design:{party,config}}, cb
|
||||
module.exports = ({StationActions})->
|
||||
createStation: (name,cb) ->
|
||||
design name, {
|
||||
sources:[]
|
||||
caption:""
|
||||
cordon: posture:"white", list:[]
|
||||
}, cb
|
||||
|
||||
removeStation: (name,cb) -> design name, null, cb
|
||||
setSources: (station,ship,sources) ->
|
||||
cordon = posture:"white", list:[]
|
||||
design station, {sources,cordon,caption:""}, (err,res) ->
|
||||
console.log 'talk-command'
|
||||
console.log arguments
|
||||
|
||||
members: -> window.urb.bind "/a/court", (err,res) ->
|
||||
if err or not res
|
||||
console.log '/a/ err'
|
||||
console.log err
|
||||
return
|
||||
console.log '/a/'
|
||||
console.log res.data
|
||||
if res.data?.group?.global
|
||||
StationActions.loadMembers res.data.group.global
|
||||
|
||||
listen: -> window.urb.bind "/", (err,res) ->
|
||||
if err or not res.data
|
||||
console.log '/ err'
|
||||
console.log err
|
||||
return
|
||||
console.log '/'
|
||||
console.log res.data
|
||||
if res.data.house
|
||||
StationActions.loadStations res.data.house
|
||||
|
||||
listenStation: (station) -> window.urb.bind "/avx/#{station}", (err,res) ->
|
||||
if err or not res
|
||||
console.log '/avx/ err'
|
||||
console.log err
|
||||
return
|
||||
console.log('/avx/')
|
||||
console.log(res.data)
|
||||
if res.data.ok is true
|
||||
StationActions.listeningStation station
|
||||
if res.data.group
|
||||
res.data.group.global[window.util.mainStationPath(window.urb.user)] =
|
||||
res.data.group.local
|
||||
StationActions.loadMembers res.data.group.global
|
||||
if res.data.cabal?.loc
|
||||
StationActions.loadConfig station,res.data.cabal.loc
|
||||
if res.data.glyph
|
||||
StationActions.loadGlyphs res.data.glyph
|
@ -1,107 +0,0 @@
|
||||
moment = require 'moment-timezone'
|
||||
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
MessageDispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||
|
||||
_messages = {}
|
||||
_fetching = false
|
||||
_last = null
|
||||
_station = null
|
||||
_listening = []
|
||||
_typing = false
|
||||
|
||||
MessageStore = _.merge new EventEmitter,{
|
||||
removeChangeListener: (cb) -> @removeListener "change", cb
|
||||
|
||||
emitChange: -> @emit 'change'
|
||||
|
||||
addChangeListener: (cb) -> @on 'change', cb
|
||||
|
||||
leadingZero: (str) ->
|
||||
if Number(str) < 10 then "0"+str else str
|
||||
|
||||
convertDate: (time) ->
|
||||
time = time.substr(1).split(".")
|
||||
time[1] = @leadingZero time[1]
|
||||
time[2] = @leadingZero time[2]
|
||||
d = new moment "#{time[0]}-#{time[1]}-#{time[2]}T#{time[4]}:#{time[5]}:#{time[6]}Z"
|
||||
d.tz "Europe/London"
|
||||
d
|
||||
|
||||
getListening: -> _listening
|
||||
|
||||
getTyping: -> _typing
|
||||
|
||||
getLastAudience: ->
|
||||
if _.keys(_messages).length is 0 then return []
|
||||
messages = _.sortBy _messages, (_message) -> _message.thought.statement.time
|
||||
_.keys messages[messages.length-1].thought.audience
|
||||
|
||||
setTyping: (state) -> _typing = state
|
||||
|
||||
setListening: (station) ->
|
||||
if _listening.indexOf(station) isnt -1
|
||||
console.log 'already listening on that station (somehow).'
|
||||
else
|
||||
_listening.push station
|
||||
|
||||
setStation: (station) -> _station = station
|
||||
|
||||
sendMessage: (message) ->
|
||||
_messages[message.thought.serial] = message
|
||||
|
||||
loadMessages: (messages,last,get) ->
|
||||
key = last
|
||||
for v in messages
|
||||
serial = v.thought.serial
|
||||
v.key = key++
|
||||
# always overwrite with new
|
||||
_messages[serial] = v
|
||||
_last = last if last < _last or _last is null or get is true
|
||||
_fetching = false
|
||||
|
||||
getAll: -> _.values _messages
|
||||
|
||||
getFetching: -> _fetching
|
||||
|
||||
setFetching: (state) -> _fetching = state
|
||||
|
||||
getLast: -> _last
|
||||
}
|
||||
|
||||
MessageStore.setMaxListeners 100
|
||||
|
||||
MessageStore.dispatchToken = MessageDispatcher.register (payload) ->
|
||||
action = payload.action
|
||||
|
||||
switch action.type
|
||||
when 'station-switch'
|
||||
MessageStore.setStation action.station
|
||||
break
|
||||
when 'messages-listen'
|
||||
MessageStore.setListening action.station
|
||||
MessageStore.emitChange()
|
||||
break
|
||||
when 'messages-typing'
|
||||
MessageStore.setTyping action.state
|
||||
MessageStore.emitChange()
|
||||
break
|
||||
when 'messages-fetch'
|
||||
MessageStore.setFetching true
|
||||
MessageStore.emitChange()
|
||||
break
|
||||
when 'messages-load'
|
||||
MessageStore.loadMessages action.messages,action.last,action.get
|
||||
MessageStore.emitChange()
|
||||
break
|
||||
when 'message-load'
|
||||
MessageStore.loadMessage action.time,action.message,action.author
|
||||
MessageStore.emitChange()
|
||||
break
|
||||
when 'message-send'
|
||||
MessageStore.sendMessage action.message
|
||||
MessageStore.emitChange()
|
||||
break
|
||||
|
||||
module.exports = MessageStore
|
@ -1,165 +0,0 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
StationDispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||
|
||||
_audience = []
|
||||
_members = {}
|
||||
_stations = []
|
||||
_listening = []
|
||||
_station = null
|
||||
_config = {}
|
||||
_typing = {}
|
||||
_glyphs = {}
|
||||
_shpylg = {}
|
||||
|
||||
_validAudience = true
|
||||
|
||||
StationStore = _.merge new EventEmitter,{
|
||||
removeChangeListener: (cb) -> @removeListener "change", cb
|
||||
|
||||
emitChange: -> @emit 'change'
|
||||
|
||||
addChangeListener: (cb) -> @on 'change', cb
|
||||
|
||||
getAudience: -> _audience
|
||||
|
||||
setAudience: (audience) -> _audience = audience
|
||||
|
||||
getValidAudience: -> _validAudience
|
||||
|
||||
setValidAudience: (valid) -> _validAudience = valid
|
||||
|
||||
toggleAudience: (station) ->
|
||||
if _audience.indexOf(station) isnt -1
|
||||
_audience.splice _audience.indexOf(station), 1
|
||||
else
|
||||
_audience.push station
|
||||
|
||||
loadConfig: (station,config) -> _config[station] = config
|
||||
|
||||
getConfigs: -> _config
|
||||
|
||||
getConfig: (station) -> _config[station]
|
||||
|
||||
getGlyph: (station) -> _shpylg[station]
|
||||
|
||||
getGlyphMap: -> _shpylg
|
||||
|
||||
getGlyphAudience: (glyph) ->
|
||||
aud = _glyphs[glyph] ? []
|
||||
if aud.length is 1
|
||||
aud[0]
|
||||
|
||||
getMember: (ship) -> {ship:ship}
|
||||
|
||||
loadMembers: (members) ->
|
||||
_members = {}
|
||||
for station,list of members
|
||||
for member,presence of list
|
||||
_members[member] = {} if not _members[member]
|
||||
_members[member][station] = presence
|
||||
|
||||
getMembers: -> _members
|
||||
|
||||
getListening: -> _listening
|
||||
|
||||
setListening: (station) ->
|
||||
if _listening.indexOf(station) isnt -1
|
||||
console.log 'already listening on that station (somehow).'
|
||||
else
|
||||
_listening.push station
|
||||
|
||||
createStation: (station) ->
|
||||
_stations.push(station) if _stations.indexOf(station) is -1
|
||||
|
||||
loadStations: (stations) -> _stations = stations
|
||||
|
||||
loadGlyphs: (glyphs) ->
|
||||
_glyphs = glyphs
|
||||
_shpylg = {}
|
||||
for char,auds of glyphs
|
||||
for aud in auds
|
||||
_shpylg[aud.join " "] = char
|
||||
|
||||
getStations: -> _stations
|
||||
|
||||
setStation: (station) -> _station = station
|
||||
|
||||
unsetStation: (station) ->
|
||||
_station = null if _station is station
|
||||
|
||||
getStation: -> _station
|
||||
|
||||
joinStation: (station) ->
|
||||
if _config.court?.sources.indexOf(station) is -1
|
||||
_config.court.sources.push station
|
||||
|
||||
getTyping: () -> _typing
|
||||
|
||||
setTyping: (station,state) ->
|
||||
for k,v of _typing
|
||||
_typing[k] = (k is station)
|
||||
_typing[station] = state
|
||||
}
|
||||
|
||||
StationStore.setMaxListeners 100
|
||||
|
||||
StationStore.dispatchToken = StationDispatcher.register (payload) ->
|
||||
action = payload.action
|
||||
|
||||
switch action.type
|
||||
when 'station-audience-toggle'
|
||||
StationStore.toggleAudience action.station
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when 'station-set-audience'
|
||||
StationStore.setAudience action.audience
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when 'station-set-valid-audience'
|
||||
StationStore.setValidAudience action.valid
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when 'station-switch'
|
||||
StationStore.setAudience []
|
||||
StationStore.setStation action.station
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when 'station-listen'
|
||||
StationStore.setListening action.station
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "config-load" #[name:'loadConfig', args:['station', 'config']]
|
||||
StationStore.loadConfig action.station,action.config
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "glyphs-load" #[name:'loadConfig', args:['station', 'config']]
|
||||
StationStore.loadGlyphs action.glyphs
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "stations-load"
|
||||
StationStore.loadStations action.stations
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "stations-leave" # stations-leave:[{name:'loadStations' args:['stations']} ['unsetStation' 'station']]
|
||||
# ...
|
||||
# for command in actionVtable[action.type]
|
||||
# StationStore[command[0]].apply(command[1..].map(argname -> action[argname]))
|
||||
StationStore.loadStations action.stations
|
||||
StationStore.unsetStation action.station
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "station-create"
|
||||
StationStore.createStation action.station
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "members-load"
|
||||
StationStore.loadMembers action.members
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "typing-set"
|
||||
StationStore.setTyping action.station,action.state
|
||||
StationStore.emitChange()
|
||||
break
|
||||
|
||||
module.exports = StationStore
|
19439
pub/talk/src/js/test.js
19439
pub/talk/src/js/test.js
File diff suppressed because it is too large
Load Diff
@ -1,93 +0,0 @@
|
||||
if not window.util then window.util = {}
|
||||
_.merge window.util,
|
||||
mainStations: ["court","floor","porch"]
|
||||
|
||||
mainStationPath: (user = window.urb.user) ->
|
||||
"~#{user}/#{window.util.mainStation(user)}"
|
||||
|
||||
mainStation: (user = window.urb.ship) ->
|
||||
switch user.length
|
||||
when 3
|
||||
return "court"
|
||||
when 6
|
||||
return "floor"
|
||||
when 13
|
||||
return "porch"
|
||||
|
||||
getGlyph: (glyphs, audi)->
|
||||
glyphs[audi.join " "] or switch
|
||||
when not _.contains audi, window.util.mainStationPath()
|
||||
"*"
|
||||
when audi.length is 1
|
||||
":"
|
||||
else ";"
|
||||
|
||||
clipAudi: (audi) ->
|
||||
audi = audi.join " "
|
||||
ms = window.util.mainStationPath()
|
||||
regx = new RegExp "/#{ms}","g"
|
||||
audi = audi.replace regx,""
|
||||
audi.split " "
|
||||
|
||||
expandAudi: (audi) ->
|
||||
audi = audi.join " "
|
||||
ms = window.util.mainStationPath()
|
||||
if audi.indexOf(ms) is -1
|
||||
if audi.length > 0
|
||||
audi += " "
|
||||
audi += "#{ms}"
|
||||
audi.split " "
|
||||
|
||||
create: (name) ->
|
||||
window.talk.StationPersistence.createStation name, (err,res) ->
|
||||
|
||||
subscribe: (name) ->
|
||||
window.talk.StationPersistence.addSource "main",window.urb.ship,["~zod/#{name}"]
|
||||
|
||||
uuid32: ->
|
||||
str = "0v"
|
||||
str += Math.ceil(Math.random()*8)+"."
|
||||
for i in [0..5]
|
||||
_str = Math.ceil(Math.random()*10000000).toString(32)
|
||||
_str = ("00000"+_str).substr(-5,5)
|
||||
str += _str+"."
|
||||
str.slice(0,-1)
|
||||
|
||||
populate: (station,number) ->
|
||||
c = 0
|
||||
send = ->
|
||||
if c < number
|
||||
c++
|
||||
else
|
||||
console.log 'done'
|
||||
return true
|
||||
_audi = {}
|
||||
_audi[station] = "pending"
|
||||
_message =
|
||||
serial:window.util.uuid32()
|
||||
audience:_audi
|
||||
statement:
|
||||
speech:
|
||||
say:"Message "+c
|
||||
time: Date.now()
|
||||
now: Date.now()
|
||||
window.talk.MessagePersistence.sendMessage _message,send
|
||||
send()
|
||||
|
||||
getScroll: ->
|
||||
@writingPosition = $('#c').outerHeight(true)+$('#c').offset().top-$(window).height()
|
||||
|
||||
setScroll: ->
|
||||
window.util.getScroll()
|
||||
$(window).scrollTop($("#c").height())
|
||||
|
||||
isScrolling: ->
|
||||
if not window.util.writingPosition
|
||||
window.util.getScroll()
|
||||
return ($(window).scrollTop()+$('#writing').outerHeight() < window.util.writingPosition)
|
||||
|
||||
checkScroll: ->
|
||||
if window.util.isScrolling()
|
||||
$('body').addClass 'scrolling'
|
||||
else
|
||||
$('body').removeClass 'scrolling'
|
Loading…
Reference in New Issue
Block a user