Browse Source

Merge branch 'release-0.23'

pull/222/merge v0.23.7
Simon Eisenmann 11 years ago
parent
commit
eb0082751d
  1. 2
      .hound.yml
  2. 8
      README.md
  3. 16
      debian/changelog
  4. 2
      src/app/spreed-webrtc-server/channelling_api.go
  5. 3
      src/app/spreed-webrtc-server/client.go
  6. 6
      src/app/spreed-webrtc-server/connection.go
  7. 6
      src/app/spreed-webrtc-server/hub.go
  8. 10
      src/app/spreed-webrtc-server/incoming_codec.go
  9. 5
      src/app/spreed-webrtc-server/main.go
  10. 30
      src/styles/_shame.scss
  11. 6
      src/styles/bootstrap.scss
  12. 6
      src/styles/components/_audiolevel.scss
  13. 207
      src/styles/components/_audiovideo.scss
  14. 100
      src/styles/components/_bar.scss
  15. 134
      src/styles/components/_buddylist.scss
  16. 60
      src/styles/components/_buddypicturecapture.scss
  17. 53
      src/styles/components/_buddypictureupload.scss
  18. 193
      src/styles/components/_chat.scss
  19. 33
      src/styles/components/_contactsmanager.scss
  20. 26
      src/styles/components/_fileinfo.scss
  21. 80
      src/styles/components/_presentation.scss
  22. 3
      src/styles/components/_screenshare.scss
  23. 18
      src/styles/components/_settings.scss
  24. 5
      src/styles/components/_social.scss
  25. 22
      src/styles/components/_usability.scss
  26. 60
      src/styles/components/_youtubevideo.scss
  27. 2
      src/styles/csp.scss
  28. 6
      src/styles/font-awesome.scss
  29. 11
      src/styles/global/_animations.scss
  30. 9
      src/styles/global/_base.scss
  31. 21
      src/styles/global/_loader.scss
  32. 11
      src/styles/global/_nicescroll.scss
  33. 30
      src/styles/global/_overlaybar.scss
  34. 54
      src/styles/global/_pages.scss
  35. 64
      src/styles/global/_variables.scss
  36. 6
      src/styles/global/_views.scss
  37. 60
      src/styles/main.scss
  38. 3
      src/styles/scss.yml
  39. 2
      static/css/bootstrap.min.css
  40. 2
      static/css/font-awesome.min.css
  41. 4
      static/css/main.min.css
  42. 18
      static/js/controllers/mediastreamcontroller.js
  43. 9
      static/js/directives/audiovideo.js
  44. 16
      static/js/directives/chat.js
  45. 20
      static/js/directives/settings.js
  46. 89
      static/js/libs/sjcl.js
  47. 3
      static/js/main.js
  48. 45
      static/js/mediastream/connector.js
  49. 2
      static/js/mediastream/webrtc.js
  50. 2
      static/partials/chatroom.html
  51. 2
      static/partials/youtubevideo.html

2
.hound.yml

@ -5,4 +5,4 @@ java_script:
scss: scss:
enabled: true enabled: true
config_file: .scss.yml config_file: src/styles/scss.yml

8
README.md

@ -43,9 +43,11 @@ $ make
## Build seperately ## Build seperately
Get Go external dependencies first with ``make get``. There are several make targets available. Get Go external dependencies at
least once with ``make get``, all the other targets depend on this.
```bash ```bash
$ make get
$ make assets $ make assets
$ make binary $ make binary
``` ```
@ -121,8 +123,8 @@ Spreed WebRTC should be run through a SSL frontend proxy with
support for Websockets. Example configuration for Nginx can be support for Websockets. Example configuration for Nginx can be
found in `doc/NGINX.txt`. found in `doc/NGINX.txt`.
In addion for real work use one also needs a STUN/TURN server In addion for real world use, one also needs a STUN/TURN server
configured with shared secret support. configured (with shared secret support).
See https://code.google.com/p/rfc5766-turn-server/ for a free See https://code.google.com/p/rfc5766-turn-server/ for a free
open source TURN server implementation. Make sure to use a recent open source TURN server implementation. Make sure to use a recent

16
debian/changelog vendored

@ -1,3 +1,19 @@
spreed-webrtc-server (0.23.7) precise; urgency=low
* Updated SCSS to match coding style.
* Updated sjcl.js to 1.0.2.
* Fixed possible reconnect loop.
* TURN Ttl refresh timer is no longer lost when a room was joined.
* Fixed a possible dead lock when a hanging connection was replaced.
* Fixed authentication id logging.
* Avoid broken local video aspect ratio when camera changes aspect ratio while capturing (Mac OS).
* 1080p and 720p now can fail back to lower resolution when the camera fails to provide the requested resolution.
* Chat messages are now limited to 200k characters in web client.
* Channeling API now discards all incoming messages larger than 1MB.
* Video component now corretly exits from full screen in all cases.
-- Simon Eisenmann <simon@struktur.de> Thu, 05 Mar 2015 18:00:55 +0100
spreed-webrtc-server (0.23.6) precise; urgency=low spreed-webrtc-server (0.23.6) precise; urgency=low
* Fixed Youtube module. * Fixed Youtube module.

2
src/app/spreed-webrtc-server/channelling_api.go

@ -113,7 +113,7 @@ func (api *channellingAPI) OnIncoming(c ResponseSender, session *Session, msg *D
} }
if err := api.Authenticate(session, st, ""); err == nil { if err := api.Authenticate(session, st, ""); err == nil {
log.Println("Authentication success", session.Userid) log.Println("Authentication success", session.Userid())
api.SendSelf(c, session) api.SendSelf(c, session)
session.BroadcastStatus() session.BroadcastStatus()
} else { } else {

3
src/app/spreed-webrtc-server/client.go

@ -71,8 +71,7 @@ func (client *client) OnText(b Buffer) {
if incoming, err := client.DecodeIncoming(b); err == nil { if incoming, err := client.DecodeIncoming(b); err == nil {
client.OnIncoming(client, client.session, incoming) client.OnIncoming(client, client.session, incoming)
} else { } else {
log.Println("OnText error while decoding JSON", err) log.Println("OnText error while processing incoming message", err)
log.Printf("JSON:\n%s\n", b)
} }
} }

6
src/app/spreed-webrtc-server/connection.go

@ -104,8 +104,12 @@ func (c *connection) Close() {
c.mutex.Unlock() c.mutex.Unlock()
return return
} }
c.ws.Close()
c.isClosed = true c.isClosed = true
c.mutex.Unlock()
// Unlock while we close the websocket connection.
c.ws.Close()
// Lock again to clean up the queue and send out the signal.
c.mutex.Lock()
for { for {
head := c.queue.Front() head := c.queue.Front()
if head == nil { if head == nil {

6
src/app/spreed-webrtc-server/hub.go

@ -154,8 +154,12 @@ func (h *hub) OnConnect(client Client, session *Session) {
log.Printf("Created client %d with id %s\n", client.Index(), session.Id) log.Printf("Created client %d with id %s\n", client.Index(), session.Id)
// Register connection or replace existing one. // Register connection or replace existing one.
if ec, ok := h.clients[session.Id]; ok { if ec, ok := h.clients[session.Id]; ok {
log.Printf("Closing obsolete client %d with id %s\n", ec.Index(), session.Id) // Clean up old client at the end and make sure to run this in another go routine,
// to avoid blocking the new client if the old one hangs or whatever.
go func() {
log.Printf("Closing obsolete client %d (replaced with %d) with id %s\n", ec.Index(), client.Index(), session.Id)
ec.ReplaceAndClose() ec.ReplaceAndClose()
}()
} }
h.clients[session.Id] = client h.clients[session.Id] = client
h.mutex.Unlock() h.mutex.Unlock()

10
src/app/spreed-webrtc-server/incoming_codec.go

@ -24,6 +24,7 @@ package main
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"log" "log"
) )
@ -43,10 +44,11 @@ type Codec interface {
type incomingCodec struct { type incomingCodec struct {
buffers BufferCache buffers BufferCache
incomingLimit int
} }
func NewCodec() Codec { func NewCodec(incomingLimit int) Codec {
return &incomingCodec{NewBufferCache(1024, bytes.MinRead)} return &incomingCodec{NewBufferCache(1024, bytes.MinRead), incomingLimit}
} }
func (codec incomingCodec) NewBuffer() Buffer { func (codec incomingCodec) NewBuffer() Buffer {
@ -54,6 +56,10 @@ func (codec incomingCodec) NewBuffer() Buffer {
} }
func (codec incomingCodec) DecodeIncoming(b Buffer) (*DataIncoming, error) { func (codec incomingCodec) DecodeIncoming(b Buffer) (*DataIncoming, error) {
length := b.GetBuffer().Len()
if length > codec.incomingLimit {
return nil, errors.New("Incoming message size limit exceeded")
}
incoming := &DataIncoming{} incoming := &DataIncoming{}
return incoming, json.Unmarshal(b.Bytes(), incoming) return incoming, json.Unmarshal(b.Bytes(), incoming)
} }

5
src/app/spreed-webrtc-server/main.go

@ -280,6 +280,9 @@ func runner(runtime phoenix.Runtime) error {
log.Printf("Loaded extra templates from: %s", extraFolder) log.Printf("Loaded extra templates from: %s", extraFolder)
} }
// Define incoming channeling API limit it byte. Larger messages will be discarded.
incomingCodecLimit := 1024 * 1024 // 1MB
// Create realm string from config. // Create realm string from config.
computedRealm := fmt.Sprintf("%s.%s", serverRealm, config.Token) computedRealm := fmt.Sprintf("%s.%s", serverRealm, config.Token)
@ -336,7 +339,7 @@ func runner(runtime phoenix.Runtime) error {
// Add handlers. // Add handlers.
buddyImages := NewImageCache() buddyImages := NewImageCache()
codec := NewCodec() codec := NewCodec(incomingCodecLimit)
roomManager := NewRoomManager(config, codec) roomManager := NewRoomManager(config, codec)
hub := NewHub(config, sessionSecret, encryptionSecret, turnSecret, codec) hub := NewHub(config, sessionSecret, encryptionSecret, turnSecret, codec)
tickets := NewTickets(sessionSecret, encryptionSecret, computedRealm) tickets := NewTickets(sessionSecret, encryptionSecret, computedRealm)

30
src/styles/_shame.scss

@ -30,31 +30,37 @@
#toast-container > .toast { #toast-container > .toast {
background-image: none !important; background-image: none !important;
} }
#toast-container > .toast:before { #toast-container > .toast:before {
position: fixed; color: #fff;
float: left;
font-family: FontAwesome; font-family: FontAwesome;
font-size: 20px; font-size: 20px;
line-height: 20px; line-height: 20px;
float: left; margin: auto .5em auto -1.5em;
color: #fff; padding-right: .5em;
padding-right: 0.5em; position: fixed;
margin: auto 0.5em auto -1.5em;
} }
#toast-container > .toast-warning:before { #toast-container > .toast-warning:before {
content: "\f05a"; content: '\f05a';
} }
#toast-container > .toast-error:before { #toast-container > .toast-error:before {
content: "\f05a"; content: '\f05a';
} }
#toast-container > .toast-info:before { #toast-container > .toast-info:before {
content: "\f05a"; content: '\f05a';
} }
#toast-container > .toast-success:before { #toast-container > .toast-success:before {
content: "\f05a"; content: '\f05a';
} }
// No shadows for toastr. // No shadows for toastr.
#toast-container > :hover, #toast-container > div { #toast-container > :hover,
#toast-container > div {
box-shadow: none !important; box-shadow: none !important;
} }
@ -65,12 +71,12 @@
// Update position of toastr close icon. // Update position of toastr close icon.
.toast-close-button { .toast-close-button {
top: -0.6em;
font-size: 1em; font-size: 1em;
top: -.6em;
} }
// No opacity for toastr. // No opacity for toastr.
#toast-container > div { #toast-container > div {
opacity: 1;
filter: alpha(opacity=100); filter: alpha(opacity=100);
opacity: 1;
} }

6
src/styles/bootstrap.scss vendored

@ -1,4 +1,4 @@
@import "compass"; @import 'compass';
@import "global/variables"; @import 'global/variables';
@import "libs/bootstrap/bootstrap"; @import 'libs/bootstrap/bootstrap';

6
src/styles/components/_audiolevel.scss

