mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-18 12:22:10 +03:00
moved talk, example module
This commit is contained in:
parent
e2924c2396
commit
e5b8d19274
@ -18,8 +18,8 @@
|
|||||||
;head
|
;head
|
||||||
;title: Bootstrap Test - ~2016.1
|
;title: Bootstrap Test - ~2016.1
|
||||||
;meta(name "viewport", content "width=device-width, initial-scale=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/css/fonts.css");
|
||||||
;link(rel "stylesheet", href "/home/lib/bootstrap.css");
|
;link(rel "stylesheet", href "/home/lib/css/bootstrap.css");
|
||||||
;script(src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js");
|
;script(src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js");
|
||||||
==
|
==
|
||||||
;body
|
;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"
|
"lodash.js/2.4.1/lodash.min.js"
|
||||||
"react/0.13.1/react.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, ".
|
;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");
|
"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
|
;title: Talk
|
||||||
==
|
==
|
||||||
;body
|
;body
|
||||||
@ -45,6 +45,6 @@
|
|||||||
;div#scrolling: BOTTOM
|
;div#scrolling: BOTTOM
|
||||||
==
|
==
|
||||||
;script: window.talk = {(pojo (joba 'mainStation' s/man))}
|
;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