removed bootstrap dependencies
This commit is contained in:
+186
-122
@@ -4,18 +4,147 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Basic elements defined */
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
height:100%;
|
height:100%;
|
||||||
width:100%;
|
width:100%;
|
||||||
font-family: 'Roboto', Arial, sans-serif;
|
font-family: 'Roboto', Arial, sans-serif;
|
||||||
|
font-size: 10pt;
|
||||||
|
color: #666;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: silver;
|
background-color: silver;
|
||||||
|
box-shadow: inset 0 10em #3949AB; /* the deep-plue stripe accross the top */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #2196f3;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover,
|
||||||
|
a:focus {
|
||||||
|
color: #0a6ebd;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a:focus {
|
||||||
|
outline: thin dotted;
|
||||||
|
outline: 5px auto -webkit-focus-ring-color;
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input fields and buttons */
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: inline-block;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
height: 2.2em;
|
||||||
|
line-height: 2.2em;
|
||||||
|
font-weight: normal;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
touch-action: manipulation;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
white-space: nowrap;
|
||||||
|
padding-left: 2em;
|
||||||
|
padding-right: 2em;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
button[disabled],
|
||||||
|
html input[disabled] {
|
||||||
|
cursor: default;
|
||||||
|
opacity: 0.65;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.round {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 1;
|
||||||
|
outline: none; /* otherwise a square outline is shown */
|
||||||
|
box-shadow: 0 2px 0.5rem 0 rgba(0, 0, 0, 0.25);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:focus, button:hover, button:active {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
button:active {
|
||||||
|
box-shadow: inset 0 3px 0.5rem rgba(0, 0, 0, 0.125);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.blue {
|
||||||
|
background-color: #1e88e5; /* blue 600 */
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
button.blue:focus, button.blue:hover, button.blue:active {
|
||||||
|
background-color: #1976d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea, input {
|
||||||
|
font-family: inherit;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
border-radius: 0.2em;
|
||||||
|
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
width: 100%;
|
||||||
|
margin: 0.25em 0;
|
||||||
|
padding: 0 0.125em;
|
||||||
|
outline: none;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
textarea:focus,input:focus {
|
||||||
|
border-bottom: 1px solid #2196f3;
|
||||||
|
box-shadow: 0 1px 0 rgba(33, 150, 243, 0.25);
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
height: 2.5em;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
/* Scrollbar styling for Chrome. Firefox does not support scrollbar styling. */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.2);
|
||||||
|
background-color: rgba(255,255,255,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* END of input and buttons */
|
||||||
|
|
||||||
|
form {
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
line-height: 1.75;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* END of basic elements */
|
||||||
|
|
||||||
#mountPoint {
|
#mountPoint {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding-top: 1em;
|
padding-top: 1em;
|
||||||
padding-bottom: 4em;
|
padding-bottom: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Top-level application layout style: sidepanel + main view */
|
/* Top-level application layout style: sidepanel + main view */
|
||||||
@@ -27,11 +156,13 @@ html, body {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
border-radius: 0.25em;
|
||||||
box-shadow: 1px 2px 0.3em gray;
|
box-shadow: 1px 2px 0.3em gray;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidepanel {
|
#sidepanel {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 30em;
|
width: 30em;
|
||||||
@@ -47,25 +178,35 @@ html, body {
|
|||||||
/* END of top-level layout */
|
/* END of top-level layout */
|
||||||
|
|
||||||
/* Sidepanel styles */
|
/* Sidepanel styles */
|
||||||
|
.panel-title {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-buttons {
|
||||||
|
display: flex;
|
||||||
|
padding: 0.5em;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
#side-caption-panel {
|
#side-caption-panel {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
x-justify-content: space-between;
|
x-justify-content: space-between;
|
||||||
flex: none;
|
flex: none;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
height: 4.5em;
|
height: 4em;
|
||||||
|
|
||||||
background-color: #039be5; /* light-blue 600 */
|
background-color: #2196f3; /* blue 500 */
|
||||||
color: #b3e5fc; /* light-blue 100 */
|
color: #bbdefb; /* light-blue 100 */
|
||||||
|
|
||||||
box-shadow: 0 1px 1px -1px gray;
|
box-shadow: 0 1px 2px gray;
|
||||||
z-index: 1; /* otherwise the shadow becomes invisible */
|
z-index: 1; /* otherwise the shadow becomes invisible */
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-caption-panel a {
|
#side-caption-panel a {
|
||||||
color: #b3e5fc; /* light-blue 100 */
|
color: #bbdefb; /* blue 100 */
|
||||||
padding-left: 0.5em;
|
padding-left: 0.5em;
|
||||||
vertical-align: -1.5em; /* icons are bigger than the declared font size */
|
vertical-align: -1em; /* icons are bigger than the declared font size */
|
||||||
}
|
}
|
||||||
|
|
||||||
#side-caption-panel :hover {
|
#side-caption-panel :hover {
|
||||||
@@ -75,7 +216,6 @@ html, body {
|
|||||||
#sidepanel-title {
|
#sidepanel-title {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
font-size: 2rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#self-avatar {
|
#self-avatar {
|
||||||
@@ -97,8 +237,8 @@ html, body {
|
|||||||
|
|
||||||
/* List of contacts */
|
/* List of contacts */
|
||||||
#contacts-panel {
|
#contacts-panel {
|
||||||
position: relative;
|
overflow-y: auto;
|
||||||
overflow-y: scroll;
|
margin-bottom: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#contact-box {
|
#contact-box {
|
||||||
@@ -112,7 +252,14 @@ html, body {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
#contact-box li:hover {
|
#contact-box li:hover {
|
||||||
background-color: #fffde7; /* yellow 50 highlight */
|
background-color: #eceff1; /* blue-gray 50 highlight */
|
||||||
|
}
|
||||||
|
#contact-box li.selected {
|
||||||
|
background-color: #cfd8dc; /* blue-gray 100 highlight */
|
||||||
|
}
|
||||||
|
|
||||||
|
#contact-box .contact-title {
|
||||||
|
font-size: 1.05rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Avatar and online-offline indicator */
|
/* Avatar and online-offline indicator */
|
||||||
@@ -132,9 +279,10 @@ html, body {
|
|||||||
/* Online-offline indicator positioned inside avatar-box */
|
/* Online-offline indicator positioned inside avatar-box */
|
||||||
#contact-box .online, .offline {
|
#contact-box .online, .offline {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
|
line-height: 1;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: -0.5em;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
#contact-box .online {
|
#contact-box .online {
|
||||||
color: #66bb6a;
|
color: #66bb6a;
|
||||||
@@ -159,24 +307,37 @@ html, body {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex: none;
|
flex: none;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
height: 4.5em;
|
height: 4em;
|
||||||
background-color: #b0bec5;
|
background-color: #b0bec5;
|
||||||
box-shadow: 0 1px 1px -1px gray;
|
box-shadow: 0 1px 2px gray;
|
||||||
z-index: 1; /* otherwise the shadow becomes invisible */
|
z-index: 1; /* otherwise the shadow becomes invisible */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#topic-title {
|
||||||
|
}
|
||||||
|
#topic-last-seen {
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scrollable panel where the messages are shown */
|
||||||
#messages-panel {
|
#messages-panel {
|
||||||
padding: 0.75em;
|
padding: 0.75em;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
background-color: #eceff1;
|
background-color: #eceff1;
|
||||||
|
height: 100%;
|
||||||
background-image: url("../img/ignasi_pattern_s.png");
|
background-image: url("../img/ignasi_pattern_s.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Footer-panel with the input for the new message */
|
/* Footer-panel with the input for the new message */
|
||||||
#send-message-panel {
|
#send-message-panel {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
flex: none;
|
flex: none;
|
||||||
margin-top: auto;
|
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
background-color: #eceff1;
|
||||||
|
box-shadow: 0 -1px rgba(0,0,0,0.1); /* Faint shadow above panel */
|
||||||
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A static panel shown when no topic is selected */
|
/* A static panel shown when no topic is selected */
|
||||||
@@ -189,53 +350,6 @@ html, body {
|
|||||||
background-color: #e0f7fa;
|
background-color: #e0f7fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* END of topic/mesages view */
|
|
||||||
|
|
||||||
|
|
||||||
.contactBox {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#newTopicInput {
|
|
||||||
z-index: 3;
|
|
||||||
background-color: #FFF;
|
|
||||||
padding-bottom: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contactList {
|
|
||||||
padding: 9.5em 0em 0.5em 0em;
|
|
||||||
margin-top: -9em;
|
|
||||||
height: 100vh;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contactList li {
|
|
||||||
padding: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contactList li:hover {
|
|
||||||
background-color: #EEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullHeight {
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullViewPort {
|
|
||||||
height: 99vh;
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-12 {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Talk bubbles */
|
/* Talk bubbles */
|
||||||
.chat-box {
|
.chat-box {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@@ -373,65 +487,8 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* END of talk bubbles */
|
/* END of talk bubbles */
|
||||||
|
/* END of topic/mesages view */
|
||||||
|
|
||||||
/* Input fields and buttons */
|
|
||||||
button {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0;
|
|
||||||
font-weight: normal;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
touch-action: manipulation;
|
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
white-space: nowrap;
|
|
||||||
padding: 0.25em 1em;
|
|
||||||
font-size: 1.35rem;
|
|
||||||
border-radius: 2px;
|
|
||||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
button[disabled],
|
|
||||||
html input[disabled] {
|
|
||||||
cursor: default;
|
|
||||||
opacity: 0.65;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.round {
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 5rem;
|
|
||||||
height: 5rem;
|
|
||||||
line-height: 1;
|
|
||||||
outline: none; /* otherwise a square outline is shown */
|
|
||||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.25);
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
button.blue {
|
|
||||||
background-color: #2196f3; /* blue 500 */
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:active {
|
|
||||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
border-bottom: 1px solid #999;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
outline: none;
|
|
||||||
transition: border 0.2s ease-in-out, box-shadow: 0.2s ease-in-out;
|
|
||||||
}
|
|
||||||
input:focus {
|
|
||||||
border-bottom: 1px solid #2196f3;
|
|
||||||
box-shadow: inset 0 -1px 0 rgba(33, 150, 243, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* END of input and buttons */
|
|
||||||
|
|
||||||
/* Modal dialog */
|
/* Modal dialog */
|
||||||
.overlay {
|
.overlay {
|
||||||
@@ -454,9 +511,15 @@ input:focus {
|
|||||||
|
|
||||||
/* Badge with the number of unread messages */
|
/* Badge with the number of unread messages */
|
||||||
.badge {
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: bold;
|
||||||
background-color: #0097A7;
|
background-color: #0097A7;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
|
padding: 0.25em;
|
||||||
|
min-width: 1.5em;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Color of buttons */
|
/* Color of buttons */
|
||||||
@@ -466,8 +529,9 @@ input:focus {
|
|||||||
|
|
||||||
/* Material icons resized from the default 24pt */
|
/* Material icons resized from the default 24pt */
|
||||||
.material-icons {
|
.material-icons {
|
||||||
font-size: 2rem;
|
font-size: 1.4rem;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
.material-icons.small {
|
.material-icons.small {
|
||||||
font-size: 1.5rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-7519
File diff suppressed because it is too large
Load Diff
+68
-50
@@ -25,6 +25,11 @@
|
|||||||
</head>
|
</head>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!--
|
||||||
|
<i class="material-icons">group</i>
|
||||||
|
<i class="material-icons" id="self-avatar">person</i>
|
||||||
|
-->
|
||||||
|
|
||||||
<div id="mountPoint"></div>
|
<div id="mountPoint"></div>
|
||||||
<script type="text/babel">
|
<script type="text/babel">
|
||||||
// Host name and posrt to connect to
|
// Host name and posrt to connect to
|
||||||
@@ -93,21 +98,20 @@
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<form className="form-signin" onSubmit={this.handleSubmit}>
|
<form id="login-form" onSubmit={this.handleSubmit}>
|
||||||
<label htmlFor="inputLogin" className="sr-only">Login</label>
|
<input type="text" id="inputLogin"
|
||||||
<input type="text" id="inputLogin" className="form-control"
|
|
||||||
placeholder="Login (alice, bob, carol, dave, frank)"
|
placeholder="Login (alice, bob, carol, dave, frank)"
|
||||||
value={this.state.login}
|
value={this.state.login}
|
||||||
onChange={this.handleLoginChange}
|
onChange={this.handleLoginChange}
|
||||||
required autofocus />
|
required autofocus />
|
||||||
<label htmlFor="inputPassword" className="sr-only">Password</label>
|
<input type="password" id="inputPassword"
|
||||||
<input type="password" id="inputPassword" className="form-control"
|
|
||||||
placeholder="Password (alice123, bob123, ...)"
|
placeholder="Password (alice123, bob123, ...)"
|
||||||
value={this.state.password}
|
value={this.state.password}
|
||||||
onChange={this.handlePasswordChange}
|
onChange={this.handlePasswordChange}
|
||||||
required />
|
required />
|
||||||
<br />
|
<div className="dialog-buttons">
|
||||||
<button className={submitClassList} type="submit">SIGN IN</button>
|
<button className={submitClassList} type="submit">Sign in</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -159,24 +163,20 @@
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<form onSubmit={this.handleSubmit} onCancel={this.props.onCancel}>
|
<form id="signup-form" onSubmit={this.handleSubmit} onCancel={this.props.onCancel}>
|
||||||
<label htmlFor="signupLogin" className="sr-only">Login</label>
|
<input type="text" placeholder="Login"
|
||||||
<input type="text" id="signupLogin" className="form-control" placeholder="Login"
|
|
||||||
value={this.state.login} onChange={this.handleLoginChange} required autofocus />
|
value={this.state.login} onChange={this.handleLoginChange} required autofocus />
|
||||||
<label htmlFor="signupPassword" className="sr-only">Password</label>
|
<input type="password" placeholder="Password"
|
||||||
<input type="password" id="signupPassword" className="form-control" placeholder="Password"
|
|
||||||
value={this.state.password} onChange={this.handlePasswordChange} required />
|
value={this.state.password} onChange={this.handlePasswordChange} required />
|
||||||
<label htmlFor="signupPassword2" className="sr-only">Repeat password</label>
|
<input type="password" placeholder="Repeat password"
|
||||||
<input type="password" id="signupPassword" className="form-control" placeholder="Repeat password"
|
|
||||||
value={this.state.password2} onChange={this.handlePassword2Change} required />
|
value={this.state.password2} onChange={this.handlePassword2Change} required />
|
||||||
<label htmlFor="signupPublic" className="sr-only">Account public data</label>
|
<textarea rows="3" onChange={this.handlePublicChange}
|
||||||
<textarea id="signupPublic" className="form-control" rows="3" onChange={this.handlePublicChange}
|
|
||||||
value={this.state.public} placeholder="Public: text or valid JSON"></textarea>
|
value={this.state.public} placeholder="Public: text or valid JSON"></textarea>
|
||||||
<label htmlFor="signupPrivate" className="sr-only">Account private data</label>
|
<textarea rows="3" onChange={this.handlePrivateChange}
|
||||||
<textarea id="signupPrivate" className="form-control" rows="3" onChange={this.handlePrivateChange}
|
|
||||||
value={this.state.private} placeholder="Private: text or valid JSON"></textarea>
|
value={this.state.private} placeholder="Private: text or valid JSON"></textarea>
|
||||||
<br />
|
<div className="dialog-buttons">
|
||||||
<button className={submitClassList} type="submit">SIGN UP</button>
|
<button className={submitClassList} type="submit">Sign up</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -188,8 +188,8 @@
|
|||||||
var SettingsView = React.createClass({
|
var SettingsView = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="container-fluid">
|
<div id="settings-form">
|
||||||
<h3>Not implemented</h3>
|
<big>Not implemented</big>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -200,14 +200,15 @@
|
|||||||
var SideNavbar = React.createClass({
|
var SideNavbar = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
var avatar = null;
|
var avatar = null;
|
||||||
if (this.props.avatar) {
|
if (this.props.avatar === true) {
|
||||||
var src = this.props.avatar === true ? "img/avatar.svg" : this.props.avatar;
|
avatar = ( <i class="material-icons" id="self-avatar">person</i> );
|
||||||
avatar = <img id="self-avatar" alt="avatar" src={src} />
|
else if (this.props.avatar) {
|
||||||
|
avatar = ( <img id="self-avatar" alt="avatar" src={this.props.avatar} /> );
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div id="side-caption-panel">
|
<div id="side-caption-panel">
|
||||||
{avatar}
|
{avatar}
|
||||||
<div id="sidepanel-title">{this.props.title}</div>
|
<div id="sidepanel-title" className="panel-title">{this.props.title}</div>
|
||||||
{this.props.state === 'login' ?
|
{this.props.state === 'login' ?
|
||||||
<SideNavbar.MenuStart onSignUp={this.props.onSignUp} onSettings={this.props.onSettings} /> :
|
<SideNavbar.MenuStart onSignUp={this.props.onSignUp} onSettings={this.props.onSettings} /> :
|
||||||
this.props.state === 'settings' ?
|
this.props.state === 'settings' ?
|
||||||
@@ -225,9 +226,9 @@
|
|||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<a href="#" onClick={this.props.onSignUp}><i className="material-icons medium">person_add</i></a>
|
<a href="#" onClick={this.props.onSignUp}><i className="material-icons">person_add</i></a>
|
||||||
|
|
||||||
<a href="#" onClick={this.props.onSettings}><i className="material-icons medium">settings</i></a>
|
<a href="#" onClick={this.props.onSettings}><i className="material-icons">settings</i></a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -236,7 +237,7 @@
|
|||||||
SideNavbar.MenuCancel = React.createClass({
|
SideNavbar.MenuCancel = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<a href="#" onClick={this.props.onCancel}><i className="material-icons medium">close</i></a>
|
<a href="#" onClick={this.props.onCancel}><i className="material-icons">close</i></a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -244,7 +245,7 @@
|
|||||||
SideNavbar.MenuSettings = React.createClass({
|
SideNavbar.MenuSettings = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<a href="#" onClick={this.props.onSettings}><i className="material-icons medium">settings</i></a>
|
<a href="#" onClick={this.props.onSettings}><i className="material-icons">settings</i></a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -359,14 +360,15 @@
|
|||||||
if (title.length > 32) {
|
if (title.length > 32) {
|
||||||
title = title.substring(0, 30) + "...";
|
title = title.substring(0, 30) + "...";
|
||||||
}
|
}
|
||||||
|
var selected = (this.props.selected === this.props.topic) ? "selected" : null;
|
||||||
return (
|
return (
|
||||||
<li onClick={this.handleClick}>
|
<li className={selected} onClick={this.handleClick}>
|
||||||
<div className="avatar-box">
|
<div className="avatar-box">
|
||||||
<img src="img/avatar.svg" className="avatar" alt="" />
|
<img src="img/avatar.svg" className="avatar" alt="" />
|
||||||
<span className={this.props.now ? "online" : "offline"}>●</span>
|
<span className={this.props.now ? "online" : "offline"}>●</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong>{title}</strong> <Contact.Unread count={this.props.unread} />
|
<span className="contact-title">{title}</span> <Contact.Unread count={this.props.unread} />
|
||||||
<p>{this.props.comment}</p>
|
<p>{this.props.comment}</p>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@@ -379,7 +381,7 @@
|
|||||||
render: function() {
|
render: function() {
|
||||||
var showUnreadBadge = null;
|
var showUnreadBadge = null;
|
||||||
if (this.props.count > 0) {
|
if (this.props.count > 0) {
|
||||||
var count = this.props.count > 99 ? "99+" : this.props.count;
|
var count = this.props.count > 9 ? "9+" : this.props.count;
|
||||||
showUnreadBadge = <span className="badge">{count}</span>;
|
showUnreadBadge = <span className="badge">{count}</span>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
@@ -391,7 +393,10 @@
|
|||||||
/* ContactsView holds all contacts-related stuff */
|
/* ContactsView holds all contacts-related stuff */
|
||||||
var ContactsView = React.createClass({
|
var ContactsView = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {subscriptions: []};
|
return {
|
||||||
|
subscriptions: [],
|
||||||
|
selected: null
|
||||||
|
};
|
||||||
},
|
},
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
var me = Tinode.getMeTopic();
|
var me = Tinode.getMeTopic();
|
||||||
@@ -416,22 +421,18 @@
|
|||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
},
|
},
|
||||||
onSelectionChange: function(sel) {
|
onSelectionChange: function(sel) {
|
||||||
|
this.setState({selected: sel});
|
||||||
this.props.onTopicSelected(sel);
|
this.props.onTopicSelected(sel);
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var contactNodes = [];
|
var contactNodes = [];
|
||||||
Tinode.getMeTopic().contacts(function(c) {
|
Tinode.getMeTopic().contacts(function(c) {
|
||||||
var lastSeen = null;
|
|
||||||
if (c.seen) {
|
|
||||||
lastSeen = shortDateFormat(c.seen.when);
|
|
||||||
// TODO(gene): also handle user agent in c.seen.ua
|
|
||||||
}
|
|
||||||
var unread = c.seq;
|
var unread = c.seq;
|
||||||
if (c.read > 0) {
|
if (c.read > 0) {
|
||||||
unread -= c.read;
|
unread -= c.read;
|
||||||
}
|
}
|
||||||
contactNodes.push(
|
contactNodes.push(
|
||||||
<Contact public={c.public} comment={c.private} unread={unread} now={c.online} when={lastSeen}
|
<Contact public={c.public} comment={c.private} unread={unread} now={c.online} selected={this.state.selected}
|
||||||
onSelected={this.onSelectionChange} topic={c.topic} key={c.topic} />
|
onSelected={this.onSelectionChange} topic={c.topic} key={c.topic} />
|
||||||
);
|
);
|
||||||
}, this);
|
}, this);
|
||||||
@@ -543,12 +544,12 @@ dignissim a diam a hendrerit. Nulla vel est ut quam rhoncus pulvinar. In hac hab
|
|||||||
},
|
},
|
||||||
// Scroll last message into view on component update e.g. on message received.
|
// Scroll last message into view on component update e.g. on message received.
|
||||||
componentDidUpdate: function() {
|
componentDidUpdate: function() {
|
||||||
//var node = ReactDOM.findDOMNode(this);
|
var node = this.refs.messagesPanel;
|
||||||
//if (node) {
|
if (node) {
|
||||||
// node.scrollTop = node.scrollHeight;
|
console.log("scrollToBottom: top=" + node.scrollTop + ", height="+ node.scrollHeight);
|
||||||
//}
|
node.scrollTop = node.scrollHeight;
|
||||||
//var node = this.refs.messagesPanel;
|
console.log("scrollToBottom: top=" + node.scrollTop + ", height="+ node.scrollHeight);
|
||||||
//node.scrollTop = node.scrollHeight;
|
}
|
||||||
},
|
},
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
this.propsChange(this.props);
|
this.propsChange(this.props);
|
||||||
@@ -608,7 +609,7 @@ dignissim a diam a hendrerit. Nulla vel est ut quam rhoncus pulvinar. In hac hab
|
|||||||
var component = null;
|
var component = null;
|
||||||
if (this.state.topic) {
|
if (this.state.topic) {
|
||||||
var messageNodes = [];
|
var messageNodes = [];
|
||||||
var me = Tinode.getCurrentUserID();
|
var myUid = Tinode.getCurrentUserID();
|
||||||
var topic = Tinode.getTopic(this.state.topic);
|
var topic = Tinode.getTopic(this.state.topic);
|
||||||
var previousFrom = null;
|
var previousFrom = null;
|
||||||
for (var i=0; i<this.state.messages.length; i++) {
|
for (var i=0; i<this.state.messages.length; i++) {
|
||||||
@@ -626,7 +627,7 @@ dignissim a diam a hendrerit. Nulla vel est ut quam rhoncus pulvinar. In hac hab
|
|||||||
}
|
}
|
||||||
previousFrom = msg.from;
|
previousFrom = msg.from;
|
||||||
|
|
||||||
var isReply = !(msg.from === me);
|
var isReply = !(msg.from === myUid);
|
||||||
var msgReceived = Received.UNDEF;
|
var msgReceived = Received.UNDEF;
|
||||||
if (!isReply) {
|
if (!isReply) {
|
||||||
if (topic.msgReadCount(msg.seq) > 1) {
|
if (topic.msgReadCount(msg.seq) > 1) {
|
||||||
@@ -642,10 +643,27 @@ dignissim a diam a hendrerit. Nulla vel est ut quam rhoncus pulvinar. In hac hab
|
|||||||
userIndex={msg.$userIndex} sequence={sequence} received={msgReceived} key={msg.seq} />
|
userIndex={msg.$userIndex} sequence={sequence} received={msgReceived} key={msg.seq} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lastSeen = null;
|
||||||
|
/*
|
||||||
|
var cont = Tinode.getMeTopic().getContact(this.state.topic);
|
||||||
|
if (cont.getType() == "p2p") {
|
||||||
|
if (cont.online) {
|
||||||
|
lastSeen = "online now";
|
||||||
|
} else if (cont.seen) {
|
||||||
|
lastSeen = shortDateFormat(c.seen.when);
|
||||||
|
// TODO(gene): also handle user agent in c.seen.ua
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
component = (
|
component = (
|
||||||
<div id="topic-view">
|
<div id="topic-view">
|
||||||
<div id="topic-caption-panel">
|
<div id="topic-caption-panel">
|
||||||
<h4>{this.state.title}</h4>
|
<div>
|
||||||
|
<div id="topic-title" className="panel-title">{this.state.title}</div>
|
||||||
|
<div id="topic-last-seen">{lastSeen}</div>
|
||||||
|
</div>
|
||||||
|
<div>users online and menu buttons</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="messages-panel" ref="messagesPanel">
|
<div id="messages-panel" ref="messagesPanel">
|
||||||
<ul className="chat-box">
|
<ul className="chat-box">
|
||||||
@@ -713,7 +731,7 @@ dignissim a diam a hendrerit. Nulla vel est ut quam rhoncus pulvinar. In hac hab
|
|||||||
<a href="https://github.com/tinode/chat/">
|
<a href="https://github.com/tinode/chat/">
|
||||||
<div>
|
<div>
|
||||||
<img id="logo" alt="logo" src="img/logo.svg" />
|
<img id="logo" alt="logo" src="img/logo.svg" />
|
||||||
<h4>Tinode Demo Chat</h4>
|
<h2>Tinode Demo Chat</h2>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user