@ -27,10 +27,12 @@
top: $audiolevel-top; top: $audiolevel-top;
width: 400px; width: 400px;
z-index: 60; z-index: 60;
.audio-level { .audio-level {
// scss-lint:disable DuplicateProperty
background: $audiovideolevel; /* Old browsers */ background: $audiovideolevel; /* Old browsers */
background: gradient(linear, left top, left bottom, color-stop(0%,$audiovideolevel), color-stop(50%,#a1d54f), color-stop(51%,#80c217), color-stop(100%,#7cbc0a)); /* Chrome,Safari4+ */ background: gradient(linear, left top, left bottom, color-stop(0%, $audiovideolevel), color-stop(50%, #a1d54f), color-stop(51%, #80c217), color-stop(100%, #7cbc0a)); /* Chrome,Safari4+ */
background: linear-gradient(to bottom, $audiovideolevel 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%); /* W3C */ background: linear-gradient(to bottom, $audiovideolevel 0%, #a1d54f 50%, #80c217 51%, #7cbc0a 100%); /* W3C */
border-radius: 0 0 2px 2px; border-radius: 0 0 2px 2px;
height: 4px; height: 4px;
left: 0; left: 0;

207
src/styles/components/_audiovideo.scss

@ -29,22 +29,24 @@
} }
#audiovideo { #audiovideo {
@include breakpt($breakpoint-video-small, max-width, only screen) {
right: 0;
}
&.fullscreen { &.fullscreen {
background: black !important;
bottom: 0 !important; bottom: 0 !important;
left: 0 !important; left: 0 !important;
top: 0 !important;
right: 0 !important; right: 0 !important;
top: 0 !important;
.remoteVideo .peerActions { .remoteVideo .peerActions {
display: none; display: none;
} }
} }
@include breakpt($breakpoint-video-small, max-width, only screen) {
right: 0;
}
} }
.mainScreenshare #audiovideo, .mainPresentation #audiovideo { .mainScreenshare #audiovideo,
.mainPresentation #audiovideo {
@include breakpt($breakpoint-video-medium, max-width, only screen) { @include breakpt($breakpoint-video-medium, max-width, only screen) {
display: none; display: none;
} }
@ -63,29 +65,35 @@
bottom: 0; bottom: 0;
left: 0; left: 0;
position: absolute; position: absolute;
top: 0;
right: 0; right: 0;
top: 0;
&.active { &.active {
perspective: 1000; perspective: 1000;
&:hover .overlayActions { &:hover .overlayActions {
opacity: .3; opacity: .3;
} }
.overlayActions:hover { .overlayActions:hover {
opacity: .6; opacity: .6;
} }
.audiovideoBase { .audiovideoBase {
transform: rotateY(180deg); transform: rotateY(180deg);
} }
} }
.audiovideoBase { .audiovideoBase {
position: relative;
width: 100%;
height: 100%; height: 100%;
transition-property: transform; position: relative;
transition-duration: 2s;
transform: rotateY(0deg); transform: rotateY(0deg);
transition-duration: 2s;
transition-property: transform;
width: 100%;
z-index: 2; z-index: 2;
} }
.localContainer { .localContainer {
bottom: 0; bottom: 0;
left: 0; left: 0;
@ -95,7 +103,9 @@
top: 0; top: 0;
transform: scale(-1, 1); transform: scale(-1, 1);
z-index: 2; z-index: 2;
overflow: hidden;
} }
video { video {
object-fit: cover; object-fit: cover;
} }
@ -112,36 +122,41 @@
transform: rotateY(180deg); transform: rotateY(180deg);
z-index: 2; z-index: 2;
} }
.miniContainer { .miniContainer {
background: #000;
bottom: 2px; bottom: 2px;
max-height: 18%;
height: 100%; height: 100%;
max-height: 18%;
opacity: 0; opacity: 0;
position: absolute; position: absolute;
right: 2px; right: 2px;
transform: scale(-1, 1); transform: scale(-1, 1);
transition-property: opacity;
transition-duration: .5s; transition-duration: .5s;
transition-property: opacity;
z-index: 25; z-index: 25;
background: black; overflow: hidden;
&.visible { &.visible {
opacity: 1; opacity: 1;
} }
} }
.miniVideo { .miniVideo {
display: block; display: block;
height: 100%;
max-height: 100%; max-height: 100%;
max-width: 100%; max-width: 100%;
height: 100%;
width: 100%; width: 100%;
} }
.localVideo { .localVideo {
background: $video-background; background: $video-background;
display: block; display: block;
max-height: 100%; max-height: 100%;
opacity: 0; opacity: 0;
transition-property: opacity;
transition-duration: 2s; transition-duration: 2s;
transition-property: opacity;
width: 100%; width: 100%;
} }
} }
@ -153,8 +168,9 @@
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
transition-property: opacity;
transition-duration: 2s; transition-duration: 2s;
transition-property: opacity;
video { video {
display: block; display: block;
height: 100%; height: 100%;
@ -162,7 +178,7 @@
} }
} }
.audiovideo .remoteVideo{ .audiovideo .remoteVideo {
background: $video-background; background: $video-background;
display: inline-block; display: inline-block;
max-height: 100%; max-height: 100%;
@ -172,13 +188,16 @@
vertical-align: bottom; vertical-align: bottom;
//visibility: hidden; //visibility: hidden;
width: 100%; width: 100%;
&.withvideo { &.withvideo {
//visibility: visible; //visibility: visible;
} }
&.onlyaudio { &.onlyaudio {
background: $video-onlyaudio-background; background: $video-onlyaudio-background;
//visibility: visible; //visibility: visible;
} }
.onlyaudio { .onlyaudio {
color: $video-onlyaudio; color: $video-onlyaudio;
display: none; display: none;
@ -191,15 +210,20 @@
text-align: center; text-align: center;
top: 45%; top: 45%;
} }
&.onlyaudio video, &.dummy video {
&.onlyaudio video,
&.dummy video {
visibility: hidden; visibility: hidden;
} }
&.onlyaudio .onlyaudio { &.onlyaudio .onlyaudio {
display: block; display: block;
} }
&.dummy .onlyaudio { &.dummy .onlyaudio {
display: block; display: block;
} }
.peerActions { .peerActions {
bottom: 5%; bottom: 5%;
left: 40px; left: 40px;
@ -208,28 +232,31 @@
position: absolute; position: absolute;
right: 40px; right: 40px;
text-align: center; text-align: center;
transition-property: opacity;
transition-duration: .2s; transition-duration: .2s;
transition-property: opacity;
z-index: 10; z-index: 10;
&:hover { &:hover {
opacity: .5; opacity: .5;
} }
i { i {
font-size: 3vw; font-size: 3vw;
} }
} }
.peerLabel { .peerLabel {
bottom: 4%; bottom: 4%;
color: white; color: #fff;
left: 4%;
font-size: 2.5vw; font-size: 2.5vw;
left: 4%;
max-width: 30%; max-width: 30%;
opacity: .7; opacity: .7;
overflow: hidden; overflow: hidden;
padding: 4px; padding: 4px;
position: absolute; position: absolute;
text-overflow: ellipsis; text-overflow: ellipsis;
text-shadow: 0 0 4px black; text-shadow: 0 0 4px #000;
white-space: nowrap; white-space: nowrap;
z-index: 8; z-index: 8;
} }
@ -240,51 +267,36 @@
bottom: 0; bottom: 0;
height: 140px; height: 140px;
left: 0; left: 0;
margin:auto 0; margin: auto 0;
opacity: 0; opacity: 0;
padding: 3px 0; padding: 3px 0;
position: absolute; position: absolute;
top: 0; top: 0;
width: 40px; width: 40px;
z-index: 5; z-index: 5;
button {
.btn {
color: #ccc; color: #ccc;
cursor: pointer; cursor: pointer;
display: block; display: block;
outline: 0; outline: 0;
text-shadow: 0 0 5px black; text-shadow: 0 0 5px #000;
width: 40px; width: 40px;
} }
button.renderer-auditorium {
position: relative;
span:before {
position:absolute;
left:50%;
top:50%;
margin-left: -0.8em;
margin-top: -0.5em;
content: "\f183";
}
span:after {
position:absolute;
top:50%;
right:50%;
margin-right: -0.9em;
margin-top: -0.5em;
content: "\f183";
}
}
} }
.remoteVideo { .remoteVideo {
&.talking .peerLabel { &.talking .peerLabel {
color: $audiovideolevel; color: $audiovideolevel;
} }
.peerLabel { .peerLabel {
transition: color 500ms ease-out; transition: color 500ms ease-out;
} }
.overlayLogo { .overlayLogo {
background: url(../img/logo-overlay.png) no-repeat center; background: url('../img/logo-overlay.png') no-repeat center;
background-size: 100%; background-size: 100%;
height: 20%; height: 20%;
max-height: 40px; max-height: 40px;
@ -301,35 +313,62 @@
.miniContainer { .miniContainer {
&.talking:after { &.talking:after {
content: ""; bottom: 2px;
position: absolute; box-shadow: 0 0 20px $audiovideolevel inset;
top: 2px; content: '';
left: 2px; left: 2px;
position: absolute;
right: 2px; right: 2px;
bottom: 2px; top: 2px;
box-shadow: 0px 0px 20px $audiovideolevel inset;
} }
video { video {
} }
} }
.renderer-auditorium {
position: relative;
span:before {
content: '\f183';
left: 50%;
margin-left: -.8em;
margin-top: -.5em;
position: absolute;
top: 50%;
}
span:after {
content: '\f183';
margin-right: -.9em;
margin-top: -.5em;
position: absolute;
right: 50%;
top: 50%;
}
}
.renderer-smally { .renderer-smally {
background: #000;
border-right: 0;
border-top: 0;
width: 150px; width: 150px;
background: black;
border-right: none;
border-top: none;
.remoteVideos { .remoteVideos {
padding-bottom: 85px; padding-bottom: 85px;
} }
.remoteVideo { .remoteVideo {
.peerLabel { .peerLabel {
font-size: .9em; font-size: .9em;
font-weight: bold; font-weight: bold;
} }
.peerActions i { .peerActions i {
font-size: 1em; font-size: 1em;
} }
} }
.miniContainer { .miniContainer {
bottom: 0; bottom: 0;
height: 85px; height: 85px;
@ -345,13 +384,13 @@
.renderer-democrazy { .renderer-democrazy {
.remoteVideos .miniContainer { .remoteVideos .miniContainer {
position: relative; bottom: auto;
display: inline-block;
max-height: 100%; max-height: 100%;
max-width: 100%; max-width: 100%;
display: inline-block; position: relative;
vertical-align: bottom;
bottom: auto;
right: auto; right: auto;
vertical-align: bottom;
} }
.active .miniContainer { .active .miniContainer {
@ -369,27 +408,33 @@
text-align: center; text-align: center;
top: auto; top: auto;
white-space: nowrap; white-space: nowrap;
> div { > div {
cursor: pointer; cursor: pointer;
height: 108px; height: 108px;
width: 192px; width: 192px;
} }
.overlayLogo { .overlayLogo {
display: none; display: none;
} }
.peerLabel, .peerLabel,
.peerActions i { .peerActions i {
font-size: 1.1em; font-size: 1.1em;
} }
.peerLabel { .peerLabel {
background: $video-overlayactions; background: $video-overlayactions;
} }
} }
.miniContainer { .miniContainer {
height: 108px; height: 108px;
max-height: none; max-height: none;
width: 192px; width: 192px;
} }
.bigVideo { .bigVideo {
bottom: 112px; bottom: 112px;
left: 0; left: 0;
@ -398,71 +443,83 @@
position: absolute; position: absolute;
right: 0; right: 0;
top: 2px; top: 2px;
transition-property: opacity;
transition-duration: 2s; transition-duration: 2s;
transition-property: opacity;
video { video {
width: 100%;
height: 100%; height: 100%;
width: 100%;
} }
} }
} }
.renderer-auditorium { .renderer-auditorium {
.remoteContainer { .remoteContainer {
border-left: 40px solid black; border-left: 40px solid #000;
} }
.remoteVideos { .remoteVideos {
background: $video-background;
pointer-events: auto;
top: 180px; top: 180px;
width: 320px; width: 320px;
pointer-events: auto;
background: $video-background;
.overlayLogo { .overlayLogo {
display: none; display: none;
} }
video { video {
height: 100%; height: 100%;
width: 100%;
object-fit: cover;
margin-top: -9px; margin-top: -9px;
object-fit: cover;
width: 100%;
} }
> div { > div {
cursor: pointer; cursor: pointer;
width: 80px;
height: 60px;
display: inline-block; display: inline-block;
height: 60px;
width: 80px;
} }
.overlayLogo { .overlayLogo {
display: none; display: none;
} }
.peerLabel { .peerLabel {
font-size: 0.6em;
background: $video-overlayactions; background: $video-overlayactions;
bottom: 0;
font-size: .6em;
left: 0;
line-height: 9px;
max-width: 100%; max-width: 100%;
bottom: 0px;
left: 0px;
right: 0px;
padding: 0 4px; padding: 0 4px;
line-height: 9px; right: 0;
} }
.peerActions { .peerActions {
display: none; display: none;
} }
.miniContainer { .miniContainer {
right: auto;
max-height: auto; max-height: auto;
right: auto;
} }
} }
.bigVideo { .bigVideo {
width: 320px;
height: 180px; height: 180px;
width: 320px;
video { video {
height: 100%; height: 100%;
width: 100%; width: 100%;
} }
.peerLabel { .peerLabel {
bottom: 8%;
font-size: 1vw; font-size: 1vw;
max-width: 40%; max-width: 40%;
bottom: 8%;
} }
} }
} }

100
src/styles/components/_bar.scss

@ -20,6 +20,7 @@
*/ */
.bar { .bar {
// scss-lint:disable PropertySpelling
background: $bar-background; background: $bar-background;
color: $componentfg1; color: $componentfg1;
font: bold 1em/50px $font-sans-serif; font: bold 1em/50px $font-sans-serif;
@ -31,50 +32,57 @@
.bar .left { .bar .left {
padding: 5px 5px 5px 15px; padding: 5px 5px 5px 15px;
@include breakpt($breakpoint-medium) {
padding: 2px 5px 0 11px;
padding: 2px 5px 0 11px;
}
.logo { .logo {
background: $logo no-repeat; background: $logo no-repeat;
background-size: 100%; background-size: 100%;
color: #000;
display: inline-block; display: inline-block;
color: black;
height: 32px;
width: 90px;
font: normal 11px/11px $font-sans-serif; font: normal 11px/11px $font-sans-serif;
height: 32px;
text-align: left; text-align: left;
vertical-align: middle; vertical-align: middle;
width: 90px;
@include breakpt($breakpoint-medium) {
background: $scalable-logo no-repeat center;
height: 46px;
width: 46px;
span {
display: none;
}
}
span { span {
font-style: italic; font-style: italic;
left: 38px; left: 38px;
position: relative; position: relative;
top: 26px; top: 26px;
} }
span a { span a {
color: $bar-logo-text-desc; color: $bar-logo-text-desc;
} }
@include breakpt($breakpoint-medium) {
background: $scalable-logo no-repeat center;
width: 46px;
height: 46px;
span {
display: none;
}
}
}
@include breakpt($breakpoint-medium) {
padding: 2px 5px 0px 11px;
} }
} }
.bar .middle { .bar .middle {
left: 0;
pointer-events: none;
position: absolute; position: absolute;
left: 0px;
right: 60px; right: 60px;
top: 0px;
pointer-events: none;
text-align: center; text-align: center;
top: 0;
> span { > span {
display: inline-block;
background: $bar-background; background: $bar-background;
display: inline-block;
min-height: 50px; min-height: 50px;
pointer-events: auto; pointer-events: auto;
} }
@ -82,9 +90,10 @@
.userpicture { .userpicture {
border-radius: 2px; border-radius: 2px;
display: inline-block; display: inline-block;
width: 46px;
height: 46px; height: 46px;
margin: -1px .5em 0 .5em; margin: -1px .5em 0;
width: 46px;
@include breakpt($breakpoint-medium) { @include breakpt($breakpoint-medium) {
display: none; display: none;
} }
@ -97,13 +106,15 @@
.status-reconnecting, .status-reconnecting,
.status-error, .status-error,
.status-ringing { .status-ringing {
@include breakpt($breakpoint-medium) { @include breakpt($breakpoint-medium) {
max-width: 100%;
left: 0; left: 0;
max-width: 100%;
position: absolute; position: absolute;
right: 0; right: 0;
} }
} }
.status-connecting .actions, .status-connecting .actions,
.status-closed .actions, .status-closed .actions,
.status-reconnecting .actions, .status-reconnecting .actions,
@ -113,64 +124,75 @@
} }
.bar .right { .bar .right {
padding-right: 4px;
margin-top: -1px; margin-top: -1px;
padding-right: 4px;
.badge { .badge {
background-color: $actioncolor1; background-color: $actioncolor1;
border: 1px solid white; border: 1px solid #fff;
font-size: .4em; font-size: .4em;
position: absolute; position: absolute;
right: 0; right: 0;
top: 2px; top: 2px;
} }
.btn { .btn {
background: $bar-btn-action-normal; background: $bar-btn-action-normal;
border-color: $bar-btn-action-normal-border; border-color: $bar-btn-action-normal-border;
color: $bar-btn-action-color; color: $bar-btn-action-color;
height: 42px;
font: 24px/40px $font-sans-serif; font: 24px/40px $font-sans-serif;
height: 42px;
margin-left: -2px; margin-left: -2px;
padding: 0; padding: 0;
position: relative;
text-align: center; text-align: center;
width: 42px; width: 42px;
position: relative;
&:focus { &:focus {
border: none; border: 0;
outline: none;
box-shadow: 0; box-shadow: 0;
outline: none;
} }
&:hover { &:hover {
background-color: transparent; background-color: transparent;
border-color: $bar-btn-action-border; border-color: $bar-btn-action-border;
color: $bar-btn-action-hover; color: $bar-btn-action-hover;
} }
&.active { &.active {
background-color: transparent; background-color: transparent;
border-color: $bordercolor; border-color: $bordercolor;
color: $bar-btn-action-hover; color: $bar-btn-action-hover;
} }
&.active.amutebtn { &.active.amutebtn {
background-color: $bar-btn-action-mute; background-color: $bar-btn-action-mute;
border-color: $bar-btn-action-mute; border-color: $bar-btn-action-mute;
color: white; color: #fff;
} }
&.active.aenablebtn { &.active.aenablebtn {
background-color: $bar-btn-action-enable; background-color: $bar-btn-action-enable;
border-color: $bar-btn-action-enable; border-color: $bar-btn-action-enable;
color: white; color: #fff;
} }
} }
.btn-mutemicrophone i:before { .btn-mutemicrophone i:before {
content: "\f130"; content: '\f130';
} }
.btn-mutemicrophone.active i:before { .btn-mutemicrophone.active i:before {
content: "\f131"; content: '\f131';
} }
.btn-mutecamera i:before { .btn-mutecamera i:before {
content: "\f06e"; content: '\f06e';
} }
.btn-mutecamera.active i:before { .btn-mutecamera.active i:before {
content: "\f070"; content: '\f070';
} }
} }
@ -178,8 +200,8 @@
@keyframes shakeityeah { @keyframes shakeityeah {
0% { transform: translate(2px, 1px) rotate(0deg); } 0% { transform: translate(2px, 1px) rotate(0deg); }
2% { transform: translate(-1px, -2px) rotate(-1deg); } 2% { transform: translate(-1px, -2px) rotate(-1deg); }
4% { transform: translate(-3px, 0px) rotate(1deg); } 4% { transform: translate(-3px, 0) rotate(1deg); }
8% { transform: translate(0px, 2px) rotate(0deg); } 8% { transform: translate(0, 2px) rotate(0deg); }
10% { transform: translate(1px, -1px) rotate(1deg); } 10% { transform: translate(1px, -1px) rotate(1deg); }
12% { transform: translate(-1px, 2px) rotate(-1deg); } 12% { transform: translate(-1px, 2px) rotate(-1deg); }
14% { transform: translate(-3px, 1px) rotate(0deg); } 14% { transform: translate(-3px, 1px) rotate(0deg); }
@ -187,13 +209,13 @@
18% { transform: translate(-1px, -1px) rotate(1deg); } 18% { transform: translate(-1px, -1px) rotate(1deg); }
20% { transform: translate(2px, 2px) rotate(0deg); } 20% { transform: translate(2px, 2px) rotate(0deg); }
22% { transform: translate(1px, -2px) rotate(-1deg); } 22% { transform: translate(1px, -2px) rotate(-1deg); }
24% { transform: translate(0px, 0px) rotate(0deg); } 24% { transform: translate(0, 0) rotate(0deg); }
} }
.btn-shakeityeah { .btn-shakeityeah {
animation-name: shakeityeah; animation-duration: 4s;
animation-duration: 4.0s;
transform-origin:50% 50%;
animation-iteration-count: infinite; animation-iteration-count: infinite;
animation-name: shakeityeah;
animation-timing-function: linear; animation-timing-function: linear;
transform-origin: 50% 50%;
} }

134
src/styles/components/_buddylist.scss

@ -30,14 +30,14 @@
#buddylist:before { #buddylist:before {
background: $buddylist-tab-background; background: $buddylist-tab-background;
border-bottom: 1px solid $bordercolor;
border-bottom-left-radius: 6px;
border-left: 1px solid $bordercolor; border-left: 1px solid $bordercolor;
border-top: 1px solid $bordercolor; border-top: 1px solid $bordercolor;
border-bottom: 1px solid $bordercolor;
border-top-left-radius: 6px; border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
bottom: 0; bottom: 0;
color: $buddylist-tab-color; color: $buddylist-tab-color;
content: "\f100"; content: '\f100';
cursor: pointer; cursor: pointer;
display: none; display: none;
font-family: FontAwesome; font-family: FontAwesome;
@ -46,18 +46,18 @@
left: 0; left: 0;
line-height: 55px; line-height: 55px;
margin: auto; margin: auto;
padding-right: 4px;
pointer-events: auto; pointer-events: auto;
position: absolute; position: absolute;
text-align: center; text-align: center;
top: 0; top: 0;
width: 26px; width: 26px;
z-index: 1; z-index: 1;
padding-right: 4px;
} }
.withBuddylist #buddylist:before { .withBuddylist #buddylist:before {
content: "\f101"; content: '\f101';
padding-right: 0px; padding-right: 0;
} }
.withBuddylistAutoHide #buddylist:before { .withBuddylistAutoHide #buddylist:before {
@ -81,19 +81,22 @@
.buddylist { .buddylist {
&.loading { &.loading {
.buddylistloading { .buddylistloading {
display:block; display: block;
} }
} }
&.empty { &.empty {
.buddylistempty { .buddylistempty {
display:block; display: block;
} }
} }
.buddycontainer { .buddycontainer {
pointer-events: auto; pointer-events: auto;
position: relative; position: relative;
user-select: none; user-select: none;
} }
.buddylistempty { .buddylistempty {
bottom: 0; bottom: 0;
color: $font-color-accent; color: $font-color-accent;
@ -102,12 +105,13 @@
height: 2em; height: 2em;
left: 0; left: 0;
margin: auto; margin: auto;
padding:.4em; padding: .4em;
position: absolute; position: absolute;
right: 0; right: 0;
text-align: center; text-align: center;
top: 0; top: 0;
} }
.buddylistloading { .buddylistloading {
bottom: 0; bottom: 0;
color: $font-color-accent; color: $font-color-accent;
@ -115,7 +119,7 @@
font-size: 1.4em; font-size: 1.4em;
height: 2em; height: 2em;
margin: auto; margin: auto;
padding:.4em; padding: .4em;
position: absolute; position: absolute;
right: 0; right: 0;
text-align: center; text-align: center;
@ -123,6 +127,8 @@
} }
.buddy { .buddy {
@include tap-highlight-color($tap-highlight);
background: $sidepanebg; background: $sidepanebg;
border-bottom: 1px solid $bordercolor; border-bottom: 1px solid $bordercolor;
cursor: pointer; cursor: pointer;
@ -133,7 +139,6 @@
position: relative; position: relative;
text-align: left; text-align: left;
width: 100%; width: 100%;
@include tap-highlight-color($tap-highlight);
} }
.buddy:hover { .buddy:hover {
@ -141,24 +146,32 @@
} }
.buddy { .buddy {
&.withSubline .buddy1, &.contact .buddy1 { &.withSubline .buddy1,
&.contact .buddy1 {
top: 15px; top: 15px;
} }
&.withSubline .buddy2, &.contact .buddy2 {
&.withSubline .buddy2,
&.contact .buddy2 {
display: block; display: block;
} }
&.hovered .buddyactions { &.hovered .buddyactions {
right: 0; right: 0;
} }
& .fa.contact:before {
content: "\f006"; .fa.contact:before {
content: '\f006';
} }
&.contact .fa.contact:before { &.contact .fa.contact:before {
content: "\f005"; content: '\f005';
} }
&.isself .fa.contact:before { &.isself .fa.contact:before {
content: "\f192"; content: '\f192';
} }
.buddyPicture { .buddyPicture {
background: $actioncolor1; background: $actioncolor1;
border-radius: 2px; border-radius: 2px;
@ -169,65 +182,72 @@
position: relative; position: relative;
text-align: center; text-align: center;
width: 46px; width: 46px;
.#{$fa-css-prefix} { .#{$fa-css-prefix} {
color: $actioncolor2; color: $actioncolor2;
line-height: 46px;
font-size: 3em; font-size: 3em;
line-height: 46px;
} }
img { img {
bottom: 0; bottom: 0;
display: block; display: block;
left: 0; left: 0;
max-height: 100%;
max-width: 100%;
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
max-height: 100%;
max-width: 100%;
} }
} }
.buddyPictureSmall { .buddyPictureSmall {
margin:0px; height: 30px;
margin-left:0px; margin: 0;
height:30px; margin-left: 0;
width:30px; margin-right: 0;
margin-right:0px; width: 30px;
.#{$fa-css-prefix} { .#{$fa-css-prefix} {
line-height: 30px;
font-size: 2em; font-size: 2em;
line-height: 30px;
} }
} }
.buddy1 { .buddy1 {
color: $buddylist-buddy1; color: $buddylist-buddy1;
font-weight: bold;
font-size: 14px; font-size: 14px;
font-weight: bold;
height: 28px; height: 28px;
left: 65px; left: 65px;
position: absolute;
overflow: hidden; overflow: hidden;
position: absolute;
right: 4px; right: 4px;
text-overflow: ellipsis; text-overflow: ellipsis;
top: 24px; top: 24px;
white-space: nowrap; white-space: nowrap;
} }
.buddy2 { .buddy2 {
color: $buddylist-buddy2; color: $buddylist-buddy2;
display: none;
left: 65px; left: 65px;
overflow: hidden; overflow: hidden;
position: absolute; position: absolute;
right: 0px; right: 0;
top: 33px; top: 33px;
white-space: nowrap; white-space: nowrap;
display: none;
} }
.buddy3 { .buddy3 {
display: inline-block;
overflow: hidden; overflow: hidden;
white-space: nowrap; padding: 0 6px;
text-align: left;
text-overflow: ellipsis; text-overflow: ellipsis;
text-align:left; vertical-align: middle;
vertical-align:middle; white-space: nowrap;
display: inline-block;
width: 120px; width: 120px;
padding: 0px 6px;
} }
} }
@ -235,58 +255,62 @@
background: $buddylist-action-background; background: $buddylist-action-background;
height: 66px; height: 66px;
line-height: 66px; line-height: 66px;
padding: 0 10px;
position: absolute; position: absolute;
right: -125px; right: -125px;
padding: 0 10px;
text-align: right; text-align: right;
top: 0px; top: 0;
transition-property: right;
transition-duration: .3s; transition-duration: .3s;
transition-property: right;
white-space: nowrap; white-space: nowrap;
z-index: 5; z-index: 5;
.btn { .btn {
width: 42px; font-size: $buddylist-action-font-size;
height: 40px; height: 40px;
padding: 0px; line-height: 40px;
padding: 0;
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
line-height: 40px; width: 42px;
font-size: $buddylist-action-font-size;
} }
} }
.buddy .buddysessions { .buddy .buddysessions {
margin-top: 56px;
max-height:0px;
margin-bottom: 10px; margin-bottom: 10px;
transition-property: max-height; margin-top: 56px;
transition-duration: .5s; max-height: 0;
transition-delay: .1s; transition-delay: .1s;
transition-duration: .5s;
transition-property: max-height;
ul { ul {
padding-top: 10px;
margin: 0 14px;
padding-left: 0px;
border-left: 1px dotted $bordercolor; border-left: 1px dotted $bordercolor;
border-right: 1px dotted $bordercolor; border-right: 1px dotted $bordercolor;
margin: 0 14px;
padding-left: 0;
padding-top: 10px;
} }
ul li { ul li {
margin-bottom: 2px;
margin-left: 0px;
list-style-type: none; list-style-type: none;
margin-bottom: 2px;
margin-left: 0;
.btn-group { .btn-group {
visibility: hidden; visibility: hidden;
} }
&:hover {
.btn-group { &:hover .btn-group {
visibility: visible; visibility: visible;
} }
} }
}
.currentsession .buddy3 { .currentsession .buddy3 {
font-weight: bold; font-weight: bold;
} }
} }
.buddy.hovered .buddysessions { .buddy.hovered .buddysessions {
max-height:999px; max-height: 999px;
} }

60
src/styles/components/_buddypicturecapture.scss

@ -24,76 +24,92 @@
display: block; display: block;
margin-bottom: 5px; margin-bottom: 5px;
} }
.videoPicture { .videoPicture {
margin-bottom: 4px; margin-bottom: 4px;
.videoPictureVideo { .videoPictureVideo {
background-color: black; background-color: #000;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
} }
video { video {
object-fit: cover; object-fit: cover;
} }
} }
.videoPictureVideo { .videoPictureVideo {
width: 200px;
height: 200px; height: 200px;
.videoPrev, video, .preview { width: 200px;
width: 100%;
.videoPrev,
video,
.preview {
height: 100%; height: 100%;
width: 100%;
} }
} }
.videoFlash { .videoFlash {
position: absolute; background-color: #fff;
left:0px;
right:0px;
top:0px;
bottom:0px;
background-color:white;
border: 1px dotted $bordercolor; border: 1px dotted $bordercolor;
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
visibility: hidden; visibility: hidden;
z-index: 5; z-index: 5;
} }
.videoFlash.flash { .videoFlash.flash {
visibility: visible; visibility: visible;
} }
.preview { .preview {
left: 0; left: 0;
position: absolute; position: absolute;
top: 0; top: 0;
&.previewPicture { &.previewPicture {
position: relative; position: relative;
} }
} }
.showTakePicture { .showTakePicture {
.btn { .btn {
} }
} }
.btn-takePicture, .btn-takePicture,
.btn-retakePicture { .btn-retakePicture {
left: 0px; left: 0;
right: 0px; margin: 0 auto;
max-width: 40%;
position: absolute; position: absolute;
right: 0;
top: 50%; top: 50%;
margin:0 auto;
max-width:40%;
} }
.btn-retakePicture { .btn-retakePicture {
visibility:hidden; visibility: hidden;
} }
.videoPictureVideo:hover .btn-retakePicture { .videoPictureVideo:hover .btn-retakePicture {
visibility:visible; visibility: visible;
} }
.countdownPicture { .countdownPicture {
color: $componentbg; color: $componentbg;
font-size: 45px; font-size: 45px;
left: 0px; left: 0;
right: 0px; margin: 0 auto;
opacity: .8;
position: absolute; position: absolute;
top: 75px; right: 0;
margin:0 auto;
text-align: center; text-align: center;
text-shadow: 0 0 5px black; text-shadow: 0 0 5px #000;
opacity:0.8; top: 75px;
} }
} }

