mirror of
https://github.com/urbit/shrub.git
synced 2024-12-14 20:02:51 +03:00
here comes talk
This commit is contained in:
commit
70e73f4f03
@ -1989,7 +1989,7 @@ try to get the aeon referred to by the starting case. If it doesn't
|
||||
exist yet, then we can't do anything interesting with this subscription,
|
||||
so we move on to the next one.
|
||||
|
||||
Otherwise, we try to get the aeon referrred to by the ending case. If it
|
||||
Otherwise, we try to get the aeon referred to by the ending case. If it
|
||||
doesn't exist yet, then we produce all the information we can. We call
|
||||
`++lobes-at-path` at the given aeon and path to see if the requested
|
||||
path has actually changed. If it hasn't, then we don't produce anything;
|
||||
|
12
docs/pub/tree/src/readme.md
Normal file
12
docs/pub/tree/src/readme.md
Normal file
@ -0,0 +1,12 @@
|
||||
# installing
|
||||
|
||||
`npm install`
|
||||
|
||||
# building
|
||||
|
||||
in `src/js/`:
|
||||
`watchify -v -t coffeeify -o main.js main.coffee`
|
||||
|
||||
in `src/css/`:
|
||||
`stylus -w main.styl`
|
||||
|
@ -9,8 +9,7 @@
|
||||
;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js");
|
||||
;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js");
|
||||
;script(type "text/javascript", src "//cdnjs.cloudflare.com/ajax/libs/react/0.12.1/react.js");
|
||||
;script(type "text/javascript", src "/main/pub/talk/src/js/dep/director.js");
|
||||
;meta(name "viewport", content "width=432, initial-scale=1");
|
||||
;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 "/main/pub/talk/src/css/main.css");
|
||||
;script(type "text/javascript", src "/gop/hart.js");
|
||||
;title: Radio
|
||||
|
@ -69,4 +69,16 @@
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-medium.woff");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-bold.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-black.woff");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
@ -70,10 +70,25 @@
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-bold.woff");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "scp";
|
||||
src: url("http://storage.googleapis.com/urbit-extra/scp-black.woff");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
.iden,
|
||||
.audi,
|
||||
.time,
|
||||
#length {
|
||||
#length,
|
||||
#where,
|
||||
#who,
|
||||
.station {
|
||||
font-family: "scp";
|
||||
}
|
||||
.join-ctrl input {
|
||||
@ -100,6 +115,9 @@ input.join,
|
||||
#station {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
.iden {
|
||||
font-weight: 600;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
font-size: 18px;
|
||||
@ -113,124 +131,152 @@ body {
|
||||
display: none;
|
||||
}
|
||||
#c {
|
||||
top: 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
#stations-container {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
top: 0rem;
|
||||
left: 50%;
|
||||
width: 24rem;
|
||||
margin-left: -12rem;
|
||||
font-size: 4rem;
|
||||
width: 58rem;
|
||||
margin-left: -29rem;
|
||||
margin-bottom: 12rem;
|
||||
}
|
||||
#station-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
width: 28rem;
|
||||
max-height: 2.6rem;
|
||||
width: 58rem;
|
||||
max-height: 2.7rem;
|
||||
background-color: #fff;
|
||||
border-bottom: 0.3rem solid #000;
|
||||
padding-bottom: 1rem;
|
||||
overflow: hidden;
|
||||
margin-left: -14rem;
|
||||
padding-top: 1rem;
|
||||
background-color: #f5f5f5;
|
||||
border-bottom: 3px solid #ededed;
|
||||
transition: max-height 0.15s ease-out;
|
||||
z-index: 10;
|
||||
-webkit-transition: max-height 0.2s;
|
||||
}
|
||||
#station-container:hover {
|
||||
max-height: 12rem;
|
||||
transition: max-height 0.25s ease-in;
|
||||
max-height: 30rem;
|
||||
height: auto;
|
||||
-webkit-transition: max-height 0.2s;
|
||||
}
|
||||
#stations-container,
|
||||
#messages-container {
|
||||
vertical-align: top;
|
||||
#station #station-container {
|
||||
padding-top: 1rem;
|
||||
min-width: 30rem;
|
||||
text-align: right;
|
||||
}
|
||||
#messaging-container {
|
||||
position: absolute;
|
||||
top: 4rem;
|
||||
left: 50%;
|
||||
width: 24rem;
|
||||
margin-left: -12rem;
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
#station > div {
|
||||
display: inline-block;
|
||||
}
|
||||
#station-meta {
|
||||
margin-right: 1rem;
|
||||
#writing-container {
|
||||
bottom: 4rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
#sources-container {
|
||||
width: 6rem;
|
||||
float: right;
|
||||
margin: 1rem -6rem 0 0;
|
||||
#messages-container {
|
||||
vertical-align: top;
|
||||
margin-top: 4rem;
|
||||
}
|
||||
#members {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
#station .iden {
|
||||
display: block;
|
||||
}
|
||||
.station {
|
||||
.caret,
|
||||
.circle {
|
||||
display: inline-block;
|
||||
width: 9rem;
|
||||
margin-bottom: 0.3rem;
|
||||
cursor: pointer;
|
||||
font-weight: 200;
|
||||
}
|
||||
#stations .station {
|
||||
display: block;
|
||||
width: 24rem;
|
||||
}
|
||||
.station .name {
|
||||
padding: 0.3rem;
|
||||
.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;
|
||||
}
|
||||
.station .name:hover {
|
||||
background-color: #f5f5f5;
|
||||
border-bottom: 6px solid #ededed;
|
||||
.circle {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border: 3px solid #000;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.station > div {
|
||||
#station-container #where .caret {
|
||||
-webkit-transform: rotate(0deg);
|
||||
-webkit-transform-origin: 0 50%;
|
||||
-webkit-transition: -webkit-transform 0.2s;
|
||||
}
|
||||
#station-container:hover #where .caret {
|
||||
transform: rotate(90deg);
|
||||
transform-origin: 0 50%;
|
||||
-webkit-transform: rotate(90deg);
|
||||
-webkit-transition: -webkit-transform 0.2s;
|
||||
}
|
||||
#head {
|
||||
width: 100%;
|
||||
height: 4rem;
|
||||
}
|
||||
#station-container h1 {
|
||||
font-weight: 500;
|
||||
font-size: 0.6rem;
|
||||
letter-spacing: 0.06rem;
|
||||
display: inline-block;
|
||||
line-height: 1.2rem;
|
||||
}
|
||||
#audience,
|
||||
#who {
|
||||
width: 34.6rem;
|
||||
}
|
||||
#stations,
|
||||
#where {
|
||||
width: 17.3rem;
|
||||
}
|
||||
#stations,
|
||||
#audience,
|
||||
#head > div {
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
}
|
||||
#head > div {
|
||||
height: 2rem;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
#where .caret {
|
||||
border-left-color: #f00;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
#who > span {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
#members > div {
|
||||
display: block;
|
||||
}
|
||||
#members > div div {
|
||||
display: inline-block;
|
||||
}
|
||||
.toggle {
|
||||
width: 0.4rem;
|
||||
height: 0.4rem;
|
||||
border: 2px solid #000;
|
||||
margin-right: 0.6rem;
|
||||
#members .audi {
|
||||
margin-right: 0.3rem;
|
||||
}
|
||||
.toggle.active {
|
||||
background-color: #000;
|
||||
#members .iden {
|
||||
min-width: 6rem;
|
||||
}
|
||||
.station div {
|
||||
display: inline-block;
|
||||
}
|
||||
.station .remove {
|
||||
display: none;
|
||||
float: right;
|
||||
margin-left: 1rem;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
width: 0.6rem;
|
||||
margin-right: 0.6rem;
|
||||
font-weight: 600;
|
||||
color: #f00;
|
||||
}
|
||||
.station:hover .remove {
|
||||
display: inline;
|
||||
opacity: 1;
|
||||
}
|
||||
#sources-container .station {
|
||||
font-family: "scp";
|
||||
font-weight: 500;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
.sour-ctrl {
|
||||
margin-bottom: 0.16rem;
|
||||
}
|
||||
.join-ctrl input,
|
||||
.sour-ctrl input {
|
||||
font-family: "scp";
|
||||
border: none;
|
||||
font-weight: 400;
|
||||
text-align: right;
|
||||
line-height: 1rem;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.sour-ctrl input::-webkit-input-placeholder {
|
||||
font-family: "bau";
|
||||
font-family: "scp";
|
||||
font-size: 1rem;
|
||||
font-weight: 200;
|
||||
font-weight: 600;
|
||||
margin-left: 0.6rem;
|
||||
color: #0003ff;
|
||||
color: #000;
|
||||
}
|
||||
.sour-ctrl input:focus::-webkit-input-placeholder {
|
||||
color: #fff;
|
||||
}
|
||||
.message {
|
||||
padding-top: 0.3rem;
|
||||
@ -245,8 +291,9 @@ body {
|
||||
#messages .message:hover .time {
|
||||
opacity: 1;
|
||||
}
|
||||
.time {
|
||||
margin-right: 0.6rem;
|
||||
#messages .message .ship,
|
||||
#messages .message .audi > div {
|
||||
cursor: pointer;
|
||||
}
|
||||
.member {
|
||||
width: 12rem;
|
||||
@ -255,55 +302,82 @@ body {
|
||||
#messages {
|
||||
height: auto;
|
||||
}
|
||||
.message.pending {
|
||||
color: #ccc;
|
||||
}
|
||||
.message.say .mess {
|
||||
font-style: italic;
|
||||
}
|
||||
.mess,
|
||||
.iden,
|
||||
.attr > div,
|
||||
#station .member div,
|
||||
#writing {
|
||||
display: inline-block;
|
||||
}
|
||||
.iden > div {
|
||||
display: inline;
|
||||
}
|
||||
.mess,
|
||||
#writing,
|
||||
#length {
|
||||
vertical-align: top;
|
||||
}
|
||||
.attr > div {
|
||||
max-width: 16rem;
|
||||
}
|
||||
.attr {
|
||||
color: #d7d7d7;
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
margin-right: 0.3rem;
|
||||
min-width: 16rem;
|
||||
}
|
||||
.attr .iden {
|
||||
color: #000;
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
.attr > div {
|
||||
.audi {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.audi > div {
|
||||
margin-right: 0.3rem;
|
||||
max-width: 8rem;
|
||||
}
|
||||
.iden > div {
|
||||
max-width: 16rem;
|
||||
}
|
||||
.iden > div,
|
||||
.audi > div {
|
||||
display: inline-block;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-transition: max-height 0.2s;
|
||||
}
|
||||
.audi > div:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
.iden > div:hover,
|
||||
.audi > div:hover {
|
||||
position: relative;
|
||||
max-width: 30rem;
|
||||
-webkit-transition: max-height 0.2s;
|
||||
}
|
||||
.mess {
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.6rem;
|
||||
letter-spacing: 0.03rem;
|
||||
word-wrap: break-word;
|
||||
max-width: 31rem;
|
||||
max-width: 30rem;
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
.ship {
|
||||
font-weight: 600;
|
||||
#writing {
|
||||
font-size: 0.9rem;
|
||||
min-height: 1.6rem;
|
||||
min-width: 1.3rem;
|
||||
outline: none;
|
||||
background-color: #eee;
|
||||
padding: 0.3rem 0.1rem;
|
||||
margin-left: 0.2rem;
|
||||
margin-top: -0.3rem;
|
||||
}
|
||||
.ship.talk:before {
|
||||
content: "...";
|
||||
margin-left: -1.3rem;
|
||||
margin-right: 0.3rem;
|
||||
width: 1rem;
|
||||
margin-top: -0.4rem;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
line-height: 0.2rem;
|
||||
letter-spacing: -0.1rem;
|
||||
}
|
||||
#writing-container {
|
||||
bottom: 4rem;
|
||||
margin-bottom: 1rem;
|
||||
float: left;
|
||||
#writing:focus {
|
||||
background-color: #fff;
|
||||
}
|
||||
.writing {
|
||||
padding-top: 0.3rem;
|
||||
@ -313,60 +387,25 @@ body {
|
||||
margin-left: 1rem;
|
||||
margin-top: 1.2rem;
|
||||
}
|
||||
#writing {
|
||||
font-size: 0.9rem;
|
||||
min-height: 1.6rem;
|
||||
line-height: 1.6rem;
|
||||
min-width: 1.3rem;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
.writing .iden {
|
||||
display: block;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
}
|
||||
.writing .iden .ship {
|
||||
margin-right: 0.3rem;
|
||||
}
|
||||
#audi {
|
||||
display: inline-block;
|
||||
background-color: #eee;
|
||||
}
|
||||
#writing:focus {
|
||||
background-color: #fff;
|
||||
}
|
||||
#station h1 {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
font-weight: 200;
|
||||
font-size: 2rem;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
input.join {
|
||||
font-size: 4rem;
|
||||
background-color: #fff;
|
||||
padding: 0.3rem 0.1rem;
|
||||
margin-top: -0.3rem;
|
||||
margin-right: -0.2rem;
|
||||
outline: none;
|
||||
width: 24rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
#station input.join {
|
||||
font-family: "scp";
|
||||
font-size: 0.7rem;
|
||||
line-height: 1rem;
|
||||
width: 12rem;
|
||||
}
|
||||
input.join::-webkit-input-placeholder {
|
||||
color: #0003ff;
|
||||
}
|
||||
input.join:focus::-webkit-input-placeholder {
|
||||
color: #fff;
|
||||
}
|
||||
.pending {
|
||||
color: #ccc;
|
||||
}
|
||||
a.up {
|
||||
height: 2rem;
|
||||
margin-top: 0.6rem;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
.arow-up {
|
||||
display: inline-block;
|
||||
margin: 0 0.5rem 0 0.5rem;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 9px solid transparent;
|
||||
border-right: 9px solid transparent;
|
||||
border-bottom: 9px solid #000;
|
||||
#audi.valid-false {
|
||||
color: #ff2f2f;
|
||||
}
|
||||
#scrolling {
|
||||
display: none;
|
||||
@ -383,67 +422,45 @@ a.up {
|
||||
font-size: 0.8rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@media (max-width: 40rem) {
|
||||
#c {
|
||||
@media only screen and (max-width: 1170px) {
|
||||
#c,
|
||||
#station-container {
|
||||
width: 96%;
|
||||
left: 0;
|
||||
margin-left: 0;
|
||||
width: 24rem;
|
||||
margin-left: 2%;
|
||||
margin-right: 2%;
|
||||
}
|
||||
#messages-container,
|
||||
#writing-container {
|
||||
margin-left: 1rem;
|
||||
.mess,
|
||||
#writing {
|
||||
max-width: 40%;
|
||||
line-height: 1.2rem;
|
||||
}
|
||||
#stations-container,
|
||||
#station-container {
|
||||
position: relative;
|
||||
float: left;
|
||||
.attr,
|
||||
#stations,
|
||||
#where {
|
||||
width: 20%;
|
||||
min-width: 20%;
|
||||
}
|
||||
#stations-container {
|
||||
width: 8rem;
|
||||
}
|
||||
#station-container {
|
||||
left: auto;
|
||||
}
|
||||
.station {
|
||||
width: 5rem;
|
||||
}
|
||||
.attr {
|
||||
display: block;
|
||||
text-align: left;
|
||||
width: 2rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
.message {
|
||||
height: 1.6rem;
|
||||
}
|
||||
.stations,
|
||||
.iden,
|
||||
#station {
|
||||
font-size: 0.5rem;
|
||||
}
|
||||
.station .remove {
|
||||
display: inline;
|
||||
font-size: 0.6rem;
|
||||
line-height: 0.6rem;
|
||||
}
|
||||
.ship.talk:before {
|
||||
margin-left: -0.3rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
.attr {
|
||||
width: 4rem;
|
||||
}
|
||||
.iden > div {
|
||||
display: block;
|
||||
}
|
||||
.attr > .time {
|
||||
display: none;
|
||||
}
|
||||
.mess {
|
||||
max-width: 12rem;
|
||||
margin-bottom: 1rem;
|
||||
#audience,
|
||||
#who {
|
||||
width: 60%;
|
||||
}
|
||||
#writing {
|
||||
max-width: 12rem;
|
||||
padding: 0.1rem;
|
||||
}
|
||||
.m-down,
|
||||
.m-up {
|
||||
position: absolute;
|
||||
}
|
||||
.m-down.m-fixed {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
|
||||
.mess,
|
||||
#writing {
|
||||
max-width: 70%;
|
||||
line-height: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,16 @@
|
||||
//
|
||||
// fonts first
|
||||
//
|
||||
|
||||
@import 'fonts'
|
||||
|
||||
.iden
|
||||
.audi
|
||||
.time
|
||||
#length
|
||||
#where
|
||||
#who
|
||||
.station
|
||||
font-family "scp"
|
||||
|
||||
.join-ctrl input
|
||||
@ -30,10 +37,17 @@ input.join
|
||||
#station
|
||||
font-size .7rem
|
||||
|
||||
.iden
|
||||
font-weight 600
|
||||
|
||||
html
|
||||
body
|
||||
font-size 18px
|
||||
|
||||
//
|
||||
// containers
|
||||
//
|
||||
|
||||
body
|
||||
background-color #fefefe
|
||||
padding 0
|
||||
@ -43,125 +57,165 @@ body
|
||||
display none
|
||||
|
||||
#c
|
||||
top 0
|
||||
background-color #fff
|
||||
|
||||
#stations-container
|
||||
position absolute
|
||||
top 1rem
|
||||
top 0rem
|
||||
left 50%
|
||||
width 24rem
|
||||
margin-left -12rem
|
||||
font-size 4rem
|
||||
|
||||
width 58rem
|
||||
margin-left -29rem
|
||||
margin-bottom 12rem
|
||||
|
||||
#station-container
|
||||
position fixed
|
||||
top 0
|
||||
left 50%
|
||||
width 28rem
|
||||
max-height 2.6rem
|
||||
width 58rem
|
||||
max-height 2.7rem
|
||||
background-color white
|
||||
border-bottom .3rem solid black
|
||||
padding-bottom 1rem
|
||||
overflow hidden
|
||||
margin-left -14rem
|
||||
padding-top 1rem
|
||||
background-color #f5f5f5
|
||||
border-bottom 3px solid #ededed
|
||||
transition max-height 0.15s ease-out
|
||||
z-index 10
|
||||
-webkit-transition max-height .2s
|
||||
|
||||
#station-container:hover
|
||||
max-height 12rem
|
||||
transition max-height 0.25s ease-in
|
||||
max-height 30rem
|
||||
height auto
|
||||
-webkit-transition max-height .2s
|
||||
|
||||
#station #station-container
|
||||
padding-top 1rem
|
||||
min-width 30rem
|
||||
text-align right
|
||||
|
||||
#stations-container
|
||||
#messages-container
|
||||
vertical-align top
|
||||
|
||||
#messaging-container
|
||||
position absolute
|
||||
top 4rem
|
||||
left 50%
|
||||
width 24rem
|
||||
margin-left -12rem
|
||||
margin-bottom 4rem
|
||||
|
||||
#station > div
|
||||
display inline-block
|
||||
|
||||
#station-meta
|
||||
margin-right 1rem
|
||||
#writing-container
|
||||
bottom 4rem
|
||||
margin-bottom 1rem
|
||||
|
||||
#sources-container
|
||||
width 6rem
|
||||
float right
|
||||
margin 1rem -6rem 0 0
|
||||
#messages-container
|
||||
vertical-align top
|
||||
margin-top 4rem
|
||||
|
||||
#members
|
||||
margin-left 2rem
|
||||
//
|
||||
// components
|
||||
//
|
||||
|
||||
#station .iden
|
||||
display block
|
||||
|
||||
.station
|
||||
.caret
|
||||
.circle
|
||||
display inline-block
|
||||
width 9rem
|
||||
margin-bottom .3rem
|
||||
cursor pointer
|
||||
font-weight 200
|
||||
|
||||
#stations .station
|
||||
display block
|
||||
width 24rem
|
||||
|
||||
.station .name
|
||||
padding .3rem
|
||||
.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
|
||||
|
||||
.station .name:hover
|
||||
background-color #f5f5f5
|
||||
border-bottom 6px solid #ededed
|
||||
.circle
|
||||
width 6px
|
||||
height 6px
|
||||
border 3px solid black
|
||||
border-radius 6px
|
||||
|
||||
.station > div
|
||||
//
|
||||
// station
|
||||
//
|
||||
|
||||
#station-container #where .caret
|
||||
-webkit-transform rotate(0deg)
|
||||
-webkit-transform-origin 0 50%
|
||||
-webkit-transition -webkit-transform .2s
|
||||
|
||||
#station-container:hover #where .caret
|
||||
transform rotate(90deg)
|
||||
transform-origin 0 50%
|
||||
-webkit-transform rotate(90deg)
|
||||
-webkit-transition -webkit-transform .2s
|
||||
|
||||
#head
|
||||
width 100%
|
||||
height 4rem
|
||||
|
||||
#station-container h1
|
||||
font-weight 500
|
||||
font-size .6rem
|
||||
letter-spacing .06rem
|
||||
display inline-block
|
||||
line-height 1.2rem
|
||||
|
||||
#audience
|
||||
#who
|
||||
width 34.6rem
|
||||
|
||||
#stations
|
||||
#where
|
||||
width 17.3rem
|
||||
|
||||
#stations
|
||||
#audience
|
||||
#head > div
|
||||
display inline-block
|
||||
text-align right
|
||||
vertical-align top
|
||||
|
||||
#head > div
|
||||
height 2rem
|
||||
margin-top 1.5rem
|
||||
|
||||
#where .caret
|
||||
border-left-color red
|
||||
margin-left 1rem
|
||||
|
||||
#who > span
|
||||
margin-left 1rem
|
||||
|
||||
#members > div
|
||||
display block
|
||||
|
||||
#members > div div
|
||||
display inline-block
|
||||
|
||||
.toggle
|
||||
width .4rem
|
||||
height .4rem
|
||||
border 2px solid #000
|
||||
margin-right .6rem
|
||||
#members .audi
|
||||
margin-right .3rem
|
||||
|
||||
.toggle.active
|
||||
background-color #000
|
||||
#members .iden
|
||||
min-width 6rem
|
||||
|
||||
.station div
|
||||
display inline-block
|
||||
|
||||
.station .remove
|
||||
display none
|
||||
float right
|
||||
margin-left 1rem
|
||||
opacity 0
|
||||
cursor pointer
|
||||
width .6rem
|
||||
margin-right .6rem
|
||||
font-weight 600
|
||||
color #ff0000
|
||||
|
||||
.station:hover .remove
|
||||
display inline
|
||||
opacity 1
|
||||
|
||||
#sources-container .station
|
||||
font-family "scp"
|
||||
font-weight 500
|
||||
text-transform lowercase
|
||||
|
||||
// hate this.
|
||||
.sour-ctrl
|
||||
margin-bottom .16rem
|
||||
|
||||
.join-ctrl input
|
||||
// add source
|
||||
.sour-ctrl input
|
||||
font-family "scp"
|
||||
border none
|
||||
font-weight 400
|
||||
text-align right
|
||||
line-height 1rem
|
||||
outline none
|
||||
cursor pointer
|
||||
|
||||
.sour-ctrl input::-webkit-input-placeholder
|
||||
font-family "bau"
|
||||
font-family "scp"
|
||||
font-size 1rem
|
||||
font-weight 200
|
||||
font-weight 600
|
||||
margin-left .6rem
|
||||
color #0003FF
|
||||
color #000
|
||||
|
||||
.sour-ctrl input:focus::-webkit-input-placeholder
|
||||
color white
|
||||
|
||||
//
|
||||
// messages
|
||||
//
|
||||
|
||||
.message
|
||||
padding-top .3rem
|
||||
@ -176,8 +230,9 @@ body
|
||||
#messages .message:hover .time
|
||||
opacity 1
|
||||
|
||||
.time
|
||||
margin-right .6rem
|
||||
#messages .message .ship
|
||||
#messages .message .audi > div
|
||||
cursor pointer
|
||||
|
||||
.member
|
||||
width 12rem
|
||||
@ -186,55 +241,86 @@ body
|
||||
#messages
|
||||
height auto
|
||||
|
||||
.message.pending
|
||||
color #ccc
|
||||
|
||||
.message.say .mess
|
||||
font-style italic
|
||||
|
||||
.mess
|
||||
.iden
|
||||
.attr > div
|
||||
#station .member div
|
||||
#writing
|
||||
display inline-block
|
||||
|
||||
.iden > div
|
||||
display inline
|
||||
|
||||
.mess
|
||||
#writing
|
||||
#length
|
||||
vertical-align top
|
||||
|
||||
.attr > div
|
||||
max-width 16rem
|
||||
|
||||
.attr
|
||||
color #D7D7D7
|
||||
text-align right
|
||||
display inline-block
|
||||
margin-right .3rem
|
||||
min-width 16rem
|
||||
|
||||
.attr .iden
|
||||
color #000
|
||||
margin-left .3rem
|
||||
|
||||
.attr > div
|
||||
.audi
|
||||
white-space nowrap
|
||||
|
||||
.audi > div
|
||||
margin-right .3rem
|
||||
max-width 8rem
|
||||
|
||||
.iden > div
|
||||
max-width 16rem
|
||||
|
||||
.iden > div
|
||||
.audi > div
|
||||
display inline-block
|
||||
background-color white
|
||||
overflow hidden
|
||||
white-space nowrap
|
||||
text-overflow ellipsis
|
||||
-webkit-transition max-height .2s
|
||||
|
||||
.audi > div:last-child
|
||||
margin-right 0
|
||||
|
||||
.iden > div:hover
|
||||
.audi > div:hover
|
||||
position relative
|
||||
max-width 30rem
|
||||
-webkit-transition max-height .2s
|
||||
|
||||
.mess
|
||||
font-size .9rem
|
||||
line-height 1.6rem
|
||||
letter-spacing .03rem
|
||||
word-wrap break-word
|
||||
max-width 31rem
|
||||
max-width 30rem
|
||||
margin-left .3rem
|
||||
|
||||
.ship
|
||||
font-weight 600
|
||||
//
|
||||
// writing
|
||||
//
|
||||
|
||||
.ship.talk:before
|
||||
content "..."
|
||||
margin-left -1.3rem
|
||||
margin-right .3rem
|
||||
width 1rem
|
||||
margin-top -.4rem
|
||||
vertical-align middle
|
||||
display inline-block
|
||||
line-height .2rem
|
||||
letter-spacing -.1rem
|
||||
#writing
|
||||
font-size .9rem
|
||||
min-height 1.6rem
|
||||
min-width 1.3rem
|
||||
outline none
|
||||
background-color #eee
|
||||
padding .3rem .1rem
|
||||
margin-left .2rem
|
||||
margin-top -.3rem
|
||||
|
||||
#writing-container
|
||||
bottom 4rem
|
||||
margin-bottom 1rem
|
||||
float left
|
||||
#writing:focus
|
||||
background-color #fff
|
||||
|
||||
.writing
|
||||
padding-top .3rem
|
||||
@ -244,60 +330,29 @@ body
|
||||
margin-left 1rem
|
||||
margin-top 1.2rem
|
||||
|
||||
#writing
|
||||
font-size .9rem
|
||||
min-height 1.6rem
|
||||
line-height 1.6rem
|
||||
min-width 1.3rem
|
||||
padding 0
|
||||
outline none
|
||||
.writing .iden
|
||||
display block
|
||||
text-align right
|
||||
width 100%
|
||||
|
||||
.writing .iden .ship
|
||||
margin-right .3rem
|
||||
|
||||
#audi
|
||||
display inline-block
|
||||
background-color #eee
|
||||
|
||||
#writing:focus
|
||||
background-color #fff
|
||||
|
||||
#station h1
|
||||
display inline-block
|
||||
margin 0
|
||||
font-weight 200
|
||||
font-size 2rem
|
||||
text-transform lowercase
|
||||
|
||||
input.join
|
||||
font-size 4rem
|
||||
background-color #fff
|
||||
padding .3rem .1rem
|
||||
margin-top -.3rem
|
||||
margin-right -.2rem
|
||||
outline none
|
||||
width 24rem
|
||||
overflow hidden
|
||||
|
||||
#station input.join
|
||||
font-family "scp"
|
||||
font-size .7rem
|
||||
line-height 1rem
|
||||
width 12rem
|
||||
#audi.valid-false
|
||||
color #ff2f2f
|
||||
|
||||
input.join::-webkit-input-placeholder
|
||||
color #0003FF
|
||||
|
||||
input.join:focus::-webkit-input-placeholder
|
||||
color #fff
|
||||
|
||||
.pending
|
||||
color #ccc
|
||||
|
||||
a.up
|
||||
height 2rem
|
||||
margin-top .6rem
|
||||
vertical-align middle
|
||||
display inline-block
|
||||
|
||||
.arow-up
|
||||
display inline-block
|
||||
margin 0 .5rem 0 .5rem
|
||||
width 0
|
||||
height 0
|
||||
border-left 9px solid transparent
|
||||
border-right 9px solid transparent
|
||||
border-bottom 9px solid #000
|
||||
//
|
||||
// scrolling
|
||||
//
|
||||
|
||||
#scrolling
|
||||
display none
|
||||
@ -314,66 +369,4 @@ a.up
|
||||
font-size .8rem
|
||||
text-transform uppercase
|
||||
|
||||
@media (max-width: 40rem)
|
||||
#c
|
||||
left 0
|
||||
margin-left 0
|
||||
width 24rem
|
||||
|
||||
#messages-container
|
||||
#writing-container
|
||||
margin-left 1rem
|
||||
|
||||
#stations-container
|
||||
#station-container
|
||||
position relative
|
||||
float left
|
||||
|
||||
#stations-container
|
||||
width 8rem
|
||||
|
||||
#station-container
|
||||
left auto
|
||||
|
||||
.station
|
||||
width 5rem
|
||||
|
||||
.attr
|
||||
display block
|
||||
text-align left
|
||||
width 2rem
|
||||
margin-right 1rem
|
||||
|
||||
.message
|
||||
height 1.6rem
|
||||
|
||||
.stations
|
||||
.iden
|
||||
#station
|
||||
font-size .5rem
|
||||
|
||||
.station .remove
|
||||
display inline
|
||||
font-size .6rem
|
||||
line-height .6rem
|
||||
|
||||
.ship.talk:before
|
||||
margin-left -.3rem
|
||||
margin-right 0
|
||||
|
||||
.attr
|
||||
width 4rem
|
||||
|
||||
.iden > div
|
||||
display block
|
||||
|
||||
.attr > .time
|
||||
display none
|
||||
|
||||
.mess
|
||||
max-width 12rem
|
||||
margin-bottom 1rem
|
||||
|
||||
#writing
|
||||
max-width 12rem
|
||||
|
||||
@import 'mobile'
|
44
main/pub/talk/src/css/mobile.styl
Normal file
44
main/pub/talk/src/css/mobile.styl
Normal file
@ -0,0 +1,44 @@
|
||||
/* laptops / small screens ----------- */
|
||||
@media only screen and (max-width: 1170px)
|
||||
#c
|
||||
#station-container
|
||||
width 96%
|
||||
left 0
|
||||
margin-left 2%
|
||||
margin-right 2%
|
||||
|
||||
.mess
|
||||
#writing
|
||||
max-width 40%
|
||||
line-height 1.2rem
|
||||
|
||||
.attr
|
||||
#stations
|
||||
#where
|
||||
width 20%
|
||||
min-width 20%
|
||||
|
||||
#audience
|
||||
#who
|
||||
width 60%
|
||||
|
||||
#writing
|
||||
padding .1rem
|
||||
|
||||
.m-down
|
||||
.m-up
|
||||
position absolute
|
||||
|
||||
.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
|
@ -1,7 +1,5 @@
|
||||
MessageDispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||
|
||||
# hm
|
||||
|
||||
module.exports =
|
||||
loadMessages: (grams,get) ->
|
||||
MessageDispatcher.handleServerAction
|
||||
@ -29,12 +27,11 @@ module.exports =
|
||||
type:"messages-fetch"
|
||||
window.chat.MessagePersistence.get station,start,end
|
||||
|
||||
sendMessage: (station,message,audience) ->
|
||||
sendMessage: (message,audience) ->
|
||||
serial = window.util.uuid32()
|
||||
|
||||
if station[0] isnt "~" then station = "~"+window.urb.ship+"/"+station
|
||||
|
||||
if audience.length is 0 then audience.push station
|
||||
audience.push window.util.mainStationPath window.urb.user
|
||||
audience = _.uniq audience
|
||||
|
||||
_audi = {}
|
||||
for k,v of audience
|
||||
@ -53,9 +50,13 @@ module.exports =
|
||||
bouquet:[]
|
||||
speech:
|
||||
lin:
|
||||
say:false
|
||||
say:true
|
||||
txt:message
|
||||
date: Date.now()
|
||||
|
||||
if message[0] is "@"
|
||||
_message.thought.statement.speech.lin.txt = _message.thought.statement.speech.lin.txt.slice(1).trim()
|
||||
_message.thought.statement.speech.lin.say = false
|
||||
|
||||
MessageDispatcher.handleViewAction
|
||||
type:"message-send"
|
||||
|
@ -17,6 +17,11 @@ module.exports =
|
||||
type:"station-set-audience"
|
||||
audience:audience
|
||||
|
||||
setValidAudience: (valid) ->
|
||||
StationDispatcher.handleViewAction
|
||||
type:"station-set-valid-audience"
|
||||
valid:valid
|
||||
|
||||
toggleAudience: (station) ->
|
||||
StationDispatcher.handleViewAction
|
||||
type:"station-audience-toggle"
|
||||
@ -53,11 +58,10 @@ module.exports =
|
||||
type:"stations-load"
|
||||
stations:stations
|
||||
|
||||
loadMembers: (station,members) ->
|
||||
loadMembers: (members) ->
|
||||
StationDispatcher.handleServerAction
|
||||
type:"members-load"
|
||||
members:members
|
||||
station:station
|
||||
|
||||
createStation: (station) ->
|
||||
StationDispatcher.handleViewAction
|
||||
|
@ -1,13 +1,13 @@
|
||||
moment = require 'moment-timezone'
|
||||
|
||||
recl = React.createClass
|
||||
[div,input,textarea] = [React.DOM.div,React.DOM.input,React.DOM.textarea]
|
||||
[div,br,input,textarea] = [React.DOM.div,React.DOM.br,React.DOM.input,React.DOM.textarea]
|
||||
|
||||
MessageStore = require '../stores/MessageStore.coffee'
|
||||
StationStore = require '../stores/StationStore.coffee'
|
||||
MessageActions = require '../actions/MessageActions.coffee'
|
||||
MessageStore = require '../stores/MessageStore.coffee'
|
||||
StationActions = require '../actions/StationActions.coffee'
|
||||
Member = require './MemberComponent.coffee'
|
||||
StationStore = require '../stores/StationStore.coffee'
|
||||
Member = require './MemberComponent.coffee'
|
||||
|
||||
Message = recl
|
||||
lz: (n) -> if n<10 then "0#{n}" else "#{n}"
|
||||
@ -19,24 +19,31 @@ Message = recl
|
||||
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().slice(1)
|
||||
@props._handlePm user
|
||||
|
||||
render: ->
|
||||
# pendingClass = if @props.pending isnt "received" then "pending" else ""
|
||||
delivery = _.uniq _.pluck @props.thought.audience, "delivery"
|
||||
pendingClass = if delivery.indexOf("received") isnt -1 then "received" else "pending"
|
||||
|
||||
if pendingClass is "pending"
|
||||
console.log @props.thought
|
||||
console.log delivery
|
||||
klass = if delivery.indexOf("received") isnt -1 then " received" else " pending"
|
||||
if @props.thought.statement.speech.lin.say is false then klass += " say"
|
||||
|
||||
name = if @props.name then @props.name else ""
|
||||
audi = _.remove _.keys(@props.thought.audience), (stat) =>
|
||||
stat isnt "~"+window.urb.ship+"/"+@props.station
|
||||
audi = audi.join " "
|
||||
audi = _.keys @props.thought.audience
|
||||
audi = _.without audi,window.util.mainStationPath window.urb.user
|
||||
audi = window.util.clipAudi audi
|
||||
audi = audi.map (_audi) -> (div {}, _audi)
|
||||
|
||||
div {className:"message "+pendingClass}, [
|
||||
div {className:"message #{klass}"}, [
|
||||
(div {className:"attr"}, [
|
||||
(Member {ship:@props.ship}, "")
|
||||
div {className:"audi"}, "#{audi}"
|
||||
div {onClick:@_handleAudi,className:"audi"}, audi
|
||||
(div {onClick:@_handlePm}, (Member {ship:@props.ship}, ""))
|
||||
div {className:"time"}, @convTime @props.thought.statement.date
|
||||
])
|
||||
div {className:"mess"}, @props.thought.statement.speech.lin.txt
|
||||
@ -51,7 +58,7 @@ module.exports = recl
|
||||
last:MessageStore.getLast()
|
||||
fetching:MessageStore.getFetching()
|
||||
listening:MessageStore.getListening()
|
||||
station:StationStore.getStation()
|
||||
station:window.util.mainStation()
|
||||
stations:StationStore.getStations()
|
||||
configs:StationStore.getConfigs()
|
||||
typing:MessageStore.getTyping()
|
||||
@ -78,7 +85,8 @@ module.exports = recl
|
||||
componentDidMount: ->
|
||||
MessageStore.addChangeListener @_onChangeStore
|
||||
StationStore.addChangeListener @_onChangeStore
|
||||
if @state.station and @state.listening.indexOf(@state.station) is -1
|
||||
if @state.station and
|
||||
@state.listening.indexOf(@state.station) is -1
|
||||
MessageActions.listenStation @state.station
|
||||
checkMore = @checkMore
|
||||
$(window).on 'scroll', checkMore
|
||||
@ -101,14 +109,25 @@ module.exports = recl
|
||||
|
||||
_onChangeStore: -> @setState @stateFromStore()
|
||||
|
||||
_handlePm: (user) ->
|
||||
audi = [
|
||||
window.util.mainStationPath(user)
|
||||
window.util.mainStationPath(window.urb.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 = _.filter @state.messages, (_message) ->
|
||||
audience = _.keys(_message.thought.audience)
|
||||
_.intersection(sources,audience).length > 0
|
||||
_messages = @state.messages
|
||||
# _messages = _.filter @state.messages, (_message) ->
|
||||
# audience = _.keys(_message.thought.audience)
|
||||
# _.intersection(sources,audience).length > 0
|
||||
_messages = _.sortBy _messages, (_message) ->
|
||||
_message.pending = _message.thought.audience[station]
|
||||
_message.thought.statement.time
|
||||
@ -122,5 +141,7 @@ module.exports = recl
|
||||
|
||||
messages = _messages.map (_message) =>
|
||||
_message.station = @state.station
|
||||
_message._handlePm = @_handlePm
|
||||
_message._handleAudi = @_handleAudi
|
||||
Message _message, ""
|
||||
div {id: "messages"}, messages
|
@ -1,15 +0,0 @@
|
||||
recl = React.createClass
|
||||
[div,input,textarea] = [React.DOM.div,React.DOM.input,React.DOM.textarea]
|
||||
|
||||
StationComponent = require './StationComponent.coffee'
|
||||
MessagesComponent = require './MessagesComponent.coffee'
|
||||
WritingComponent = require './WritingComponent.coffee'
|
||||
|
||||
module.exports = recl
|
||||
render: ->
|
||||
div {id:"d"}, "asdf"
|
||||
# div {id:"d"}, [
|
||||
# (div {id:'station-container'}, (StationComponent {}, ""))
|
||||
# (div {id:'messages-container'}, (MessagesComponent {}, ""))
|
||||
# (div {id:'writing-container'}, (WritingComponent {}, ""))
|
||||
# ]
|
@ -15,7 +15,7 @@ module.exports = recl
|
||||
stateFromStore: -> {
|
||||
audi:StationStore.getAudience()
|
||||
members:StationStore.getMembers()
|
||||
station:StationStore.getStation()
|
||||
station:window.util.mainStation()
|
||||
stations:StationStore.getStations()
|
||||
configs:StationStore.getConfigs()
|
||||
typing:StationStore.getTyping()
|
||||
@ -35,10 +35,6 @@ module.exports = recl
|
||||
componentWillUnmount: ->
|
||||
StationStore.removeChangeListener @_onChangeStore
|
||||
|
||||
_toggleAudi: (e) ->
|
||||
$e = $(e.target).closest('.station')
|
||||
station = $e.find('.path').text()
|
||||
StationActions.toggleAudience station
|
||||
|
||||
_onChangeStore: ->
|
||||
@setState @stateFromStore()
|
||||
@ -51,51 +47,50 @@ module.exports = recl
|
||||
_sources.push v
|
||||
StationActions.setSources @state.station,_sources
|
||||
@$input.val('')
|
||||
@$input.blur()
|
||||
|
||||
_remove: (e) ->
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
_station = $(e.target).attr "data-station"
|
||||
_sources = _.clone @state.configs[@state.station].sources
|
||||
_sources.slice _sources.indexOf(_station),1
|
||||
_sources.splice _sources.indexOf(_station),1
|
||||
StationActions.setSources @state.station,_sources
|
||||
|
||||
render: ->
|
||||
parts = []
|
||||
members = []
|
||||
|
||||
if @state.station and @state.members[@state.station]
|
||||
members = _.map @state.members[@state.station], (state,member) ->
|
||||
Member {ship:member,presence:state.presence}
|
||||
if @state.station and @state.members
|
||||
members = _.map @state.members, (stations,member) ->
|
||||
audi = _.map stations,(presence,station) -> (div {className:"audi"}, station)
|
||||
(div {}, [audi,Member {ship:member}])
|
||||
else
|
||||
members = ""
|
||||
|
||||
sourceInput = [(input {className:"join",onKeyUp:@_keyUp,placeholder:"+"}, "")]
|
||||
sourceCtrl = div {className:"sour-ctrl"}, sourceInput
|
||||
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.push "twitter/hoontap"
|
||||
sources = _.map _sources,(source) =>
|
||||
toggleClass = "toggle "
|
||||
if @state.audi.indexOf(source) isnt -1 then toggleClass += "active"
|
||||
(div {className:"station",onClick:@_toggleAudi}, [
|
||||
(div {className:toggleClass})
|
||||
(div {className:"path"}, source),
|
||||
(div {className:"remove",onClick:_remove,"data-station":source},"×")
|
||||
(div {className:"station"}, [
|
||||
(div {className:"remove",onClick:_remove,"data-station":source},"×"),
|
||||
(div {className:"path"}, source)
|
||||
])
|
||||
|
||||
else
|
||||
sources = ""
|
||||
sources = ""
|
||||
|
||||
station = []
|
||||
station.push (a {className:"up",href:"\#/"}, [(div {className:"arow-up"}, "")])
|
||||
station.push (h1 {},@state.station)
|
||||
station.push (div {id:"members"},members)
|
||||
head = (div {id:"head"},
|
||||
[(div {id:"where"},["/talk",(div {className:"caret"},"")]),
|
||||
(div {id:"who"},[(div {className:"circle"},""),"~#{window.urb.user}"])
|
||||
]
|
||||
)
|
||||
|
||||
parts.push (div {id:"station-container"}, (div {id:"station-meta"},station))
|
||||
parts.push (div {id:"sources-container"}, [(div {class:"sources-list"},sources),sourceCtrl])
|
||||
parts.push head
|
||||
parts.push (div {id:"stations"}, [(h1 {}, "Sources"),(div {},sources),sourceCtrl])
|
||||
parts.push (div {id:"audience"}, (div {},[(h1 {}, "Audience"),(div {id:"members"},members)]))
|
||||
|
||||
div {id:"station"},parts
|
@ -7,15 +7,15 @@ StationActions = require '../actions/StationActions.coffee'
|
||||
module.exports = recl
|
||||
stateFromStore: -> {
|
||||
stations: StationStore.getStations()
|
||||
station: StationStore.getStation()
|
||||
station: "~zod/court"
|
||||
}
|
||||
|
||||
getInitialState: -> @stateFromStore()
|
||||
|
||||
componentDidMount: ->
|
||||
@$el = $(@getDOMNode())
|
||||
@$add = $('#stations .add')
|
||||
@$input = @$el.find('input')
|
||||
@$el = $ @getDOMNode()
|
||||
@$add = $ '#stations .add'
|
||||
@$input = @$el.find 'input'
|
||||
StationStore.addChangeListener @_onChangeStore
|
||||
|
||||
componentWillUnmount: ->
|
||||
|
@ -1,10 +1,11 @@
|
||||
recl = React.createClass
|
||||
[div,input,textarea] = [React.DOM.div,React.DOM.input,React.DOM.textarea]
|
||||
[div,br,input,textarea] = [React.DOM.div,React.DOM.br,React.DOM.input,React.DOM.textarea]
|
||||
|
||||
MessageActions = require '../actions/MessageActions.coffee'
|
||||
MessageStore = require '../stores/MessageStore.coffee'
|
||||
StationActions = require '../actions/StationActions.coffee'
|
||||
StationStore = require '../stores/StationStore.coffee'
|
||||
Member = require './MemberComponent.coffee'
|
||||
StationStore = require '../stores/StationStore.coffee'
|
||||
Member = require './MemberComponent.coffee'
|
||||
|
||||
module.exports = recl
|
||||
set: ->
|
||||
@ -13,12 +14,16 @@ module.exports = recl
|
||||
get: ->
|
||||
if window.localStorage then window.localStorage.getItem 'writing'
|
||||
|
||||
stateFromStore: -> {
|
||||
audi:StationStore.getAudience()
|
||||
members:StationStore.getMembers()
|
||||
typing:StationStore.getTyping()
|
||||
station:StationStore.getStation()
|
||||
}
|
||||
stateFromStore: ->
|
||||
s =
|
||||
audi:StationStore.getAudience()
|
||||
ludi:MessageStore.getLastAudience()
|
||||
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: -> @stateFromStore()
|
||||
|
||||
@ -35,13 +40,30 @@ module.exports = recl
|
||||
@typing true
|
||||
|
||||
sendMessage: ->
|
||||
MessageActions.sendMessage @state.station,@$writing.text(),@state.audi
|
||||
if @_validateAudi() is false
|
||||
$('#audi').focus()
|
||||
return
|
||||
if @state.audi.length is 0 and $('#audi').text().trim().length > 0
|
||||
audi = @state.ludi
|
||||
@_setAudi()
|
||||
else
|
||||
audi = @state.audi
|
||||
audi = window.util.expandAudi audi
|
||||
MessageActions.sendMessage @$writing.text().trim(),audi
|
||||
@$length.text "0/69"
|
||||
@$writing.text('')
|
||||
@set()
|
||||
@typing false
|
||||
|
||||
_keyDown: (e) ->
|
||||
_audiKeyDown: (e) ->
|
||||
if e.keyCode is 13
|
||||
e.preventDefault()
|
||||
setTimeout () ->
|
||||
$('#writing').focus()
|
||||
,0
|
||||
return false
|
||||
|
||||
_writingKeyDown: (e) ->
|
||||
if e.keyCode is 13
|
||||
e.preventDefault()
|
||||
@sendMessage()
|
||||
@ -67,6 +89,40 @@ module.exports = recl
|
||||
|
||||
_setFocus: -> @$writing.focus()
|
||||
|
||||
_validateAudiPart: (a) ->
|
||||
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
|
||||
if ship.length < 3
|
||||
return false
|
||||
return true
|
||||
|
||||
_validateAudi: ->
|
||||
v = $('#audi').text()
|
||||
v = v.trim()
|
||||
if v.length is 0
|
||||
return true
|
||||
v = v.split " "
|
||||
for a in v
|
||||
a = a.trim()
|
||||
valid = @_validateAudiPart(a)
|
||||
valid
|
||||
|
||||
_setAudi: ->
|
||||
valid = @_validateAudi()
|
||||
StationActions.setValidAudience valid
|
||||
if valid is true
|
||||
v = $('#audi').text()
|
||||
v = v.split " "
|
||||
v = window.util.expandAudi v
|
||||
StationActions.setAudience v
|
||||
|
||||
getTime: ->
|
||||
d = new Date()
|
||||
seconds = d.getSeconds()
|
||||
@ -85,6 +141,7 @@ module.exports = recl
|
||||
componentDidMount: ->
|
||||
window.util.sendMessage = @sendMessage
|
||||
StationStore.addChangeListener @_onChangeStore
|
||||
MessageStore.addChangeListener @_onChangeStore
|
||||
@$el = $ @getDOMNode()
|
||||
@$length = $('#length')
|
||||
@$writing = $('#writing')
|
||||
@ -108,11 +165,20 @@ module.exports = recl
|
||||
ship = if iden then iden.ship else user
|
||||
name = if iden then iden.name else ""
|
||||
|
||||
k = "writing"
|
||||
k+= " hidden" if not @state?.station
|
||||
audi = if @state.audi.length is 0 then @state.ludi else @state.audi
|
||||
audi = window.util.clipAudi audi
|
||||
|
||||
div {className:k,onClick:@_setFocus}, [
|
||||
k = "writing"
|
||||
|
||||
div {className:k}, [
|
||||
(div {className:"attr"}, [
|
||||
(div {
|
||||
id:"audi"
|
||||
className:"audi valid-#{@state.valid}"
|
||||
contentEditable:true
|
||||
onKeyDown: @_audiKeyDown
|
||||
onBlur:@_setAudi
|
||||
}, audi.join(" "))
|
||||
(Member iden, "")
|
||||
(div {className:"time"}, @getTime())
|
||||
])
|
||||
@ -123,7 +189,7 @@ module.exports = recl
|
||||
onBlur: @_blur
|
||||
onInput: @_input
|
||||
onPaste: @_input
|
||||
onKeyDown: @_keyDown
|
||||
onKeyDown: @_writingKeyDown
|
||||
onFocus: @cursorAtEnd
|
||||
}, "")
|
||||
div {id:"length"}, "0/69"
|
||||
|
@ -8,15 +8,33 @@ $(() ->
|
||||
window.chat.StationPersistence = require './persistence/StationPersistence.coffee'
|
||||
|
||||
window.util =
|
||||
mainStation: ->
|
||||
switch window.urb.user.length
|
||||
mainStations: ["court","floor","porch"]
|
||||
|
||||
mainStationPath: (user) -> "~#{user}/#{window.util.mainStation(user)}"
|
||||
|
||||
mainStation: (user) ->
|
||||
if not user then user = window.urb.user
|
||||
switch user.length
|
||||
when 3
|
||||
return "court"
|
||||
when 5
|
||||
when 6
|
||||
return "floor"
|
||||
when 13
|
||||
return "porch"
|
||||
|
||||
clipAudi: (audi) ->
|
||||
audi = audi.join " "
|
||||
for v in window.util.mainStations
|
||||
regx = new RegExp "/#{v}","g"
|
||||
audi = audi.replace regx,""
|
||||
audi.split " "
|
||||
|
||||
expandAudi: (audi) ->
|
||||
for k,v of audi
|
||||
if v.indexOf("/") is -1
|
||||
audi[k] = "#{v}/#{window.util.mainStation(v.slice(1))}"
|
||||
audi
|
||||
|
||||
create: (name) ->
|
||||
window.chat.StationPersistence.createStation name, (err,res) ->
|
||||
|
||||
@ -54,8 +72,7 @@ $(() ->
|
||||
send()
|
||||
|
||||
getScroll: ->
|
||||
@writingPosition = $('#messaging-container').outerHeight(true)+$('#messaging-container').offset().top-$(window).height()
|
||||
#@writingPosition = $('#writing-container').position().top-$(window).height()+$('#writing-container').outerHeight(true)
|
||||
@writingPosition = $('#c').outerHeight(true)+$('#c').offset().top-$(window).height()
|
||||
|
||||
setScroll: ->
|
||||
window.util.getScroll()
|
||||
@ -68,44 +85,93 @@ $(() ->
|
||||
$('body').addClass 'scrolling'
|
||||
else
|
||||
$('body').removeClass 'scrolling'
|
||||
|
||||
# checkScroll = ->
|
||||
# if $(window).scrollTop() > 20
|
||||
# $('#nav').addClass 'scrolling'
|
||||
# else
|
||||
# $('#nav').removeClass 'scrolling'
|
||||
# setInterval checkScroll, 500
|
||||
|
||||
so = {}
|
||||
so.ls = $(window).scrollTop()
|
||||
so.cs = $(window).scrollTop()
|
||||
so.w = null
|
||||
so.$n = $('#station-container')
|
||||
so.$d = $('#nav > div')
|
||||
so.nh = so.$n.outerHeight(true)
|
||||
setSo = ->
|
||||
so.$n = $('#station-container')
|
||||
so.w = $(window).width()
|
||||
setInterval setSo,200
|
||||
|
||||
$(window).on 'resize', (e) ->
|
||||
if so.w > 1170
|
||||
so.$n.removeClass 'm-up m-down m-fixed'
|
||||
|
||||
$(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
|
||||
|
||||
so.$d.removeClass 'focus'
|
||||
|
||||
if so.cs <= 0
|
||||
so.$n.removeClass 'm-up'
|
||||
so.$n.addClass 'm-down m-fixed'
|
||||
return
|
||||
|
||||
if so.$n.hasClass 'm-fixed' and
|
||||
so.w < 1024
|
||||
so.$n.css left:-1*$(window).scrollLeft()
|
||||
|
||||
if dy > 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
|
||||
if not so.$n.hasClass 'm-up'
|
||||
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
|
||||
|
||||
so.ls = so.cs
|
||||
|
||||
$(window).on 'scroll', window.util.checkScroll
|
||||
|
||||
window.chat.StationPersistence.listen()
|
||||
|
||||
StationComponent = require './components/StationComponent.coffee'
|
||||
StationsComponent = require './components/StationsComponent.coffee'
|
||||
MessagesComponent = require './components/MessagesComponent.coffee'
|
||||
WritingComponent = require './components/WritingComponent.coffee'
|
||||
|
||||
$c = $('#c')
|
||||
|
||||
clean = ->
|
||||
React.unmountComponentAtNode $('#stations-container')[0]
|
||||
React.unmountComponentAtNode $('#station-parts-container')[0]
|
||||
React.unmountComponentAtNode $('#writing-container')[0]
|
||||
React.unmountComponentAtNode $('#station-container')[0]
|
||||
React.unmountComponentAtNode $('#messages-container')[0]
|
||||
React.unmountComponentAtNode $('#writing-container')[0]
|
||||
|
||||
routes =
|
||||
'': ->
|
||||
clean()
|
||||
$c.html "<div id='stations-container'></div>"
|
||||
rend (StationsComponent {}, ""),$('#stations-container')[0]
|
||||
'/:station': (station) ->
|
||||
clean()
|
||||
StationActions.switchStation station
|
||||
$c.html ""
|
||||
$c.append("<div id='messaging-container'></div>")
|
||||
$d = $('#messaging-container')
|
||||
$d.append("<div id='messages-container'></div>")
|
||||
$d.append("<div id='writing-container'></div>")
|
||||
$d.append("<div id='station-parts-container'></div>")
|
||||
$c.append("<div id='scrolling'>BOTTOM</div>")
|
||||
rend (StationComponent {}, ""),$('#station-parts-container')[0]
|
||||
rend (MessagesComponent {}, ""),$('#messages-container')[0]
|
||||
rend (WritingComponent {}, ""),$('#writing-container')[0]
|
||||
|
||||
router = Router routes
|
||||
if not window.location.hash then window.location.hash = "/"
|
||||
router.init()
|
||||
$c.append "<div id='station-container'></div>"
|
||||
$c.append "<div id='messages-container'></div>"
|
||||
$c.append "<div id='writing-container'></div>"
|
||||
$c.append "<div id='scrolling'>BOTTOM</div>"
|
||||
rend (StationComponent {}, ""),$('#station-container')[0]
|
||||
rend (MessagesComponent {}, ""),$('#messages-container')[0]
|
||||
rend (WritingComponent {}, ""),$('#writing-container')[0]
|
||||
)
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,10 @@
|
||||
{
|
||||
"name": "urbit-radio",
|
||||
"version": "0.0.0",
|
||||
"repository": {
|
||||
"type":"git",
|
||||
"url":"https://github.com/urbit/urbit"
|
||||
},
|
||||
"description": "urbit radio frontend",
|
||||
"main": "main.js",
|
||||
"dependencies": {
|
||||
|
@ -3,7 +3,7 @@ MessageActions = require '../actions/MessageActions.coffee'
|
||||
module.exports =
|
||||
listenStation: (station,since) ->
|
||||
window.urb.subscribe {
|
||||
appl:"rodeo"
|
||||
appl:"radio"
|
||||
path:"/f/#{station}/#{since}"
|
||||
}, (err,res) ->
|
||||
console.log('m subscription updates')
|
||||
@ -15,7 +15,7 @@ module.exports =
|
||||
|
||||
get: (station,start,end) ->
|
||||
window.urb.subscribe {
|
||||
appl:"rodeo"
|
||||
appl:"radio"
|
||||
path:"/f/#{station}/#{end}/#{start}"
|
||||
}, (err,res) ->
|
||||
console.log 'get'
|
||||
@ -23,7 +23,7 @@ module.exports =
|
||||
if res.data?.grams?.tele
|
||||
MessageActions.loadMessages res.data.grams,true
|
||||
window.urb.unsubscribe {
|
||||
appl:"rodeo"
|
||||
appl:"radio"
|
||||
path:"/f/#{station}/#{end}/#{start}"
|
||||
}, (err,res) ->
|
||||
console.log 'done'
|
||||
@ -31,8 +31,8 @@ module.exports =
|
||||
|
||||
sendMessage: (message,cb) ->
|
||||
window.urb.send {
|
||||
appl:"rodeo"
|
||||
mark:"rodeo-command"
|
||||
appl:"radio"
|
||||
mark:"radio-command"
|
||||
data:
|
||||
publish: [
|
||||
message
|
||||
|
@ -3,8 +3,8 @@ StationActions = require '../actions/StationActions.coffee'
|
||||
module.exports =
|
||||
createStation: (name,cb) ->
|
||||
window.urb.send {
|
||||
appl:"rodeo"
|
||||
mark:"rodeo-command"
|
||||
appl:"radio"
|
||||
mark:"radio-command"
|
||||
data:
|
||||
design:
|
||||
party:name
|
||||
@ -16,8 +16,8 @@ module.exports =
|
||||
|
||||
removeStation: (name,cb) ->
|
||||
window.urb.send {
|
||||
appl:"rodeo"
|
||||
mark:"rodeo-command"
|
||||
appl:"radio"
|
||||
mark:"radio-command"
|
||||
data:
|
||||
design:
|
||||
party:name
|
||||
@ -26,8 +26,8 @@ module.exports =
|
||||
|
||||
setSources: (station,ship,sources) ->
|
||||
send =
|
||||
appl:"rodeo"
|
||||
mark:"rodeo-command"
|
||||
appl:"radio"
|
||||
mark:"radio-command"
|
||||
data:
|
||||
design:
|
||||
party:station
|
||||
@ -41,7 +41,7 @@ module.exports =
|
||||
|
||||
members: ->
|
||||
window.urb.subscribe {
|
||||
appl:"rodeo"
|
||||
appl:"radio"
|
||||
path:"/a/court"
|
||||
}, (err,res) ->
|
||||
console.log 'membership updates'
|
||||
@ -51,7 +51,7 @@ module.exports =
|
||||
|
||||
listen: ->
|
||||
window.urb.subscribe {
|
||||
appl:"rodeo"
|
||||
appl:"radio"
|
||||
path:"/"
|
||||
}, (err,res) ->
|
||||
console.log 'house updates'
|
||||
@ -61,14 +61,15 @@ module.exports =
|
||||
|
||||
listenStation: (station) ->
|
||||
window.urb.subscribe {
|
||||
appl:"rodeo"
|
||||
appl:"radio"
|
||||
path:"/ax/#{station}"
|
||||
}, (err,res) ->
|
||||
console.log('station subscription updates')
|
||||
console.log(res.data)
|
||||
if res.data.ok is true
|
||||
StationActions.listeningStation station
|
||||
if res.data.group?.local
|
||||
StationActions.loadMembers station,res.data.group.local
|
||||
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.config
|
||||
StationActions.loadConfig station,res.data.config
|
@ -33,6 +33,11 @@ MessageStore = _.merge new EventEmitter,{
|
||||
|
||||
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) ->
|
||||
|
@ -1,14 +1,16 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
StationDispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||
|
||||
_audience = []
|
||||
_members = {}
|
||||
_stations = []
|
||||
_listening = []
|
||||
_station = null
|
||||
_config = {}
|
||||
_typing = {}
|
||||
_audience = []
|
||||
_members = {}
|
||||
_stations = []
|
||||
_listening = []
|
||||
_station = null
|
||||
_config = {}
|
||||
_typing = {}
|
||||
|
||||
_validAudience = true
|
||||
|
||||
StationStore = _.merge new EventEmitter,{
|
||||
removeChangeListener: (cb) -> @removeListener "change", cb
|
||||
@ -21,6 +23,10 @@ StationStore = _.merge new EventEmitter,{
|
||||
|
||||
setAudience: (audience) -> _audience = audience
|
||||
|
||||
getValidAudience: -> _validAudience
|
||||
|
||||
setValidAudience: (valid) -> _validAudience = valid
|
||||
|
||||
toggleAudience: (station) ->
|
||||
if _audience.indexOf(station) isnt -1
|
||||
_audience.splice _audience.indexOf(station), 1
|
||||
@ -35,14 +41,12 @@ StationStore = _.merge new EventEmitter,{
|
||||
|
||||
getMember: (ship) -> {ship:ship}
|
||||
|
||||
changeMember: (dir,name,ship) ->
|
||||
if dir is "out"
|
||||
_members = _.filter _members, (_member) ->
|
||||
return (_member.ship isnt ship)
|
||||
if dir is "in"
|
||||
_members.push {name:name, ship:ship}
|
||||
|
||||
loadMembers: (station,members) -> _members[station] = members
|
||||
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
|
||||
|
||||
@ -94,6 +98,10 @@ StationStore.dispatchToken = StationDispatcher.register (payload) ->
|
||||
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
|
||||
@ -103,7 +111,7 @@ StationStore.dispatchToken = StationDispatcher.register (payload) ->
|
||||
StationStore.setListening action.station
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "config-load"
|
||||
when "config-load" #[name:'loadConfig', args:['station', 'config']]
|
||||
StationStore.loadConfig action.station,action.config
|
||||
StationStore.emitChange()
|
||||
break
|
||||
@ -111,7 +119,10 @@ StationStore.dispatchToken = StationDispatcher.register (payload) ->
|
||||
StationStore.loadStations action.stations
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "stations-leave"
|
||||
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()
|
||||
@ -121,7 +132,7 @@ StationStore.dispatchToken = StationDispatcher.register (payload) ->
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "members-load"
|
||||
StationStore.loadMembers action.station,action.members
|
||||
StationStore.loadMembers action.members
|
||||
StationStore.emitChange()
|
||||
break
|
||||
when "typing-set"
|
||||
|
Loading…
Reference in New Issue
Block a user