53
src/styles/components/_buddypictureupload.scss

@ -21,79 +21,94 @@
.buddyPictureUpload { .buddyPictureUpload {
position: relative; position: relative;
.loader { .loader {
left: 90px;
position: absolute; position: absolute;
z-index: 1; z-index: 1;
left: 90px;
.fa-spin { .fa-spin {
color: $componentfg4; color: $componentfg4;
} }
} }
>p { >p {
white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
} }
.showUploadPicture { .showUploadPicture {
position: relative; background-color: $componentbg;
border: 1px solid $bordercolor; border: 1px solid $bordercolor;
height: 200px; height: 200px;
line-height: 200px; line-height: 200px;
margin-bottom: 10px; margin-bottom: 10px;
overflow: hidden; overflow: hidden;
position: relative;
text-align: center; text-align: center;
width: 200px;
background-color: $componentbg;
user-select: none; user-select: none;
width: 200px;
&.imgData { &.imgData {
background-color: black; background-color: #000;
.chooseUploadPicture {
display: none;
} }
&.imgData .chooseUploadPicture {
display: none;
} }
.chooseUploadPicture { .chooseUploadPicture {
color: $componentfg4; color: $componentfg4;
left: 0;
margin: 0 auto;
position: absolute; position: absolute;
right: 0;
z-index: 1; z-index: 1;
left: 0px;
right: 0px;
margin: 0 auto;
} }
.fa { .fa {
color: $componentbg; color: $componentbg;
text-shadow: 0 0 5px black; opacity: .8;
opacity: 0.8; text-shadow: 0 0 5px #000;
} }
} }
.preview { .preview {
left: 0;
position: relative; position: relative;
top: 0px; top: 0;
left: 0px;
} }
.imageUtilites { .imageUtilites {
line-height: 30px; line-height: 30px;
position: absolute; position: absolute;
visibility: hidden; visibility: hidden;
width: 200px; width: 200px;
z-index: 1; z-index: 1;
.fa { .fa {
cursor: pointer; cursor: pointer;
font-size: 40px; font-size: 40px;
width: 50px;
height: 50px; height: 50px;
width: 50px;
} }
} }
.showUploadPicture.imgData:hover .imageUtilites { .showUploadPicture.imgData:hover .imageUtilites {
visibility:visible; visibility: visible;
} }
.moveHorizontal { .moveHorizontal {
top: -4px;
position: relative; position: relative;
top: -4px;
} }
.moveVertical { .moveVertical {
position: absolute;
left: 158px; left: 158px;
position: absolute;
} }
.resize { .resize {
position: relative; position: relative;
top: 108px; top: 108px;

193
src/styles/components/_chat.scss

@ -20,25 +20,27 @@
*/ */
#chat { #chat {
bottom: 0;
min-width: $chat-width;
opacity: 0;
pointer-events: none; pointer-events: none;
position: absolute; position: absolute;
bottom: 0px;
right: $chat-width; right: $chat-width;
top: 0px; top: 0;
width: $chat-width; width: $chat-width;
min-width: $chat-width;
z-index: 45; z-index: 45;
opacity: 0;
} }
.withChat { .withChat {
#chat { #chat {
opacity: 1; opacity: 1;
} }
&.withChatMaximized #chat { &.withChatMaximized #chat {
left: 0; left: 0;
width: auto; width: auto;
} }
.chat { .chat {
pointer-events: auto; pointer-events: auto;
} }
@ -46,18 +48,19 @@
.chatcontainer { .chatcontainer {
background: $chat-background; background: $chat-background;
bottom: 0px; bottom: 0;
left: 0px; left: 0;
right: 0px;
top: 0px;
overflow: hidden; overflow: hidden;
position: absolute; position: absolute;
right: 0;
top: 0;
} }
.showchatlist { .showchatlist {
.chatpane { .chatpane {
right: 100%; right: 100%;
} }
.chatlist { .chatlist {
left: 0; left: 0;
} }
@ -70,42 +73,50 @@
position: absolute; position: absolute;
top: 0; top: 0;
width: 100%; width: 100%;
.list-group { .list-group {
margin-top: -1px;
margin-bottom: -1px; margin-bottom: -1px;
margin-top: -1px;
max-height: 100%; max-height: 100%;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
} }
.list-group-item { .list-group-item {
border-right: none; border-left: 0;
border-left: none;
border-radius: 0; border-radius: 0;
border-right: 0;
line-height: 26px;
min-height: 51px;
padding-right: 70px; padding-right: 70px;
position: relative; position: relative;
min-height: 51px;
line-height: 26px;
&.newmessage { &.newmessage {
animation: newmessage 1s ease -0.3s infinite; animation: newmessage 1s ease -.3s infinite;
} }
&.disabled { &.disabled {
color: $chat-disabled; color: $chat-disabled;
} }
&:hover button { &:hover button {
display: inline; display: inline;
} }
.fa-lg { .fa-lg {
display: inline-block; display: inline-block;
text-align: center; text-align: center;
width: 18px; width: 18px;
} }
.badge { .badge {
background: $chat-badge; background: $chat-badge;
border: 1px solid white; border: 1px solid #fff;
position: absolute; position: absolute;
right: 50px; right: 50px;
top: 14px; top: 14px;
} }
button { button {
display: none; display: none;
position: absolute; position: absolute;
@ -125,8 +136,8 @@
.chat { .chat {
background: $chat-background; background: $chat-background;
display: none;
bottom: 0; bottom: 0;
display: none;
left: 0; left: 0;
overflow: hidden; overflow: hidden;
position: absolute; position: absolute;
@ -139,9 +150,11 @@
&.visible { &.visible {
display: block; display: block;
} }
.chatbody { .chatbody {
// nothing // nothing
} }
.chatheader { .chatheader {
// nothing // nothing
} }
@ -149,12 +162,13 @@
} }
.chatmenu { .chatmenu {
position: absolute;
top: 36px;
left: 0px;
right: 0px;
height: 36px; height: 36px;
left: 0;
padding: 2px 4px; padding: 2px 4px;
position: absolute;
right: 0;
top: 36px;
@include breakpt($breakpoint-chat-small, max-height) { @include breakpt($breakpoint-chat-small, max-height) {
display: none; display: none;
} }
@ -167,9 +181,11 @@
position: absolute; position: absolute;
right: 0; right: 0;
top: 74px; top: 74px;
@include breakpt($breakpoint-chat-small, max-height) { @include breakpt($breakpoint-chat-small, max-height) {
border-top: 1px solid $bordercolor; border-top: 1px solid $bordercolor;
top: 0px; top: 0;
top: 0;
} }
} }
@ -184,6 +200,11 @@
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
@include breakpt($breakpoint-chat-small, max-height) {
display: none;
}
.chatstatusicon { .chatstatusicon {
cursor: pointer; cursor: pointer;
display: block; display: block;
@ -195,20 +216,24 @@
top: 0; top: 0;
width: 36px; width: 36px;
} }
.chatheadertitle { .chatheadertitle {
display: inline; display: inline;
padding-left: 28px; padding-left: 28px;
} }
.ctrl { .ctrl {
color: $chat-ctrl; color: $chat-ctrl;
position: absolute; position: absolute;
right: 1px; right: 1px;
top: 0; top: 0;
.#{$fa-css-prefix} { .#{$fa-css-prefix} {
cursor: pointer; cursor: pointer;
padding: 6px; padding: 6px;
} }
} }
span { span {
display: inline-block; display: inline-block;
max-width: 60%; max-width: 60%;
@ -218,9 +243,6 @@
vertical-align: middle; vertical-align: middle;
white-space: nowrap; white-space: nowrap;
} }
@include breakpt($breakpoint-chat-small, max-height) {
display: none;
}
} }
.chat .outputbox { .chat .outputbox {
@ -229,6 +251,7 @@
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
@include breakpt($breakpoint-chat-small, max-height) { @include breakpt($breakpoint-chat-small, max-height) {
bottom: 45px; bottom: 45px;
} }
@ -238,7 +261,8 @@
height: 100%; height: 100%;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
padding: 0.4em 0; padding: .4em 0;
> i { > i {
clear: both; clear: both;
color: $chat-meta; color: $chat-meta;
@ -246,6 +270,7 @@
font-size: .8em; font-size: .8em;
padding: 6px 0; padding: 6px 0;
text-align: center; text-align: center;
&.p2p { &.p2p {
font-weight: bold; font-weight: bold;
padding: 6px 0; padding: 6px 0;
@ -256,10 +281,12 @@
.chat.with_pictures .message { .chat.with_pictures .message {
&.is_self { &.is_self {
padding-right: 54px; padding-right: 54px;
.timestamp { .timestamp {
right: 58px; right: 58px;
} }
} }
&.is_remote { &.is_remote {
padding-left: 58px; padding-left: 58px;
} }
@ -269,23 +296,26 @@
background: $chat-msg-background; background: $chat-msg-background;
border: 1px solid $chat-msg-border; border: 1px solid $chat-msg-border;
border-radius: 6px; border-radius: 6px;
box-shadow: 0 0 2px 0 $chat-msg-shadow;
clear: both; clear: both;
display: block; display: block;
margin: 0 4px 2px 18px; margin: 0 4px 2px 18px;
padding: 8px; padding: 8px;
position: relative; position: relative;
word-wrap: break-word; word-wrap: break-word;
box-shadow: 0px 0px 2px 0px $chat-msg-shadow;
ul { ul {
list-style-type: none; list-style-type: none;
margin: 0; margin: 0;
padding-left: 0; padding-left: 0;
} }
li { li {
line-height: 1.1em; line-height: 1.1em;
margin: 4px 0; margin: 4px 0;
padding-left: 1.2em; padding-left: 1.2em;
position: relative; position: relative;
&:before { &:before {
color: $chat-msg-default-icon-color; color: $chat-msg-default-icon-color;
content: '\f075'; content: '\f075';
@ -296,6 +326,7 @@
width: 12px; width: 12px;
} }
} }
.timestamp { .timestamp {
color: $chat-timestamp; color: $chat-timestamp;
font-size: .8em; font-size: .8em;
@ -304,18 +335,20 @@
text-align: right; text-align: right;
top: 8px; top: 8px;
} }
.timestamp-space { .timestamp-space {
width:40px; float: right;
height:10px; height: 10px;
float:right; width: 40px;
} }
strong { strong {
display: block; display: block;
padding-bottom: 2px;
margin-right: 40px; margin-right: 40px;
white-space: nowrap;
overflow: hidden; overflow: hidden;
padding-bottom: 2px;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
} }
} }
@ -324,30 +357,36 @@
color: $chat-msg-default-icon-color; color: $chat-msg-default-icon-color;
transform: scale(-1, 1); transform: scale(-1, 1);
} }
li { li {
&.unread:before { &.unread:before {
content: $chat-msg-unread-icon;
color: $chat-msg-unread-icon-color; color: $chat-msg-unread-icon-color;
content: $chat-msg-unread-icon;
} }
&.sending:before { &.sending:before {
content: $chat-msg-sending-icon;
color: $chat-msg-sending-icon-color; color: $chat-msg-sending-icon-color;
content: $chat-msg-sending-icon;
} }
&.sent:before { &.sent:before {
content: $chat-msg-sent-icon;
color: $chat-msg-sent-icon-color; color: $chat-msg-sent-icon-color;
content: $chat-msg-sent-icon;
} }
&.delivered:before { &.delivered:before {
content: $chat-msg-delivered-icon;
color: $chat-msg-delivered-icon-color; color: $chat-msg-delivered-icon-color;
content: $chat-msg-delivered-icon;
} }
&.received:before { &.received:before {
content: $chat-msg-received-icon;
color: $chat-msg-received-icon-color; color: $chat-msg-received-icon-color;
content: $chat-msg-received-icon;
} }
&.read:before { &.read:before {
content: $chat-msg-read-icon;
color: $chat-msg-read-icon-color; color: $chat-msg-read-icon-color;
content: $chat-msg-read-icon;
} }
} }
} }
@ -357,6 +396,7 @@
left: auto; left: auto;
right: 4px; right: 4px;
} }
.buddyPicture { .buddyPicture {
background: $actioncolor1; background: $actioncolor1;
border-radius: 2px; border-radius: 2px;
@ -368,69 +408,79 @@
top: 4px; top: 4px;
width: 46px; width: 46px;
z-index: 0; z-index: 0;
.#{$fa-css-prefix} { .#{$fa-css-prefix} {
color: $actioncolor2; color: $actioncolor2;
line-height: 46px; line-height: 46px;
} }
img { img {
display: block;
bottom: 0; bottom: 0;
display: block;
left: 0; left: 0;
right: 0;
position: absolute;
top: 0;
max-height: 100%; max-height: 100%;
max-width: 100%; max-width: 100%;
position: absolute;
right: 0;
top: 0;
} }
} }
} }
.chat .message { .chat .message {
// scss-lint:disable DuplicateProperty
&:before, &:before,
&:after { &:after {
border-style: solid; border-style: solid;
content: ""; content: '';
display: block; display: block;
position: absolute; position: absolute;
width: 0; width: 0;
} }
&.is_remote { &.is_remote {
background: $chat-msg-remote-background; background: $chat-msg-remote-background;
&:before { // arrow border &:before { // arrow border
border-width: 7px 11px 7px 0;
border-color: transparent $chat-arrow-border; border-color: transparent $chat-arrow-border;
border-width: 7px 11px 7px 0;
bottom: auto; bottom: auto;
left: -12px; left: -12px;
top: 4px; top: 4px;
} }
&:after { // arrow background &:after { // arrow background
border-width: 6px 10px 6px 0;
border-color: transparent $chat-msg-remote-background; border-color: transparent $chat-msg-remote-background;
bottom:auto; border-width: 6px 10px 6px 0;
bottom: auto;
left: -11px; left: -11px;
top: 5px; top: 5px;
} }
} }
&.is_self { &.is_self {
background: $chat-msg-self-background; background: $chat-msg-self-background;
margin-right:18px;
margin-left: 4px; margin-left: 4px;
margin-right: 18px;
padding-right: 0; padding-right: 0;
&:before { // arrow border &:before { // arrow border
border-width: 7px 0 7px 11px;
border-color: transparent $chat-arrow-border; border-color: transparent $chat-arrow-border;
border-width: 7px 0 7px 11px;
bottom: 4px;
bottom: auto; bottom: auto;
right: -12px; right: -12px;
bottom: 4px;
} }
&:after { // arrow background &:after { // arrow background
border-width: 6px 0 6px 10px;
border-color: transparent $chat-msg-self-background; border-color: transparent $chat-msg-self-background;
border-width: 6px 0 6px 10px;
bottom: 5px;
bottom: auto; bottom: auto;
right: -11px; right: -11px;
bottom: 5px;
} }
} }
&.with_name { &.with_name {
// none // none
} }
@ -444,54 +494,64 @@
margin: 0 auto; margin: 0 auto;
position: absolute; position: absolute;
right: 0; right: 0;
@include breakpt($breakpoint-chat-small, max-height) { @include breakpt($breakpoint-chat-small, max-height) {
height: auto; height: auto;
} }
} }
.typinghint { .typinghint {
padding: 0 6px 0 6px;
white-space: nowrap;
overflow: hidden;
font-size:.8em;
color: $chat-typing; color: $chat-typing;
font-size: .8em;
height: 14px; height: 14px;
overflow: hidden;
padding: 0 6px;
white-space: nowrap;
@include breakpt($breakpoint-chat-small, max-height) { @include breakpt($breakpoint-chat-small, max-height) {
display: none; display: none;
} }
} }
.inputbox { .inputbox {
position: relative; position: relative;
@include breakpt($breakpoint-chat-small, max-height) {
height: auto;
}
.btn { .btn {
display: none;
padding: .5em 1em;
position: absolute; position: absolute;
right: 6px; right: 6px;
top: 1px; top: 1px;
padding: .5em 1em;
display: none;
} }
> div { > div {
border-top: 1px solid $bordercolor; border-top: 1px solid $bordercolor;
} }
@include breakpt($breakpoint-chat-small, max-height) {
height: auto;
}
} }
.input { .input {
border-radius: 0;
border-color: transparent; border-color: transparent;
border-radius: 0;
box-shadow: none; box-shadow: none;
display: block; display: block;
height: 54px; height: 54px;
max-height: 54px; /* FF hack */
margin: 0; margin: 0;
max-height: 54px; /* FF hack */
resize: none; resize: none;
width: 100%; width: 100%;
@include breakpt($breakpoint-chat-small, max-height) {
max-height: 2.5em;
}
&:active, &:active,
&:focus { &:focus {
border-color: $chat-input-border-color; border-color: $chat-input-border-color;
} }
@include breakpt($breakpoint-chat-small, max-height) {
max-height: 2.5em;
}
} }
} }
@ -503,12 +563,13 @@
.chat.newmessage { .chat.newmessage {
.chatheadertitle:after { .chatheadertitle:after {
content: "***"; content: '***';
position: absolute; position: absolute;
right: 32px; right: 32px;
top: 2px; top: 2px;
} }
.chatheader { .chatheader {
animation: newmessage 1s ease -0.3s infinite; animation: newmessage 1s ease -.3s infinite;
} }
} }

33
src/styles/components/_contactsmanager.scss

@ -25,52 +25,64 @@
font-weight: normal; font-weight: normal;
text-align: baseline; text-align: baseline;
} }
.addbtn { .addbtn {
font-size: 14px; font-size: 14px;
.fa-users { .fa-users {
font-size: 22px; font-size: 22px;
} }
.fa-plus { .fa-plus {
font-size: 15px; font-size: 15px;
} }
} }
.editpicture { .editpicture {
vertical-align: middle;
float: left; float: left;
margin-right: 20px; margin-right: 20px;
vertical-align: middle;
} }
.uploadbtn { .uploadbtn {
margin-top: 7px; margin-top: 7px;
} }
.editlist { .editlist {
max-height: 250px; max-height: 250px;
overflow-y: auto; overflow-y: auto;
} }
.picture { .picture {
display: table-cell;
border-bottom: 0; border-bottom: 0;
cursor: auto; cursor: auto;
display: table-cell;
min-height: 46px; min-height: 46px;
position: static; position: static;
width: auto; width: auto;
.buddyPicture { .buddyPicture {
margin: 0 0 0 10px; margin: 0 0 0 10px;
} }
} }
.table { .table {
margin-bottom: 0px; margin-bottom: 0;
tr:first-child td { tr:first-child td {
border-top: none; border-top: 0;
} }
.name { .name {
width: 40%;
text-align: left; text-align: left;
vertical-align: middle; vertical-align: middle;
width: 40%;
} }
.action { .action {
padding-right: 15px;
text-align: right; text-align: right;
vertical-align: middle; vertical-align: middle;
padding-right: 15px;
} }
} }
} }
@ -83,14 +95,15 @@
.search { .search {
&:before { &:before {
position: absolute; content: '\f002';
font-family: "fontAwesome"; font-family: 'fontAwesome';
content: "\f002";
font-size: 14px; font-size: 14px;
left: 22px;
opacity: .4; opacity: .4;
position: absolute;
top: 6px; top: 6px;
left: 22px;
} }
~ input { ~ input {
padding-left: 25px; padding-left: 25px;
} }

26
src/styles/components/_fileinfo.scss

@ -23,10 +23,10 @@
background: $fileinfo-background; background: $fileinfo-background;
border: 1px solid $fileinfo-border; border: 1px solid $fileinfo-border;
border-radius: 4px; border-radius: 4px;
max-width: 170px;
padding: 1em; padding: 1em;
position: relative; position: relative;
text-align: center; text-align: center;
max-width: 170px;
} }
.file-info { .file-info {
@ -34,19 +34,22 @@
position: relative; position: relative;
z-index: 3; z-index: 3;
} }
.file-info-bg { .file-info-bg {
bottom: 0; bottom: 0;
left: 41px; left: 41px;
right: 0;
overflow: hidden; overflow: hidden;
position: absolute; position: absolute;
right: 0;
top: -17px; top: -17px;
z-index: 2; z-index: 2;
.#{$fa-css-prefix} { .#{$fa-css-prefix} {
color: $fileinfo-icon-background-color; color: $fileinfo-icon-background-color;
font-size: 20em; font-size: 20em;
} }
} }
.actions { .actions {
left: 50%; left: 50%;
margin-left: 10px; margin-left: 10px;
@ -59,6 +62,7 @@
.is_remote .file-info { .is_remote .file-info {
background: $fileinfo-background-remote; background: $fileinfo-background-remote;
border: 1px solid $fileinfo-border-remote; border: 1px solid $fileinfo-border-remote;
.file-info-bg { .file-info-bg {
.#{$fa-css-prefix} { .#{$fa-css-prefix} {
color: $fileinfo-icon-background-color-remote; color: $fileinfo-icon-background-color-remote;
@ -78,17 +82,19 @@
font-size: .8em; font-size: .8em;
height: 20px; height: 20px;
position: relative; position: relative;
> span { > span {
display: block; display: block;
left: 0; left: 0;
margin: 0 auto; margin: 0 auto;
padding: 3px; padding: 3px;
position: absolute; position: absolute;
text-shadow: 1px 1px 1px white;
top: 0px;
right: 0; right: 0;
text-shadow: 1px 1px 1px #fff;
top: 0;
z-index: 5; z-index: 5;
} }
> div { > div {
bottom: 0; bottom: 0;
box-shadow: none !important; box-shadow: none !important;
@ -97,9 +103,11 @@
top: 0; top: 0;
width: 0; width: 0;
z-index: 0; z-index: 0;
&.progress-bar { &.progress-bar {
opacity: .5; opacity: .5;
} }
&.progress-bar.download { &.progress-bar.download {
opacity: 1; opacity: 1;
z-index: 1; z-index: 1;
@ -120,23 +128,28 @@
.file-info-speed { .file-info-speed {
bottom: 6px; bottom: 6px;
} }
.actions { .actions {
margin-left: 30px; margin-left: 30px;
opacity: 0; opacity: 0;
} }
.anim { .anim {
margin-left: 0; margin-left: 0;
} }
.hovercontrol { .hovercontrol {
&:hover .anim { &:hover .anim {
margin-left: -50px; margin-left: -50px;
} }
&:hover .actions { &:hover .actions {
margin-left: 0; margin-left: 0;
opacity: 1; opacity: 1;
} }
> div { > div {
transition: all .2s ease-in-out transition: all .2s ease-in-out;
} }
} }
} }
@ -145,13 +158,14 @@
.anim { .anim {
margin-left: -40px; margin-left: -40px;
} }
.file-info-size { .file-info-size {
margin-bottom: 10px; margin-bottom: 10px;
} }
} }
.file-info.downloading { .file-info.downloading {
.file-info-size{ .file-info-size {
border-color: $fileinfo-downloading-size-border; border-color: $fileinfo-downloading-size-border;
} }
} }

80
src/styles/components/_presentation.scss

@ -44,11 +44,11 @@
} }
.presentationpane .welcome .progress .download-info { .presentationpane .welcome .progress .download-info {
position: absolute; color: $text-color;
left: 0; left: 0;
position: absolute;
text-shadow: 1px 1px 1px #fff;
width: 100%; width: 100%;
color: $text-color;
text-shadow: 1px 1px 1px white;
} }
.mainPresentation #presentation { .mainPresentation #presentation {
@ -66,29 +66,35 @@
.presentationpane { .presentationpane {
.canvasContainer { .canvasContainer {
width: 100%;
height: 100%; height: 100%;
width: 100%;
} }
canvas { canvas {
position: relative;
display: block; display: block;
margin: 0 auto; margin: 0 auto;
position: relative;
} }
.odfcanvas { .odfcanvas {
user-select: none;
cursor: default; cursor: default;
user-select: none;
body { body {
background-color: transparent; background-color: transparent;
} }
document { document {
display: block; display: block;
} }
} }
.odfcontainer { .odfcontainer {
display: none; display: none;
padding: 0;
margin: 0; margin: 0;
padding: 0;
} }
.odfcontainer.showonepage { .odfcontainer.showonepage {
overflow: hidden; overflow: hidden;
text-align: center; text-align: center;
@ -106,25 +112,25 @@
max-width: 100%; max-width: 100%;
} }
.presentation .overlaybar a.overlaybar-button { .presentation .overlaybar .overlaybar-button {
position: absolute;
font-size: 20px; font-size: 20px;
padding: 4px 6px;
top: 0px;
line-height: 28px; line-height: 28px;
padding: 4px 6px;
position: absolute;
top: 0;
} }
.overlaybar-content .pagecontrol { .overlaybar-content .pagecontrol {
height: 30px; height: 30px;
} }
.presentation .overlaybar a.btn-prev { .presentation .overlaybar .btn-prev {
left: 40px; left: 40px;
} }
.presentation .overlaybar a.btn-next { .presentation .overlaybar .btn-next {
right: 0px;
left: auto; left: auto;
right: 0;
} }
.pageinfo input { .pageinfo input {
@ -133,15 +139,15 @@
} }
.presentation .thumbnail { .presentation .thumbnail {
text-shadow: none;
color: #333; color: #333;
margin-top: 20px;
width: 160px;
height: 122px;
display: inline-block; display: inline-block;
height: 122px;
margin-left: 20px; margin-left: 20px;
margin-top: 20px;
position: relative; position: relative;
text-shadow: none;
vertical-align: middle; vertical-align: middle;
width: 160px;
} }
.presentation .thumbnail.presentable { .presentation .thumbnail.presentable {
@ -153,9 +159,9 @@
} }
.presentation .thumbnail .caption { .presentation .thumbnail .caption {
overflow: hidden;
padding-bottom: 0; padding-bottom: 0;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden;
} }
.presentation .thumbnail .caption .size { .presentation .thumbnail .caption .size {
@ -167,39 +173,39 @@
} }
.presentation .thumbnail .caption .download-info { .presentation .thumbnail .caption .download-info {
position: absolute; bottom: 0;
color: $text-color;
left: 0; left: 0;
line-height: 20px;
position: absolute;
right: 0; right: 0;
text-shadow: 1px 1px 1px #fff;
top: 0; top: 0;
bottom: 0;
line-height: 20px;
text-shadow: 1px 1px 1px white;
color: $text-color;
} }
.presentation .thumbnail .active { .presentation .thumbnail .active {
font-size: 10em; bottom: 0;
color: #84b819; color: #84b819;
opacity: 0.7; font-size: 10em;
position: absolute;
left: 0; left: 0;
opacity: .7;
position: absolute;
right: 0; right: 0;
top: 0;
bottom: 0;
text-align: center; text-align: center;
top: 0;
} }
.presentation .thumbnail .notavailable { .presentation .thumbnail .notavailable {
bottom: 0;
color: #d2322d;
display: none; display: none;
font-size: 10em; font-size: 10em;
color: #d2322d;
opacity: 0.25;
position: absolute;
left: 0; left: 0;
opacity: .25;
position: absolute;
right: 0; right: 0;
top: 0;
bottom: 0;
text-align: center; text-align: center;
top: 0;
} }
.presentation .thumbnail:hover .notavailable { .presentation .thumbnail:hover .notavailable {
@ -207,9 +213,9 @@
} }
.presentation .thumbnail .presentation-action { .presentation .thumbnail .presentation-action {
display: none;
position: absolute; position: absolute;
top: 1px; top: 1px;
display: none;
} }
.presentation .thumbnail .download { .presentation .thumbnail .download {
@ -230,9 +236,9 @@
.presentations { .presentations {
height: 156px; height: 156px;
margin-left: -25px;
margin-right: 10px;
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
white-space: nowrap; white-space: nowrap;
margin-right: 10px;
margin-left: -25px;
} }

3
src/styles/components/_screenshare.scss

@ -32,7 +32,7 @@
} }
.screensharepane { .screensharepane {
background: black; background: #000;
bottom: 0; bottom: 0;
left: 0; left: 0;
overflow: auto; overflow: auto;
@ -45,6 +45,7 @@
.remotescreen { .remotescreen {
position: relative; position: relative;
} }
video { video {
max-height: 99%; max-height: 99%;
width: 100%; width: 100%;

18
src/styles/components/_settings.scss

@ -20,8 +20,8 @@
*/ */
#settings { #settings {
border-left: 1px solid $bordercolor;
background: $settings-background; background: $settings-background;
border-left: 1px solid $bordercolor;
bottom: 0; bottom: 0;
padding-right: 20px; padding-right: 20px;
position: fixed; position: fixed;
@ -34,12 +34,15 @@
#settings.show { #settings.show {
right: 0; right: 0;
@include breakpt($breakpoint-settings-medium, max-width, only screen) { @include breakpt($breakpoint-settings-medium, max-width, only screen) {
background: $settings-background; background: $settings-background;
left: 0; left: 0;
width: auto; width: auto;
} }
.form-actions{
.form-actions {
@include breakpt($breakpoint-settings-medium, max-width, only screen) { @include breakpt($breakpoint-settings-medium, max-width, only screen) {
bottom: 0; bottom: 0;
height: 60px; height: 60px;
@ -65,6 +68,10 @@
} }
.settings { .settings {
@include breakpt($breakpoint-settings-medium, max-width, only screen) {
padding-bottom: 10px;
}
.version { .version {
color: $settings-version; color: $settings-version;
font-size: 10px; font-size: 10px;
@ -72,12 +79,14 @@
right: 10px; right: 10px;
top: 10px; top: 10px;
} }
.form-horizontal { .form-horizontal {
.controls { .controls {
@include breakpt($breakpoint-settings-medium, max-width, only screen) { @include breakpt($breakpoint-settings-medium, max-width, only screen) {
margin-left: 110px; margin-left: 110px;
} }
} }
.control-label { .control-label {
@include breakpt($breakpoint-settings-medium, max-width, only screen) { @include breakpt($breakpoint-settings-medium, max-width, only screen) {
width: 100px; width: 100px;
@ -85,12 +94,9 @@
} }
} }
} }
@include breakpt($breakpoint-settings-medium, max-width, only screen) {
padding-bottom: 10px;
}
} }
settings-advanced { settings-advanced {
padding-top: 15px;
display: block; display: block;
padding-top: 15px;
} }

5
src/styles/components/_social.scss

@ -23,18 +23,23 @@
&.link { &.link {
color: $social-email-color; color: $social-email-color;
} }
&.email { &.email {
color: $social-email-color; color: $social-email-color;
} }
&.facebook { &.facebook {
color: $social-facebook-color; color: $social-facebook-color;
} }
&.google { &.google {
color: $social-google-color; color: $social-google-color;
} }
&.twitter { &.twitter {
color: $social-twitter-color; color: $social-twitter-color;
} }
&.xing { &.xing {
color: $social-xing-color; color: $social-xing-color;
} }

22
src/styles/components/_usability.scss

@ -27,9 +27,9 @@
margin: 0 auto; margin: 0 auto;
position: absolute; position: absolute;
right: 0; right: 0;
text-shadow: 0 0 5px black; text-shadow: 0 0 5px #000;
transition: right 200ms ease-in-out;
top: 80px; top: 80px;
transition: right 200ms ease-in-out;
user-select: none; user-select: none;
width: 350px; width: 350px;
} }
@ -45,20 +45,24 @@
} }
#help { #help {
@include breakpt($breakpoint-useability-small, max-width, only screen) {
display: none;
}
@include breakpt($breakpoint-useability-small, min-width, only screen, $breakpoint-useability-large) {
font-size: 1em;
width: 250px;
}
> div { > div {
margin: 0 10px; margin: 0 10px;
} }
.help-subline { .help-subline {
color: #888; color: #888;
padding: 20px 0; padding: 20px 0;
} }
@include breakpt($breakpoint-useability-small, max-width, only screen){
display: none;
}
@include breakpt($breakpoint-useability-small, min-width, only screen, $breakpoint-useability-large){
font-size: 1em;
width: 250px;
}
.btn { .btn {
text-shadow: none; text-shadow: none;
} }

60
src/styles/components/_youtubevideo.scss

@ -20,10 +20,10 @@
*/ */
.youtubevideo { .youtubevideo {
position: absolute; bottom: 0;
left: 0; left: 0;
position: absolute;
right: 0; right: 0;
bottom: 0;
top: 0; top: 0;
} }
@ -41,16 +41,17 @@
} }
#youtubeplayerinfo { #youtubeplayerinfo {
position: absolute;
left: 0;
right: 0;
bottom: 10%; bottom: 10%;
left: 0;
opacity: 0; opacity: 0;
pointer-events: auto; pointer-events: auto;
position: absolute;
right: 0;
text-align: center; text-align: center;
transition-property: opacity;
transition-duration: .2s; transition-duration: .2s;
transition-property: opacity;
z-index: 10; z-index: 10;
&:hover { &:hover {
opacity: .8; opacity: .8;
} }
@ -59,17 +60,17 @@
#youtubeplayerinfo div { #youtubeplayerinfo div {
background-color: #f9f2f4; background-color: #f9f2f4;
border-radius: 10px; border-radius: 10px;
padding: 20px 40px;
display: inline-block; display: inline-block;
font-size: 2em; font-size: 2em;
padding: 20px 40px;
} }
.youtubevideo .click-container { .youtubevideo .click-container {
position: absolute;
left: 0;
top: 0;
bottom: 0; bottom: 0;
left: 0;
position: absolute;
right: 0; right: 0;
top: 0;
z-index: 5; z-index: 5;
} }
@ -86,8 +87,8 @@
} }
.youtubevideo .welcome .welcome-logo { .youtubevideo .welcome .welcome-logo {
font-size: 10em;
background: transparent; background: transparent;
font-size: 10em;
} }
.mainYoutubevideo #youtubevideo { .mainYoutubevideo #youtubevideo {
@ -101,14 +102,14 @@
} }
.youtubevideo .overlaybar-content { .youtubevideo .overlaybar-content {
width: 100%;
max-width: 100%; max-width: 100%;
width: 100%;
} }
.youtubevideo .overlaybar-input { .youtubevideo .overlaybar-input {
padding-right: 15px;
position: relative; position: relative;
width: 100%; width: 100%;
padding-right: 15px;
} }
.youtubevideo .overlaybar-content form .overlaybar-buttons { .youtubevideo .overlaybar-content form .overlaybar-buttons {
@ -118,15 +119,16 @@
} }
.volumecontrol { .volumecontrol {
position: absolute; background: rgba(0, 0, 0, .6);
left: 0;
right: 0;
bottom: 0; bottom: 0;
left: 0;
opacity: 0; opacity: 0;
padding: 4px;
pointer-events: auto; pointer-events: auto;
position: absolute;
right: 0;
z-index: 10; z-index: 10;
background: rgba(0, 0, 0, 0.6);
padding: 4px;
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
@ -139,39 +141,39 @@
.volumebar { .volumebar {
display: inline-block; display: inline-block;
vertical-align: middle;
padding: 6px 8px; padding: 6px 8px;
vertical-align: middle;
} }
.volumebar input[type="range"] { .volumebar .bar {
-webkit-appearance: none; -webkit-appearance: none;
background-color: #aaa; background-color: #aaa;
border: 1px solid #aaa; border: 1px solid #aaa;
width: 100px;
height: 3px; height: 3px;
outline: 0; outline: 0;
width: 100px;
} }
.volumebar input[type="range"]::-webkit-slider-thumb { .volumebar .bar::-webkit-slider-thumb {
-webkit-appearance: none; -webkit-appearance: none;
background-color: #fff; background-color: #fff;
width: 6px;
height: 20px; height: 20px;
width: 6px;
} }
.volumebar input[type="range"]::-moz-range-track { .volumebar .bar::-moz-range-track {
background: #aaa; background: #aaa;
border: none; border: 0;
} }
.volumebar input[type="range"]::-moz-range-thumb { .volumebar .bar::-moz-range-thumb {
background-color: #fff; background-color: #fff;
width: 6px;
height: 20px;
border-radius: 0; border-radius: 0;
height: 20px;
width: 6px;
} }
.volumebar input[type="range"]::-moz-focusring{ .volumebar .bar::-moz-focusring {
outline: 1px solid #aaa; outline: 1px solid #aaa;
outline-offset: -1px; outline-offset: -1px;
} }

2
src/styles/csp.scss

@ -19,4 +19,4 @@
* *
*/ */
@import "libs/angular/angular-csp.scss"; @import 'libs/angular/angular-csp';

6
src/styles/font-awesome.scss vendored

@ -1,4 +1,4 @@
@import "compass"; @import 'compass';
@import "global/variables"; @import 'global/variables';
@import "libs/font-awesome/scss/font-awesome"; @import 'libs/font-awesome/scss/font-awesome';

11
src/styles/global/_animations.scss

@ -26,17 +26,20 @@
.animate-show { .animate-show {
&.ng-hide-add { &.ng-hide-add {
opacity: 1;
display: block !important; display: block !important;
transition: all linear 0.5s; opacity: 1;
transition: all linear .5s;
&.ng-hide-add-active { &.ng-hide-add-active {
opacity: 0; opacity: 0;
} }
} }
&.ng-hide-remove { &.ng-hide-remove {
opacity: 0;
display: block !important; display: block !important;
transition: all linear 0.5s; opacity: 0;
transition: all linear .5s;
&.ng-hide-remove-active { &.ng-hide-remove-active {
opacity: 1; opacity: 1;
} }

9
src/styles/global/_base.scss

@ -42,10 +42,11 @@ a {
background: $main-background; background: $main-background;
bottom: 0; bottom: 0;
left: 0; left: 0;
position:fixed; position: fixed;
right: 0; right: 0;
top: 0; top: 0;
z-index: 0; z-index: 0;
@include hidpi { @include hidpi {
background-image: $main-background-retina; background-image: $main-background-retina;
background-size: image-width($main-background-image-retina)/2 image-height($main-background-image-retina)/2; background-size: image-width($main-background-image-retina)/2 image-height($main-background-image-retina)/2;
@ -62,5 +63,9 @@ a {
} }
.desktopnotify-icon { .desktopnotify-icon {
background-image: url("../img/logo-48x48.png"); background-image: url('../img/logo-48x48.png');
}
:fullscreen {
background: #000;
} }

21
src/styles/global/_loader.scss

@ -24,34 +24,37 @@
background-size: contain; background-size: contain;
bottom: 15%; bottom: 15%;
left: 15%; left: 15%;
max-width: 200px;
max-height: 150px;
margin: auto; margin: auto;
max-height: 150px;
max-width: 200px;
opacity: 1; opacity: 1;
pointer-events: none; pointer-events: none;
position: fixed; position: fixed;
right: 15%; right: 15%;
top: 15%; top: 15%;
z-index: 20000;
transition-property: opacity;
transition-duration: .5s; transition-duration: .5s;
transition-property: opacity;
z-index: 20000;
&.done { &.done {
opacity: 0; opacity: 0;
} }
> div { > div {
bottom: 0;
color: $loading; color: $loading;
display: block; display: block;
font-size: 2em; font-size: 2em;
left: 0; left: 0;
margin: 0 auto; margin: 0 auto;
right: 0;
position: absolute;
bottom: 0px;
margin-bottom: -40px; margin-bottom: -40px;
position: absolute;
right: 0;
text-align: center; text-align: center;
text-shadow: 0 0 5px black; text-shadow: 0 0 5px #000;
} }
.loader-message { .loader-message {
font-size: 0.5em; font-size: .5em;
} }
} }

11
src/styles/global/_nicescroll.scss

@ -25,16 +25,19 @@
border: solid transparent; border: solid transparent;
height: 8px; height: 8px;
width: 8px; width: 8px;
&:hover { &:hover {
background-color: $background; background-color: $background;
border-left: 1px solid rgba(0,0,0,.12); border-left: 1px solid rgba(0, 0, 0, .12);
border-right: 1px solid rgba(0,0,0,.12); border-right: 1px solid rgba(0, 0, 0, .12);
} }
} }
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background: rgba(0,0,0,0.2); background: rgba(0, 0, 0, .2);
&:active { &:active {
background: rgba(0,0,0,0.4); background: rgba(0, 0, 0, .4);
} }
} }
} }

30
src/styles/global/_overlaybar.scss

@ -21,35 +21,41 @@
.overlaybar { .overlaybar {
background: $overlaybar-background; background: $overlaybar-background;
border-bottom: 1px solid #222;
border-top: 1px solid #222;
color: $overlaybar-color; color: $overlaybar-color;
min-height: 36px; min-height: 36px;
padding: 3px 8px 0 30px; padding: 3px 8px 0 30px;
position: absolute; position: absolute;
text-shadow: 0 0 5px black; text-shadow: 0 0 5px #000;
user-select: none; user-select: none;
vertical-align: middle; vertical-align: middle;
border-bottom: 1px solid #222;
border-top: 1px solid #222;
} }
.overlaybar { .overlaybar {
// scss-lint:disable QualifyingElement
&:hover { &:hover {
background: $componentfg2; background: $componentfg2;
} }
.btn { .btn {
text-shadow: none; text-shadow: none;
} }
.btn-link { .btn-link {
text-shadow: 0 0 5px black; text-shadow: 0 0 5px #000;
} }
.form-group > * { .form-group > * {
float: left; float: left;
padding-top: 0; padding-top: 0;
} }
input[type="radio"], input[type="radio"],
input[type="checkbox"] { input[type="checkbox"] {
margin-top: 2px; margin-top: 2px;
} }
label { label {
padding-top: 6px !important; padding-top: 6px !important;
} }
@ -58,44 +64,52 @@
.overlaybar { .overlaybar {
&.notvisible { &.notvisible {
background: transparent; background: transparent;
pointer-events: none;
border-bottom: 1px solid transparent; border-bottom: 1px solid transparent;
border-top: 1px solid transparent; border-top: 1px solid transparent;
pointer-events: none;
&:hover { &:hover {
background: transparent; background: transparent;
} }
.overlaybar-content { .overlaybar-content {
display: none; display: none;
} }
.overlaybar-overlay { .overlaybar-overlay {
display: block; display: block;
} }
} }
.overlaybar-button { .overlaybar-button {
color: $overlaybar-btn; color: $overlaybar-btn;
display: block; display: block;
font-size: 20px; font-size: 20px;
top: 0px;
left: 3px; left: 3px;
opacity: .7; opacity: .7;
padding: 4px 6px; padding: 4px 6px;
position: absolute;
pointer-events: auto; pointer-events: auto;
position: absolute;
top: 0;
vertical-align: middle; vertical-align: middle;
z-index: 15; z-index: 15;
} }
.overlaybar-content { .overlaybar-content {
display: inline-block; display: inline-block;
margin-left: .5em;
margin-bottom: 0; margin-bottom: 0;
margin-left: .5em;
max-width: 60%; max-width: 60%;
> * { > * {
padding-right: .5em; padding-right: .5em;
} }
.input-group { .input-group {
max-width: 160px; max-width: 160px;
} }
} }
.overlaybar-overlay { .overlaybar-overlay {
display: none; display: none;
margin-left: .5em; margin-left: .5em;

54
src/styles/global/_pages.scss

@ -28,25 +28,26 @@
} }
.welcome { .welcome {
color: $welcome; color: $welcome;
font-size: 1.1em; font-size: 1.1em;
margin-top: 80px; margin-top: 80px;
text-shadow: 0 0 5px black; max-width: 600px;
max-width:600px;
min-height: 160px; min-height: 160px;
padding-left:105px; padding-left: 105px;
padding-right: 0px; padding-right: 0;
position: relative; position: relative;
text-shadow: 0 0 5px #000;
@include breakpt($breakpoint-medium) { @include breakpt($breakpoint-medium) {
padding-left:10px;
padding-right:20px;
margin: 0 auto; margin: 0 auto;
padding-left: 10px;
padding-right: 20px;
} }
h1 { h1 {
margin-top: 0px; margin-top: 0;
white-space: nowrap; white-space: nowrap;
@include breakpt($breakpoint-medium) { @include breakpt($breakpoint-medium) {
white-space: normal; white-space: normal;
} }
@ -57,46 +58,50 @@
} }
.welcome-logo { .welcome-logo {
background: $scalable-logo no-repeat left top;
background-size: contain;
bottom: 0;
left: 0;
position: absolute; position: absolute;
left: 0px;
top: 1px; top: 1px;
bottom: 0px;
width: 90px; width: 90px;
background: $scalable-logo no-repeat left top;
background-size: contain;
@include breakpt($breakpoint-medium) { @include breakpt($breakpoint-medium) {
position: relative;
height: 70px; height: 70px;
width: 70px;
margin-top: 30px;
margin-bottom: 20px; margin-bottom: 20px;
margin-top: 30px;
position: relative;
width: 70px;
} }
} }
.welcome-input { .welcome-input {
position: relative; position: relative;
input { input {
padding-right: 105px; padding-right: 105px;
} }
} }
.welcome-input-buttons { .welcome-input-buttons {
text-shadow: none;
position: absolute; position: absolute;
top: 6px;
right: 8px; right: 8px;
text-shadow: none;
top: 6px;
a { a {
color: #000;
padding-right: .5em; padding-right: .5em;
color: black;
user-select: none; user-select: none;
} }
} }
.room-link { .room-link {
margin-top: -10px; margin-top: -10px;
white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
a { a {
color: $welcome; color: $welcome;
} }
@ -104,13 +109,16 @@
.rooms-history { .rooms-history {
margin-top: 3em; margin-top: 3em;
a { a {
&:hover {
text-decoration: none;
}
margin-right: .5em;
display: inline-block; display: inline-block;
margin-right: .5em;
} }
a:hover {
text-decoration: none;
}
} }
} }

64
src/styles/global/_variables.scss

@ -19,34 +19,34 @@
* *
*/ */
@import "compass/utilities/color/contrast"; @import 'compass/utilities/color/contrast';
// general // general
$background: #e5e5e5 !default; $background: #e5e5e5 !default;
$componentbg: #f8f8f8 !default; $componentbg: #f8f8f8 !default;
$componentfg1: #262626 !default; $componentfg1: #262626 !default;
$componentfg2: rgba(0,0,0,.5) !default; $componentfg2: rgba(0, 0, 0, .5) !default;
$componentfg3: rgba(0,0,0,.2) !default; $componentfg3: rgba(0, 0, 0, .2) !default;
$componentfg4: #737373 !default; $componentfg4: #737373 !default;
$sidepanebg: white !default; $sidepanebg: #fff !default;
$bordercolor: #e7e7e7 !default; $bordercolor: #e7e7e7 !default;
$actioncolor1: rgb(132,184,25) !default; $actioncolor1: rgb(132, 184, 25) !default;
$actioncolor2: rgb(0,149,52) !default; $actioncolor2: rgb(0, 149, 52) !default;
// branding // branding
$logo: url("../img/logo-small.png") !default; $logo: url('../img/logo-small.png') !default;
$scalable-logo: url("../img/logo.svg") !default; $scalable-logo: url('../img/logo.svg') !default;
$load-logo: $scalable-logo !default; $load-logo: $scalable-logo !default;
// background // background
$main-background-image: "../img/bg-tiles.jpg" !default; $main-background-image: '../img/bg-tiles.jpg' !default;
$main-background-image-retina: "../img/bg-tiles_x2.jpg" !default; $main-background-image-retina: '../img/bg-tiles_x2.jpg' !default;
$main-background: url($main-background-image) !default; $main-background: url($main-background-image) !default;
$main-background-retina: url($main-background-image-retina) !default; $main-background-retina: url($main-background-image-retina) !default;
// general action based colors // general action based colors
$action-hover: rgba(0,0,0,.4) !default; $action-hover: rgba(0, 0, 0, .4) !default;
$action-mute: rgb(219,79,57) !default; $action-mute: rgb(219, 79, 57) !default;
$action-enable: $actioncolor1 !default; $action-enable: $actioncolor1 !default;
// base // base
@ -57,7 +57,7 @@ $loading: #ddd !default;
$pane-width: 260px !default; $pane-width: 260px !default;
// font // font
$font-sans-serif: "Helvetica Neue",Helvetica,Arial,sans-serif !default; $font-sans-serif: 'Helvetica Neue', Helvetica, Arial, sans-serif !default;
$base-font-size: 13px; // compass vertical_rhythm mixin $base-font-size: 13px; // compass vertical_rhythm mixin
$base-line-height: 20px; // compass vertical_rhythm mixin $base-line-height: 20px; // compass vertical_rhythm mixin
$font-color: lighten(#000, 20%) !default; $font-color: lighten(#000, 20%) !default;
@ -72,7 +72,7 @@ $audiolevel-top: 43px !default;
// main navigation bar // main navigation bar
$minbarheight: 51px !default; $minbarheight: 51px !default;
$bar-background: $componentbg; $bar-background: $componentbg;
$bar-logo-text-desc: rgb(34,34,34) !default; $bar-logo-text-desc: rgb(34, 34, 34) !default;
$bar-btn-action-border: $bordercolor !default; $bar-btn-action-border: $bordercolor !default;
$bar-btn-action-color: #333 !default; $bar-btn-action-color: #333 !default;
$bar-btn-action-hover: #666 !default; $bar-btn-action-hover: #666 !default;
@ -87,20 +87,20 @@ $overlaybar-color: $bordercolor !default;
$overlaybar-btn: $bordercolor !default; $overlaybar-btn: $bordercolor !default;
// video // video
$video-background: rgba(0,0,0,.4) !default; $video-background: rgba(0, 0, 0, .4) !default;
$video-onlyaudio-background: #666 !default; $video-onlyaudio-background: #666 !default;
$video-onlyaudio: rgba(255,255,255,.3) !default; $video-onlyaudio: rgba(255, 255, 255, .3) !default;
$video-overlayactions: rgba(0,0,0,.9) !default; $video-overlayactions: rgba(0, 0, 0, .9) !default;
// settings // settings
$settings-background: white !default; $settings-background: #fff !default;
// buddylist // buddylist
$buddylist-width: $pane-width !default; $buddylist-width: $pane-width !default;
$buddylist-background: $componentbg !default; $buddylist-background: $componentbg !default;
$buddylist-tab-color: rgba(0,0,0,.3) !default; $buddylist-tab-color: rgba(0, 0, 0, .3) !default;
$buddylist-tab-background: $componentbg !default; $buddylist-tab-background: $componentbg !default;
$buddylist-action-background: rgba(255,255,255,0.5) !default; $buddylist-action-background: rgba(255, 255, 255, .5) !default;
$buddylist-buddy1: $componentfg1 !default; $buddylist-buddy1: $componentfg1 !default;
$buddylist-buddy2: $componentfg2 !default; $buddylist-buddy2: $componentfg2 !default;
$buddylist-action-font-size: 1.6em; $buddylist-action-font-size: 1.6em;
@ -108,22 +108,22 @@ $buddylist-action-font-size: 1.6em;
// chat // chat
$chat-width: $pane-width !default; $chat-width: $pane-width !default;
$chat-background: $componentbg !default; $chat-background: $componentbg !default;
$chat-header: rgba(255,255,255,0.9) !default; $chat-header: rgba(255, 255, 255, .9) !default;
$chat-disabled: #aaa !default; $chat-disabled: #aaa !default;
$chat-badge: #84b819 !default; $chat-badge: #84b819 !default;
$chat-ctrl: rgba(0,0,0,.3) !default; $chat-ctrl: rgba(0, 0, 0, .3) !default;
$chat-timestamp: #aaa !default; $chat-timestamp: #aaa !default;
$chat-meta: #aaa !default; $chat-meta: #aaa !default;
$chat-msg-background: white !default; $chat-msg-background: #fff !default;
$chat-msg-border: transparent !default; $chat-msg-border: transparent !default;
$chat-msg-shadow: rgba(0, 0, 0, 0.03) !default; $chat-msg-shadow: rgba(0, 0, 0, .03) !default;
$chat-arrow-border: #eee; $chat-arrow-border: #eee;
$chat-msg-default-icon-color: #ccc !default; $chat-msg-default-icon-color: #ccc !default;
$chat-msg-unread-icon-color: #FE9A2E !default; $chat-msg-unread-icon-color: #fe9a2e !default;
$chat-msg-sending-icon-color: $chat-msg-default-icon-color !default; $chat-msg-sending-icon-color: $chat-msg-default-icon-color !default;
$chat-msg-sent-icon-color: #5882FA !default; $chat-msg-sent-icon-color: #5882fa !default;
$chat-msg-delivered-icon-color: #5882FA !default; $chat-msg-delivered-icon-color: #5882fa !default;
$chat-msg-received-icon-color: #84b819 !default; $chat-msg-received-icon-color: #84b819 !default;
$chat-msg-read-icon-color: $chat-msg-default-icon-color !default; $chat-msg-read-icon-color: $chat-msg-default-icon-color !default;
@ -134,15 +134,15 @@ $chat-msg-delivered-icon: '\f019' !default;
$chat-msg-received-icon: '\f06e' !default; $chat-msg-received-icon: '\f06e' !default;
$chat-msg-read-icon: '\f00c' !default; $chat-msg-read-icon: '\f00c' !default;
$chat-msg-self-background: white !default; $chat-msg-self-background: #fff !default;
$chat-msg-remote-background: white !default; $chat-msg-remote-background: #fff !default;
$chat-bottom-background: $chat-background !default; $chat-bottom-background: $chat-background !default;
$chat-typing: $chat-meta !default; $chat-typing: $chat-meta !default;
$chat-input-border-color: #66afe9 !default; $chat-input-border-color: #66afe9 !default;
// fileinfo // fileinfo
$fileinfo-background: white !default; $fileinfo-background: #fff !default;
$fileinfo-border: #ddd !default; $fileinfo-border: #ddd !default;
$fileinfo-icon-background-color: #eee !default; $fileinfo-icon-background-color: #eee !default;
$fileinfo-downloading-size-border: #ddd !default; $fileinfo-downloading-size-border: #ddd !default;
@ -153,14 +153,14 @@ $fileinfo-icon-background-color-remote: $fileinfo-icon-background-color !default
// settings // settings
$settings-version: #ccc !default; $settings-version: #ccc !default;
$form-help-text: #737373 !default; $form-help-text: #737373 !default;
$settings-background: white !default; $settings-background: #fff !default;
// social // social
$social-email-color: #aaa !default; $social-email-color: #aaa !default;
$social-facebook-color: #45619d !default; $social-facebook-color: #45619d !default;
$social-google-color: #dd4b39 !default; $social-google-color: #dd4b39 !default;
$social-twitter-color: #00aced !default; $social-twitter-color: #00aced !default;
$social-xing-color: white !default; $social-xing-color: #fff !default;
// useability // useability
$breakpoint-useability-small: 400px !default; $breakpoint-useability-small: 400px !default;

6
src/styles/global/_views.scss

@ -22,12 +22,14 @@
.mainview { .mainview {
bottom: 0; bottom: 0;
display: none; display: none;
left: 0px; left: 0;
position: absolute; position: absolute;
right: 0; right: 0;
top: $minbarheight; top: $minbarheight;
@include breakpt($breakpoint-medium) { @include breakpt($breakpoint-medium) {
left: 0px; left: 0;
left: 0;
} }
} }

60
src/styles/main.scss

@ -20,37 +20,37 @@
*/ */
// must set custom compass variables before import of compass // must set custom compass variables before import of compass
@import "global/variables"; @import 'global/variables';
@import "compass"; @import 'compass';
@import "libs/libs"; @import 'libs/libs';
@import "global/mixins"; @import 'global/mixins';
@import "global/base"; @import 'global/base';
@import "global/loader"; @import 'global/loader';
@import "global/views"; @import 'global/views';
@import "global/pages"; @import 'global/pages';
@import "global/nicescroll"; @import 'global/nicescroll';
@import "global/animations"; @import 'global/animations';
@import "global/overlaybar"; @import 'global/overlaybar';
@import "global/withs"; @import 'global/withs';
@import "components/rightslide"; @import 'components/rightslide';
@import "components/bar"; @import 'components/bar';
@import "components/buddylist"; @import 'components/buddylist';
@import "components/buddypicturecapture"; @import 'components/buddypicturecapture';
@import "components/buddypictureupload"; @import 'components/buddypictureupload';
@import "components/settings"; @import 'components/settings';
@import "components/chat"; @import 'components/chat';
@import "components/usability"; @import 'components/usability';
@import "components/audiolevel"; @import 'components/audiolevel';
@import "components/fileinfo"; @import 'components/fileinfo';
@import "components/audiovideo"; @import 'components/audiovideo';
@import "components/screenshare"; @import 'components/screenshare';
@import "components/roombar"; @import 'components/roombar';
@import "components/social"; @import 'components/social';
@import "components/contactsmanager"; @import 'components/contactsmanager';
@import "components/presentation"; @import 'components/presentation';
@import "components/youtubevideo"; @import 'components/youtubevideo';
@import "shame"; @import 'shame';

3
src/styles/scss.yml

@ -118,8 +118,7 @@ linters:
max_depth: 3 max_depth: 3
SelectorFormat: SelectorFormat:
enabled: true enabled: false
convention: hyphenated_lowercase # or 'BEM', or 'hyphenated_BEM', or 'snake_case', or 'camel_case', or a regex pattern
Shorthand: Shorthand:
enabled: true enabled: true

2
static/css/bootstrap.min.css vendored

File diff suppressed because one or more lines are too long

2
static/css/font-awesome.min.css vendored

File diff suppressed because one or more lines are too long

4
static/css/main.min.css vendored

File diff suppressed because one or more lines are too long

18
static/js/controllers/mediastreamcontroller.js

@ -523,25 +523,25 @@ define(['jquery', 'underscore', 'angular', 'bigscreen', 'moment', 'sjcl', 'moder
} }
console.log("Stored data at the resurrection shrine", resurrect); console.log("Stored data at the resurrection shrine", resurrect);
} }
reconnecting = false; if (!reconnecting) {
_.delay(function() {
if (autoreconnect && !reconnecting) {
reconnecting = true; reconnecting = true;
_.delay(function() {
if (autoreconnect) {
console.log("Requesting to reconnect ..."); console.log("Requesting to reconnect ...");
mediaStream.reconnect(); mediaStream.reconnect();
} }
reconnecting = false;
}, 500); }, 500);
$scope.setStatus("reconnecting"); $scope.setStatus("reconnecting");
} else {
console.warn("Already reconnecting ...");
}
} else { } else {
$scope.setStatus("closed"); $scope.setStatus("closed");
} }
}; };
$scope.$on("room.joined", function(ev) { $scope.$on("room.joined", function(ev) {
// TODO(lcooper): Is it really needful to do this stuff?
$timeout.cancel(ttlTimeout);
connected = true;
reconnecting = false;
$scope.updateStatus(true); $scope.updateStatus(true);
}); });
@ -551,13 +551,11 @@ define(['jquery', 'underscore', 'angular', 'bigscreen', 'moment', 'sjcl', 'moder
switch (event.type) { switch (event.type) {
case "open": case "open":
connected = true; connected = true;
reconnecting = false;
$scope.updateStatus(true); $scope.updateStatus(true);
$scope.setStatus("waiting"); $scope.setStatus("waiting");
break; break;
case "error": case "error":
if (reconnecting || connected) { if (connected) {
reconnecting = false;
reconnect(); reconnect();
} else { } else {
$scope.setStatus(event.type); $scope.setStatus(event.type);

9
static/js/directives/audiovideo.js

@ -216,8 +216,13 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
$scope.toggleFullscreen = function() { $scope.toggleFullscreen = function() {
//console.log("Toggle full screen", BigScreen.enabled, $scope.isActive, $scope.hasUsermedia); //console.log("Toggle full screen", BigScreen.enabled, $scope.isActive, $scope.hasUsermedia);
if (BigScreen.enabled && ($scope.isActive || $scope.hasUsermedia)) { if (BigScreen.enabled && ($scope.isActive || $scope.hasUsermedia)) {
$scope.layoutparent.toggleClass("fullscreen"); BigScreen.toggle($scope.layoutparent[0], function() {
BigScreen.toggle($scope.layoutparent[0]); // onEnter
$scope.layoutparent.addClass("fullscreen");
}, function() {
// onExit
$scope.layoutparent.removeClass("fullscreen");
});
} }
}; };

16
static/js/directives/chat.js

@ -25,7 +25,8 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
return ["$compile", "safeDisplayName", "mediaStream", "safeApply", "desktopNotify", "translation", "playSound", "fileUpload", "randomGen", "buddyData", "appData", "$timeout", "geolocation", function($compile, safeDisplayName, mediaStream, safeApply, desktopNotify, translation, playSound, fileUpload, randomGen, buddyData, appData, $timeout, geolocation) { return ["$compile", "safeDisplayName", "mediaStream", "safeApply", "desktopNotify", "translation", "playSound", "fileUpload", "randomGen", "buddyData", "appData", "$timeout", "geolocation", function($compile, safeDisplayName, mediaStream, safeApply, desktopNotify, translation, playSound, fileUpload, randomGen, buddyData, appData, $timeout, geolocation) {
var displayName = safeDisplayName; var displayName = safeDisplayName;
var group_chat_id = ""; var groupChatId = "";
var maxMessageSize = 200000;
var controller = ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { var controller = ['$scope', '$element', '$attrs', function($scope, $element, $attrs) {
@ -35,13 +36,15 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
var ctrl = this; var ctrl = this;
var rooms = ctrl.rooms = {}; var rooms = ctrl.rooms = {};
ctrl.visibleRooms = []; ctrl.visibleRooms = [];
ctrl.group = group_chat_id; ctrl.group = groupChatId;
ctrl.get = function(id) { ctrl.get = function(id) {
return ctrl.rooms[id]; return ctrl.rooms[id];
} }
$scope.currentRoom = null; $scope.currentRoom = null;
$scope.currentRoomActive = false; $scope.currentRoomActive = false;
$scope.maxMessageSize = maxMessageSize;
$scope.getVisibleRooms = function() { $scope.getVisibleRooms = function() {
var res = []; var res = [];
for (var i = 0; i < ctrl.visibleRooms.length; i++) { for (var i = 0; i < ctrl.visibleRooms.length; i++) {
@ -133,7 +136,7 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
$scope.$parent.$on("startchat", function(event, id, options) { $scope.$parent.$on("startchat", function(event, id, options) {
//console.log("startchat requested", event, id); //console.log("startchat requested", event, id);
if (id === group_chat_id) { if (id === groupChatId) {
$scope.showGroupRoom(null, options); $scope.showGroupRoom(null, options);
} else { } else {
$scope.showRoom(id, { $scope.showRoom(id, {
@ -145,7 +148,7 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
$scope.$parent.$on("requestcontact", function(event, id, options) { $scope.$parent.$on("requestcontact", function(event, id, options) {
if (id !== group_chat_id) { if (id !== groupChatId) {
// Make sure the contact id is valid. // Make sure the contact id is valid.
var ad = appData.get(); var ad = appData.get();
if (!ad.userid) { if (!ad.userid) {
@ -245,6 +248,10 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
}; };
subscope.sendChat = function(to, message, status, mid, noloop) { subscope.sendChat = function(to, message, status, mid, noloop) {
//console.log("send chat", to, scope.peer); //console.log("send chat", to, scope.peer);
if (message && message.length > maxMessageSize) {
console.log("XXXXXXX", message.length);
return mid;
}
var peercall = mediaStream.webrtc.findTargetCall(to); var peercall = mediaStream.webrtc.findTargetCall(to);
if (peercall && peercall.peerconnection && peercall.peerconnection.datachannelReady) { if (peercall && peercall.peerconnection && peercall.peerconnection.datachannelReady) {
subscope.p2p(true); subscope.p2p(true);
@ -254,7 +261,6 @@ define(['jquery', 'underscore', 'text!partials/chat.html', 'text!partials/chatro
subscope.p2p(false); subscope.p2p(false);
return subscope.sendChatServer(to, message, status, mid, noloop); return subscope.sendChatServer(to, message, status, mid, noloop);
} }
return mid;
}; };
subscope.sendChatPeer2Peer = function(peercall, to, message, status, mid, noloop) { subscope.sendChatPeer2Peer = function(peercall, to, message, status, mid, noloop) {
if (message && !mid) { if (message && !mid) {

20
static/js/directives/settings.js

@ -37,11 +37,19 @@ define(['jquery', 'underscore', 'text!partials/settings.html'], function($, _, t
}, },
hd: { hd: {
minWidth: 1280, minWidth: 1280,
minHeight: 720 minHeight: 720,
mandatory: {
minWidth: 640,
minHeight: 360
}
}, },
fullhd: { fullhd: {
minWidth: 1920, minWidth: 1920,
minHeight: 1080 minHeight: 1080,
mandatory: {
minWidth: 1080,
minHeight: 720
}
} }
}; };
@ -238,10 +246,18 @@ define(['jquery', 'underscore', 'text!partials/settings.html'], function($, _, t
// Set video quality. // Set video quality.
var videoQuality = videoQualityMap[settings.videoQuality]; var videoQuality = videoQualityMap[settings.videoQuality];
if (videoQuality) { if (videoQuality) {
var mandatory = videoQuality.mandatory;
_.forEach(videoQuality, function(v, k) { _.forEach(videoQuality, function(v, k) {
if (k !== "mandatory") {
constraints.add("video", k, v, mandatory ? false : true);
}
});
if (mandatory) {
_.forEach(mandatory, function(v, k) {
constraints.add("video", k, v, true); constraints.add("video", k, v, true);
}); });
} }
}
// Set max frame rate if any was selected. // Set max frame rate if any was selected.
if (settings.maxFrameRate && settings.maxFrameRate != "auto") { if (settings.maxFrameRate && settings.maxFrameRate != "auto") {

89
static/js/libs/sjcl.js

@ -2,7 +2,6 @@
// ./configure --without-all --with-sha256 --with-sha512 --with-sha1 --with-hmac --with-codecBase64 --with-codecString --with-aes --with-ccm --with-convenience --compress=none // ./configure --without-all --with-sha256 --with-sha512 --with-sha1 --with-hmac --with-codecBase64 --with-codecString --with-aes --with-ccm --with-convenience --compress=none
// Copyright 2009-2010 Emily Stark, Mike Hamburg, Dan Boneh, Stanford University. // Copyright 2009-2010 Emily Stark, Mike Hamburg, Dan Boneh, Stanford University.
// SJCL is dual-licensed under the GNU GPL version 2.0 or higher, and a 2-clause BSD license. // SJCL is dual-licensed under the GNU GPL version 2.0 or higher, and a 2-clause BSD license.
/** @fileOverview Javascript cryptography implementation. /** @fileOverview Javascript cryptography implementation.
* *
* Crush to remove comments, shorten variable names and * Crush to remove comments, shorten variable names and
@ -76,6 +75,11 @@ var sjcl = {
if(typeof module !== 'undefined' && module.exports){ if(typeof module !== 'undefined' && module.exports){
module.exports = sjcl; module.exports = sjcl;
} }
if (typeof define === "function") {
define([], function () {
return sjcl;
});
}
/** @fileOverview Low-level AES implementation. /** @fileOverview Low-level AES implementation.
* *
* This file contains a low-level implementation of AES, optimized for * This file contains a low-level implementation of AES, optimized for
@ -360,7 +364,7 @@ sjcl.bitArray = {
return a1.concat(a2); return a1.concat(a2);
} }
var out, i, last = a1[a1.length-1], shift = sjcl.bitArray.getPartial(last); var last = a1[a1.length-1], shift = sjcl.bitArray.getPartial(last);
if (shift === 32) { if (shift === 32) {
return a1.concat(a2); return a1.concat(a2);
} else { } else {
@ -469,6 +473,20 @@ sjcl.bitArray = {
*/ */
_xor4: function(x,y) { _xor4: function(x,y) {
return [x[0]^y[0],x[1]^y[1],x[2]^y[2],x[3]^y[3]]; return [x[0]^y[0],x[1]^y[1],x[2]^y[2],x[3]^y[3]];
},
/** byteswap a word array inplace.
* (does not handle partial words)
* @param {sjcl.bitArray} a word array
* @return {sjcl.bitArray} byteswapped array
*/
byteswapM: function(a) {
var i, v, m = 0xff00;
for (i = 0; i < a.length; ++i) {
v = a[i];
a[i] = (v >>> 24) | ((v >>> 8) & m) | ((v & m) << 8) | (v << 24);
}
return a;
} }
}; };
/** @fileOverview Bit array codec implementations. /** @fileOverview Bit array codec implementations.
@ -1094,7 +1112,7 @@ sjcl.hash.sha512.prototype = {
t1h += chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0); t1h += chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0);
t1l += krl; t1l += krl;
t1h += krh + ((t1l >>> 0) < (krl >>> 0) ? 1 : 0); t1h += krh + ((t1l >>> 0) < (krl >>> 0) ? 1 : 0);
t1l += wrl; t1l = t1l + wrl|0; // FF32..FF34 perf issue https://bugzilla.mozilla.org/show_bug.cgi?id=1054972
t1h += wrh + ((t1l >>> 0) < (wrl >>> 0) ? 1 : 0); t1h += wrh + ((t1l >>> 0) < (wrl >>> 0) ? 1 : 0);
// t2 = sigma0 + maj // t2 = sigma0 + maj
@ -1281,8 +1299,7 @@ sjcl.hash.sha1.prototype = {
_block:function (words) { _block:function (words) {
var t, tmp, a, b, c, d, e, var t, tmp, a, b, c, d, e,
w = words.slice(0), w = words.slice(0),
h = this._h, h = this._h;
k = this._key;
a = h[0]; b = h[1]; c = h[2]; d = h[3]; e = h[4]; a = h[0]; b = h[1]; c = h[2]; d = h[3]; e = h[4];
@ -1333,7 +1350,7 @@ sjcl.mode.ccm = {
* @return {bitArray} The encrypted data, an array of bytes. * @return {bitArray} The encrypted data, an array of bytes.
*/ */
encrypt: function(prf, plaintext, iv, adata, tlen) { encrypt: function(prf, plaintext, iv, adata, tlen) {
var L, i, out = plaintext.slice(0), tag, w=sjcl.bitArray, ivl = w.bitLength(iv) / 8, ol = w.bitLength(out) / 8; var L, out = plaintext.slice(0), tag, w=sjcl.bitArray, ivl = w.bitLength(iv) / 8, ol = w.bitLength(out) / 8;
tlen = tlen || 64; tlen = tlen || 64;
adata = adata || []; adata = adata || [];
@ -1367,7 +1384,7 @@ sjcl.mode.ccm = {
decrypt: function(prf, ciphertext, iv, adata, tlen) { decrypt: function(prf, ciphertext, iv, adata, tlen) {
tlen = tlen || 64; tlen = tlen || 64;
adata = adata || []; adata = adata || [];
var L, i, var L,
w=sjcl.bitArray, w=sjcl.bitArray,
ivl = w.bitLength(iv) / 8, ivl = w.bitLength(iv) / 8,
ol = w.bitLength(ciphertext), ol = w.bitLength(ciphertext),
@ -1409,7 +1426,7 @@ sjcl.mode.ccm = {
*/ */
_computeTag: function(prf, plaintext, iv, adata, tlen, L) { _computeTag: function(prf, plaintext, iv, adata, tlen, L) {
// compute B[0] // compute B[0]
var q, mac, field = 0, offset = 24, tmp, i, macData = [], w=sjcl.bitArray, xor = w._xor4; var mac, tmp, i, macData = [], w=sjcl.bitArray, xor = w._xor4;
tlen /= 8; tlen /= 8;
@ -1469,7 +1486,7 @@ sjcl.mode.ccm = {
* @private * @private
*/ */
_ctrMode: function(prf, data, iv, tag, tlen, L) { _ctrMode: function(prf, data, iv, tag, tlen, L) {
var enc, i, w=sjcl.bitArray, xor = w._xor4, ctr, b, l = data.length, bl=w.bitLength(data); var enc, i, w=sjcl.bitArray, xor = w._xor4, ctr, l = data.length, bl=w.bitLength(data);
// start the ctr // start the ctr
ctr = w.concat([w.partial(8,L-1)],iv).concat([0,0,0]).slice(0,4); ctr = w.concat([w.partial(8,L-1)],iv).concat([0,0,0]).slice(0,4);
@ -1855,14 +1872,16 @@ sjcl.prng.prototype = {
loadTimeCollector: this._bind(this._loadTimeCollector), loadTimeCollector: this._bind(this._loadTimeCollector),
mouseCollector: this._bind(this._mouseCollector), mouseCollector: this._bind(this._mouseCollector),
keyboardCollector: this._bind(this._keyboardCollector), keyboardCollector: this._bind(this._keyboardCollector),
accelerometerCollector: this._bind(this._accelerometerCollector) accelerometerCollector: this._bind(this._accelerometerCollector),
} touchCollector: this._bind(this._touchCollector)
};
if (window.addEventListener) { if (window.addEventListener) {
window.addEventListener("load", this._eventListener.loadTimeCollector, false); window.addEventListener("load", this._eventListener.loadTimeCollector, false);
window.addEventListener("mousemove", this._eventListener.mouseCollector, false); window.addEventListener("mousemove", this._eventListener.mouseCollector, false);
window.addEventListener("keypress", this._eventListener.keyboardCollector, false); window.addEventListener("keypress", this._eventListener.keyboardCollector, false);
window.addEventListener("devicemotion", this._eventListener.accelerometerCollector, false); window.addEventListener("devicemotion", this._eventListener.accelerometerCollector, false);
window.addEventListener("touchmove", this._eventListener.touchCollector, false);
} else if (document.attachEvent) { } else if (document.attachEvent) {
document.attachEvent("onload", this._eventListener.loadTimeCollector); document.attachEvent("onload", this._eventListener.loadTimeCollector);
document.attachEvent("onmousemove", this._eventListener.mouseCollector); document.attachEvent("onmousemove", this._eventListener.mouseCollector);
@ -1883,6 +1902,7 @@ sjcl.prng.prototype = {
window.removeEventListener("mousemove", this._eventListener.mouseCollector, false); window.removeEventListener("mousemove", this._eventListener.mouseCollector, false);
window.removeEventListener("keypress", this._eventListener.keyboardCollector, false); window.removeEventListener("keypress", this._eventListener.keyboardCollector, false);
window.removeEventListener("devicemotion", this._eventListener.accelerometerCollector, false); window.removeEventListener("devicemotion", this._eventListener.accelerometerCollector, false);
window.removeEventListener("touchmove", this._eventListener.touchCollector, false);
} else if (document.detachEvent) { } else if (document.detachEvent) {
document.detachEvent("onload", this._eventListener.loadTimeCollector); document.detachEvent("onload", this._eventListener.loadTimeCollector);
document.detachEvent("onmousemove", this._eventListener.mouseCollector); document.detachEvent("onmousemove", this._eventListener.mouseCollector);
@ -2005,8 +2025,31 @@ sjcl.prng.prototype = {
}, },
_mouseCollector: function (ev) { _mouseCollector: function (ev) {
var x = ev.x || ev.clientX || ev.offsetX || 0, y = ev.y || ev.clientY || ev.offsetY || 0; var x, y;
try {
x = ev.x || ev.clientX || ev.offsetX || 0;
y = ev.y || ev.clientY || ev.offsetY || 0;
} catch (err) {
// Event originated from a secure element. No mouse position available.
x = 0;
y = 0;
}
if (x != 0 && y!= 0) {
sjcl.random.addEntropy([x,y], 2, "mouse"); sjcl.random.addEntropy([x,y], 2, "mouse");
}
this._addCurrentTimeToEntropy(0);
},
_touchCollector: function(ev) {
var touch = ev.touches[0] || ev.changedTouches[0];
var x = touch.pageX || touch.clientX,
y = touch.pageY || touch.clientY;
sjcl.random.addEntropy([x,y],1,"touch");
this._addCurrentTimeToEntropy(0); this._addCurrentTimeToEntropy(0);
}, },
@ -2015,7 +2058,7 @@ sjcl.prng.prototype = {
}, },
_addCurrentTimeToEntropy: function (estimatedEntropy) { _addCurrentTimeToEntropy: function (estimatedEntropy) {
if (window && window.performance && typeof window.performance.now === "function") { if (typeof window !== 'undefined' && window.performance && typeof window.performance.now === "function") {
//how much entropy do we want to add here? //how much entropy do we want to add here?
sjcl.random.addEntropy(window.performance.now(), estimatedEntropy, "loadtime"); sjcl.random.addEntropy(window.performance.now(), estimatedEntropy, "loadtime");
} else { } else {
@ -2073,7 +2116,7 @@ sjcl.random = new sjcl.prng(6);
} }
try { try {
var buf, crypt, getRandomValues, ab; var buf, crypt, ab;
// get cryptographically strong entropy depending on runtime environment // get cryptographically strong entropy depending on runtime environment
if (typeof module !== 'undefined' && module.exports && (crypt = getCryptoModule()) && crypt.randomBytes) { if (typeof module !== 'undefined' && module.exports && (crypt = getCryptoModule()) && crypt.randomBytes) {
@ -2081,7 +2124,7 @@ sjcl.random = new sjcl.prng(6);
buf = new Uint32Array(new Uint8Array(buf).buffer); buf = new Uint32Array(new Uint8Array(buf).buffer);
sjcl.random.addEntropy(buf, 1024, "crypto.randomBytes"); sjcl.random.addEntropy(buf, 1024, "crypto.randomBytes");
} else if (window && Uint32Array) { } else if (typeof window !== 'undefined' && typeof Uint32Array !== 'undefined') {
ab = new Uint32Array(32); ab = new Uint32Array(32);
if (window.crypto && window.crypto.getRandomValues) { if (window.crypto && window.crypto.getRandomValues) {
window.crypto.getRandomValues(ab); window.crypto.getRandomValues(ab);
@ -2162,7 +2205,7 @@ sjcl.random = new sjcl.prng(6);
plaintext = sjcl.codec.utf8String.toBits(plaintext); plaintext = sjcl.codec.utf8String.toBits(plaintext);
} }
if (typeof adata === "string") { if (typeof adata === "string") {
adata = sjcl.codec.utf8String.toBits(adata); p.adata = adata = sjcl.codec.utf8String.toBits(adata);
} }
prp = new sjcl.cipher[p.cipher](password); prp = new sjcl.cipher[p.cipher](password);
@ -2240,7 +2283,11 @@ sjcl.random = new sjcl.prng(6);
j._add(rp, p); j._add(rp, p);
rp.key = password; rp.key = password;
if (params.raw === 1) {
return ct;
} else {
return sjcl.codec.utf8String.fromBits(ct); return sjcl.codec.utf8String.fromBits(ct);
}
}, },
/** Simple decryption function. /** Simple decryption function.
@ -2308,13 +2355,15 @@ sjcl.random = new sjcl.prng(6);
} }
var a = str.replace(/^\{|\}$/g, '').split(/,/), out={}, i, m; var a = str.replace(/^\{|\}$/g, '').split(/,/), out={}, i, m;
for (i=0; i<a.length; i++) { for (i=0; i<a.length; i++) {
if (!(m=a[i].match(/^(?:(["']?)([a-z][a-z0-9]*)\1):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i))) { if (!(m=a[i].match(/^\s*(?:(["']?)([a-z][a-z0-9]*)\1)\s*:\s*(?:(-?\d+)|"([a-z0-9+\/%*_.@=\-]*)"|(true|false))$/i))) {
throw new sjcl.exception.invalid("json decode: this isn't json!"); throw new sjcl.exception.invalid("json decode: this isn't json!");
} }
if (m[3]) { if (m[3]) {
out[m[2]] = parseInt(m[3],10); out[m[2]] = parseInt(m[3],10);
} else { } else if (m[4]) {
out[m[2]] = m[2].match(/^(ct|salt|iv)$/) ? sjcl.codec.base64.toBits(m[4]) : unescape(m[4]); out[m[2]] = m[2].match(/^(ct|adata|salt|iv)$/) ? sjcl.codec.base64.toBits(m[4]) : unescape(m[4]);
} else if (m[5]) {
out[m[2]] = m[5] === 'true';
} }
} }
return out; return out;
@ -2415,5 +2464,3 @@ sjcl.misc.cachedPbkdf2 = function (password, obj) {
c[salt] = c[salt] || sjcl.misc.pbkdf2(password, salt, obj.iter); c[salt] = c[salt] || sjcl.misc.pbkdf2(password, salt, obj.iter);
return { key: c[salt].slice(0), salt:salt.slice(0) }; return { key: c[salt].slice(0), salt:salt.slice(0) };
}; };

3
static/js/main.js

@ -114,9 +114,6 @@ require.config({
deps: ['jquery'], deps: ['jquery'],
exports: '$' exports: '$'
}, },
'sjcl': {
exports: 'sjcl'
},
'pdf': { 'pdf': {
deps: ['pdf.compatibility'], deps: ['pdf.compatibility'],
exports: 'PDFJS' exports: 'PDFJS'

45
static/js/mediastream/connector.js

@ -44,6 +44,11 @@ define(['jquery', 'underscore'], function($, _) {
return; return;
} }
if (this.connecting !== null) {
console.warn("Refusing to connect while already connecting");
return;
}
this.error = false; this.error = false;
this.e.triggerHandler("connecting", [url]); this.e.triggerHandler("connecting", [url]);
this.url = url; this.url = url;
@ -51,11 +56,31 @@ define(['jquery', 'underscore'], function($, _) {
url += ("?t=" + this.token); url += ("?t=" + this.token);
//console.log("Reusing existing token", this.token); //console.log("Reusing existing token", this.token);
} }
var that = this;
// Create connection.
var conn = this.conn = new WebSocket(url); var conn = this.conn = new WebSocket(url);
conn.onopen = _.bind(this.onopen, this); conn.onopen = function(event) {
conn.onerror = _.bind(this.onerror, this); if (event.target === that.conn) {
conn.onclose = _.bind(this.onclose, this); that.onopen(event);
conn.onmessage = _.bind(this.onmessage, this) }
};
conn.onerror = function(event) {
if (event.target === that.conn) {
that.onerror(event);
}
};
conn.onclose = function(event) {
if (event.target === that.conn) {
that.onclose(event);
}
};
conn.onmessage = function(event) {
if (event.target === that.conn) {
that.onmessage(event);
}
};
this.connecting = window.setTimeout(_.bind(function() { this.connecting = window.setTimeout(_.bind(function() {
console.warn("Connection timeout out after", this.connecting_timeout); console.warn("Connection timeout out after", this.connecting_timeout);
@ -97,15 +122,15 @@ define(['jquery', 'underscore'], function($, _) {
Connector.prototype.close = function() { Connector.prototype.close = function() {
window.clearTimeout(this.connecting);
this.connecting = null;
this.connected = false; this.connected = false;
if (this.conn) { if (this.conn) {
var conn = this.conn; var conn = this.conn;
this.conn = null; this.conn = null;
if (!this.error) {
conn.close(); conn.close();
} }
conn.onopen = conn.onerror = conn.onclose = conn.onmessage = null;
}
}; };
@ -119,7 +144,9 @@ define(['jquery', 'underscore'], function($, _) {
}; };
Connector.prototype.onopen = function(event) { Connector.prototype.onopen = function(event) {
window.clearTimeout(this.connecting); window.clearTimeout(this.connecting);
this.connecting = null;
this.connecting_timeout = timeout; this.connecting_timeout = timeout;
// Connection successfully established. // Connection successfully established.
@ -133,11 +160,13 @@ define(['jquery', 'underscore'], function($, _) {
data = this.queue.shift(); data = this.queue.shift();
this.send(data); this.send(data);
} }
}; };
Connector.prototype.onerror = function(event) { Connector.prototype.onerror = function(event) {
window.clearTimeout(this.connecting); window.clearTimeout(this.connecting);
this.connecting = null;
this.connecting_timeout = timeout; this.connecting_timeout = timeout;
//console.log("onerror", event); //console.log("onerror", event);
@ -151,6 +180,7 @@ define(['jquery', 'underscore'], function($, _) {
Connector.prototype.onclose = function(event) { Connector.prototype.onclose = function(event) {
window.clearTimeout(this.connecting); window.clearTimeout(this.connecting);
this.connecting = null;
this.connecting_timeout = timeout; this.connecting_timeout = timeout;
//console.log("onclose", event); //console.log("onclose", event);
@ -159,6 +189,7 @@ define(['jquery', 'underscore'], function($, _) {
if (!this.error) { if (!this.error) {
this.e.triggerHandler("close", [null, event]); this.e.triggerHandler("close", [null, event]);
} }
}; };
Connector.prototype.onmessage = function(event) { Connector.prototype.onmessage = function(event) {

2
static/js/mediastream/webrtc.js

@ -113,7 +113,7 @@ function($, _, PeerCall, PeerConference, PeerXfer, PeerScreenshare, UserMedia, u
//videoRecvBitrate: , //videoRecvBitrate: ,
//videoRecvCodec //videoRecvCodec
} }
} };
this.screensharingSettings = { this.screensharingSettings = {

2
static/partials/chatroom.html

@ -21,7 +21,7 @@
</div> </div>
<div class="inputbox"> <div class="inputbox">
<div> <div>
<textarea class="input nicescroll form-control" ng-disabled="!(enabled)" on-enter="submit()" ng-model="input" placeholder="{{_('Type here to chat...')}}"/> <textarea class="input nicescroll form-control" maxlength="{{maxMessageSize}}" ng-disabled="!(enabled)" on-enter="submit()" ng-model="input" placeholder="{{_('Type here to chat...')}}"/>
</div> </div>
<a ng-disabled="!(enabled)" ng-click="submit()" title="{{_('Send')}}" class="btn btn-small btn-info fa fa-play"></a> <a ng-disabled="!(enabled)" ng-click="submit()" title="{{_('Send')}}" class="btn btn-small btn-info fa fa-play"></a>
</div> </div>

2
static/partials/youtubevideo.html

@ -40,7 +40,7 @@
<div class="volumecontrol"> <div class="volumecontrol">
<button class="btn volume-button" ng-class="{'active': volumebarVisible}" ng-click="volumebarVisible=!volumebarVisible"><i class="fa fa-volume-up" ng-class="{'fa-volume-up': volume &gt;= 60, 'fa-volume-down': volume &lt; 60}"></i></button> <button class="btn volume-button" ng-class="{'active': volumebarVisible}" ng-click="volumebarVisible=!volumebarVisible"><i class="fa fa-volume-up" ng-class="{'fa-volume-up': volume &gt;= 60, 'fa-volume-down': volume &lt; 60}"></i></button>
<div ng-show="volumebarVisible" class="volumebar"> <div ng-show="volumebarVisible" class="volumebar">
<input type="range" min="0" max="100" step="1" ng-model="volume" /> <input type="range" class="bar" min="0" max="100" step="1" ng-model="volume" />
</div> </div>
</div> </div>
</div> </div>

Loading…
Cancel
Save