major CSS overhaul to try to make things look a bit cleaner
This commit is contained in:
parent
303b455965
commit
b765dc005b
|
@ -318,7 +318,7 @@ textarea, input {
|
|||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
height: 70px;
|
||||
background-color: #f8f8f8;
|
||||
border-top: #aaa 1px solid;
|
||||
}
|
||||
|
@ -326,7 +326,9 @@ textarea, input {
|
|||
#controls {
|
||||
max-width: 1280px;
|
||||
padding: 12px;
|
||||
padding-right: 42px;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#buttonsCell {
|
||||
|
@ -343,7 +345,17 @@ textarea, input {
|
|||
|
||||
#mainInput {
|
||||
width: 100%;
|
||||
resize: none;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#attachButton {
|
||||
position: absolute;
|
||||
margin-top: 3px;
|
||||
right: 0px;
|
||||
background: url('img/attach.png');
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.blink {
|
||||
|
@ -415,7 +427,8 @@ textarea, input {
|
|||
.roomHeaderInfo {
|
||||
text-align: right;
|
||||
float: right;
|
||||
margin-top: 15px;
|
||||
margin-top: 0px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
/*** Room Info Dialog ***/
|
||||
|
@ -449,15 +462,32 @@ textarea, input {
|
|||
resize: vertical;
|
||||
}
|
||||
|
||||
/*** Control Buttons ***/
|
||||
#controlButtons {
|
||||
float: right;
|
||||
margin-right: -4px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.controlButton {
|
||||
border: 0px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
padding-left: 3px;
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
/*** Participant list ***/
|
||||
|
||||
#usersTableWrapper {
|
||||
float: right;
|
||||
width: 120px;
|
||||
clear: right;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
#usersTable {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
@ -473,36 +503,66 @@ textarea, input {
|
|||
position: relative;
|
||||
background-color: #000;
|
||||
}
|
||||
*/
|
||||
|
||||
.userAvatar .userAvatarImage {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
.userAvatar {
|
||||
}
|
||||
|
||||
.userAvatarFrame {
|
||||
border-radius: 46px;
|
||||
width: 80px;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
border: 3px solid #aaa;
|
||||
background-color: #aaa;
|
||||
}
|
||||
|
||||
.userAvatarImage {
|
||||
border-radius: 40px;
|
||||
text-align: center;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
.userAvatar .userAvatarGradient {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
*/
|
||||
|
||||
.userAvatar .userName {
|
||||
position: absolute;
|
||||
color: #fff;
|
||||
margin: 2px;
|
||||
bottom: 0px;
|
||||
.userName {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 6px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.userAvatar .userPowerLevel {
|
||||
.userPowerLevel {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
height: 2px;
|
||||
bottom: -1px;
|
||||
height: 1px;
|
||||
background-color: #f00;
|
||||
}
|
||||
|
||||
.userPowerLevelBar {
|
||||
display: inline;
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
height: 10px;
|
||||
/* border: 1px solid #000;
|
||||
*/ background-color: #aaa;
|
||||
}
|
||||
|
||||
.userPowerLevelMeter {
|
||||
position: relative;
|
||||
bottom: 0px;
|
||||
background-color: #f00;
|
||||
}
|
||||
|
||||
/*
|
||||
.userPresence {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
|
@ -510,12 +570,15 @@ textarea, input {
|
|||
background-color: #aaa;
|
||||
border-bottom: 1px #ddd solid;
|
||||
}
|
||||
*/
|
||||
|
||||
.online {
|
||||
border-color: #38AF00;
|
||||
background-color: #38AF00;
|
||||
}
|
||||
|
||||
.unavailable {
|
||||
border-color: #FFCC00;
|
||||
background-color: #FFCC00;
|
||||
}
|
||||
|
||||
|
@ -538,18 +601,21 @@ textarea, input {
|
|||
|
||||
#messageTable td {
|
||||
padding: 0px;
|
||||
/* border: 1px solid #888; */
|
||||
}
|
||||
|
||||
.leftBlock {
|
||||
width: 14em;
|
||||
width: 6em;
|
||||
word-wrap: break-word;
|
||||
vertical-align: top;
|
||||
background-color: #fff;
|
||||
color: #888;
|
||||
color: #aaa;
|
||||
font-weight: medium;
|
||||
font-size: 12px;
|
||||
text-align: right;
|
||||
/*
|
||||
border-top: 1px #ddd solid;
|
||||
*/
|
||||
}
|
||||
|
||||
.rightBlock {
|
||||
|
@ -560,13 +626,24 @@ textarea, input {
|
|||
}
|
||||
|
||||
.sender, .timestamp {
|
||||
padding-right: 1em;
|
||||
padding-left: 1em;
|
||||
padding-top: 3px;
|
||||
/* padding-top: 3px;
|
||||
*/}
|
||||
|
||||
.timestamp {
|
||||
font-size: 10px;
|
||||
color: #ccc;
|
||||
height: 13px;
|
||||
margin-top: 4px;
|
||||
*/ transition-property: opacity;
|
||||
transition-duration: 0.3s;
|
||||
}
|
||||
|
||||
.sender {
|
||||
margin-bottom: -3px;
|
||||
font-size: 12px;
|
||||
/*
|
||||
margin-top: 5px;
|
||||
margin-bottom: -9px;
|
||||
*/
|
||||
}
|
||||
|
||||
.avatar {
|
||||
|
@ -577,7 +654,11 @@ textarea, input {
|
|||
}
|
||||
|
||||
.avatarImage {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
object-fit: cover;
|
||||
border-radius: 32px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.emote {
|
||||
|
@ -591,6 +672,7 @@ textarea, input {
|
|||
}
|
||||
|
||||
.image {
|
||||
border: 1px solid #888;
|
||||
display: block;
|
||||
max-width:320px;
|
||||
max-height:320px;
|
||||
|
@ -603,19 +685,23 @@ textarea, input {
|
|||
}
|
||||
|
||||
.bubble {
|
||||
/*
|
||||
background-color: #eee;
|
||||
border: 1px solid #d8d8d8;
|
||||
display: inline-block;
|
||||
margin-bottom: -1px;
|
||||
max-width: 90%;
|
||||
font-size: 14px;
|
||||
word-wrap: break-word;
|
||||
padding-top: 7px;
|
||||
padding-bottom: 5px;
|
||||
-webkit-text-size-adjust:100%
|
||||
vertical-align: middle;
|
||||
*/
|
||||
display: inline-block;
|
||||
max-width: 90%;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
vertical-align: middle;
|
||||
-webkit-text-size-adjust:100%
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
font-size: 14px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.bubble img {
|
||||
|
@ -623,9 +709,11 @@ textarea, input {
|
|||
max-height: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
.differentUser td {
|
||||
padding-bottom: 5px ! important;
|
||||
}
|
||||
*/
|
||||
|
||||
.mine {
|
||||
text-align: right;
|
||||
|
@ -635,13 +723,15 @@ textarea, input {
|
|||
.text.membership .bubble,
|
||||
.mine .text.emote .bubble,
|
||||
.mine .text.membership .bubble
|
||||
{
|
||||
{
|
||||
background-color: transparent ! important;
|
||||
border: 0px ! important;
|
||||
}
|
||||
|
||||
.mine .text .bubble {
|
||||
/*
|
||||
background-color: #f8f8ff ! important;
|
||||
*/
|
||||
text-align: left ! important;
|
||||
}
|
||||
|
||||
|
@ -701,6 +791,8 @@ textarea, input {
|
|||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
.recentsRoom {
|
||||
|
@ -751,7 +843,7 @@ textarea, input {
|
|||
padding-right: 10px;
|
||||
margin-right: 10px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #ddd;
|
||||
/* border-right: 1px solid #ddd; */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 473 B |
Binary file not shown.
After Width: | Height: | Size: 864 B |
Binary file not shown.
After Width: | Height: | Size: 604 B |
Binary file not shown.
After Width: | Height: | Size: 659 B |
|
@ -17,6 +17,8 @@
|
|||
<script src="js/angular-route.min.js"></script>
|
||||
<script src="js/angular-sanitize.min.js"></script>
|
||||
<script src="js/angular-animate.min.js"></script>
|
||||
<script src="js/jquery.peity.min.js"></script>
|
||||
<script src="js/angular-peity.js"></script>
|
||||
<script type='text/javascript' src="js/ui-bootstrap-tpls-0.11.2.js"></script>
|
||||
<script type='text/javascript' src='js/ng-infinite-scroll-matrix.js'></script>
|
||||
<script type='text/javascript' src='js/autofill-event.js'></script>
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
var angularPeity = angular.module( 'angular-peity', [] );
|
||||
|
||||
$.fn.peity.defaults.pie = {
|
||||
fill: ["#ff0000", "#aaaaaa"],
|
||||
radius: 4,
|
||||
}
|
||||
|
||||
var buildChartDirective = function ( chartType ) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
data: "=",
|
||||
options: "="
|
||||
},
|
||||
link: function ( scope, element, attrs ) {
|
||||
|
||||
var options = {};
|
||||
if ( scope.options ) {
|
||||
options = scope.options;
|
||||
}
|
||||
|
||||
// N.B. live-binding to data by Matthew
|
||||
scope.$watch('data', function () {
|
||||
var span = document.createElement( 'span' );
|
||||
span.textContent = scope.data.join();
|
||||
|
||||
if ( !attrs.class ) {
|
||||
span.className = "";
|
||||
} else {
|
||||
span.className = attrs.class;
|
||||
}
|
||||
|
||||
if (element[0].nodeType === 8) {
|
||||
element.replaceWith( span );
|
||||
}
|
||||
else if (element[0].firstChild) {
|
||||
element.empty();
|
||||
element[0].appendChild( span );
|
||||
}
|
||||
else {
|
||||
element[0].appendChild( span );
|
||||
}
|
||||
|
||||
jQuery( span ).peity( chartType, options );
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
angularPeity.directive( 'pieChart', function () {
|
||||
|
||||
return buildChartDirective( "pie" );
|
||||
|
||||
} );
|
||||
|
||||
|
||||
angularPeity.directive( 'barChart', function () {
|
||||
|
||||
return buildChartDirective( "bar" );
|
||||
|
||||
} );
|
||||
|
||||
|
||||
angularPeity.directive( 'lineChart', function () {
|
||||
|
||||
return buildChartDirective( "line" );
|
||||
|
||||
} );
|
|
@ -0,0 +1,13 @@
|
|||
// Peity jQuery plugin version 3.0.2
|
||||
// (c) 2014 Ben Pickles
|
||||
//
|
||||
// http://benpickles.github.io/peity
|
||||
//
|
||||
// Released under MIT license.
|
||||
(function(h,w,i,v){var p=function(a,b){var d=w.createElementNS("http://www.w3.org/2000/svg",a);h(d).attr(b);return d},y="createElementNS"in w&&p("svg",{}).createSVGRect,e=h.fn.peity=function(a,b){y&&this.each(function(){var d=h(this),c=d.data("peity");c?(a&&(c.type=a),h.extend(c.opts,b)):(c=new x(d,a,h.extend({},e.defaults[a],b)),d.change(function(){c.draw()}).data("peity",c));c.draw()});return this},x=function(a,b,d){this.$el=a;this.type=b;this.opts=d},r=x.prototype;r.draw=function(){e.graphers[this.type].call(this,
|
||||
this.opts)};r.fill=function(){var a=this.opts.fill;return h.isFunction(a)?a:function(b,d){return a[d%a.length]}};r.prepare=function(a,b){this.svg||this.$el.hide().after(this.svg=p("svg",{"class":"peity"}));return h(this.svg).empty().data("peity",this).attr({height:b,width:a})};r.values=function(){return h.map(this.$el.text().split(this.opts.delimiter),function(a){return parseFloat(a)})};e.defaults={};e.graphers={};e.register=function(a,b,d){this.defaults[a]=b;this.graphers[a]=d};e.register("pie",
|
||||
{fill:["#ff9900","#fff4dd","#ffc66e"],radius:8},function(a){if(!a.delimiter){var b=this.$el.text().match(/[^0-9\.]/);a.delimiter=b?b[0]:","}b=this.values();if("/"==a.delimiter)var d=b[0],b=[d,i.max(0,b[1]-d)];for(var c=0,d=b.length,n=0;c<d;c++)n+=b[c];for(var c=2*a.radius,f=this.prepare(a.width||c,a.height||c),c=f.width(),f=f.height(),s=c/2,k=f/2,f=i.min(s,k),a=a.innerRadius,e=i.PI,q=this.fill(),g=this.scale=function(a,b){var c=2*a/n*e-e/2;return[b*i.cos(c)+s,b*i.sin(c)+k]},l=0,c=0;c<d;c++){var t=
|
||||
b[c],j=t/n;if(0!=j){if(1==j)if(a)var j=s-0.01,o=k-f,m=k-a,j=p("path",{d:["M",s,o,"A",f,f,0,1,1,j,o,"L",j,m,"A",a,a,0,1,0,s,m].join(" ")});else j=p("circle",{cx:s,cy:k,r:f});else o=l+t,m=["M"].concat(g(l,f),"A",f,f,0,0.5<j?1:0,1,g(o,f),"L"),a?m=m.concat(g(o,a),"A",a,a,0,0.5<j?1:0,0,g(l,a)):m.push(s,k),l+=t,j=p("path",{d:m.join(" ")});h(j).attr("fill",q.call(this,t,c,b));this.svg.appendChild(j)}}});e.register("donut",h.extend(!0,{},e.defaults.pie),function(a){a.innerRadius||(a.innerRadius=0.5*a.radius);
|
||||
e.graphers.pie.call(this,a)});e.register("line",{delimiter:",",fill:"#c6d9fd",height:16,min:0,stroke:"#4d89f9",strokeWidth:1,width:32},function(a){var b=this.values();1==b.length&&b.push(b[0]);for(var d=i.max.apply(i,a.max==v?b:b.concat(a.max)),c=i.min.apply(i,a.min==v?b:b.concat(a.min)),n=this.prepare(a.width,a.height),f=a.strokeWidth,e=n.width(),k=n.height()-f,h=d-c,d=this.x=function(a){return a*(e/(b.length-1))},n=this.y=function(a){var b=k;h&&(b-=(a-c)/h*k);return b+f/2},q=n(i.max(c,0)),g=[0,
|
||||
q],l=0;l<b.length;l++)g.push(d(l),n(b[l]));g.push(e,q);this.svg.appendChild(p("polygon",{fill:a.fill,points:g.join(" ")}));f&&this.svg.appendChild(p("polyline",{fill:"transparent",points:g.slice(2,g.length-2).join(" "),stroke:a.stroke,"stroke-width":f,"stroke-linecap":"square"}))});e.register("bar",{delimiter:",",fill:["#4D89F9"],height:16,min:0,padding:0.1,width:32},function(a){for(var b=this.values(),d=i.max.apply(i,a.max==v?b:b.concat(a.max)),c=i.min.apply(i,a.min==v?b:b.concat(a.min)),e=this.prepare(a.width,
|
||||
a.height),f=e.width(),h=e.height(),k=d-c,a=a.padding,e=this.fill(),r=this.x=function(a){return a*f/b.length},q=this.y=function(a){return h-(k?(a-c)/k*h:1)},g=0;g<b.length;g++){var l=r(g+a),t=r(g+1-a)-l,j=b[g],o=q(j),m=o,u;k?0>j?m=q(i.min(d,0)):o=q(i.max(c,0)):u=1;u=o-m;0==u&&(u=1,0<d&&k&&m--);this.svg.appendChild(p("rect",{fill:e.call(this,j,g,b),x:l,y:m,width:t,height:u}))}})})(jQuery,document,Math);
|
|
@ -1,4 +1,13 @@
|
|||
/*** Mobile voodoo ***/
|
||||
|
||||
/** iPads **/
|
||||
@media all and (max-device-width: 768px) {
|
||||
#roomRecentsTableWrapper {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/** iPhones **/
|
||||
@media all and (max-device-width: 640px) {
|
||||
|
||||
#messageTableWrapper {
|
||||
|
@ -37,11 +46,16 @@
|
|||
max-width: 640px ! important;
|
||||
}
|
||||
|
||||
#controls {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#headerUserId,
|
||||
#roomHeader img,
|
||||
#userIdCell,
|
||||
#roomRecentsTableWrapper,
|
||||
#usersTableWrapper,
|
||||
#controlButtons,
|
||||
.extraControls {
|
||||
display: none;
|
||||
}
|
||||
|
@ -64,6 +78,10 @@
|
|||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.roomHeaderInfo {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
#roomName {
|
||||
font-size: 12px ! important;
|
||||
margin-top: 0px ! important;
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
||||
angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput', 'angular-peity'])
|
||||
.controller('RoomController', ['$modal', '$filter', '$scope', '$timeout', '$routeParams', '$location', '$rootScope', 'matrixService', 'mPresence', 'eventHandlerService', 'mFileUpload', 'matrixPhoneService', 'MatrixCall', 'notificationService', 'modelService',
|
||||
function($modal, $filter, $scope, $timeout, $routeParams, $location, $rootScope, matrixService, mPresence, eventHandlerService, mFileUpload, matrixPhoneService, MatrixCall, notificationService, modelService) {
|
||||
'use strict';
|
||||
|
@ -905,7 +905,20 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
|||
paginate(MESSAGES_PER_PAGINATION);
|
||||
};
|
||||
|
||||
$scope.checkWebRTC = function() {
|
||||
if (!$rootScope.isWebRTCSupported()) {
|
||||
alert("Your browser does not support WebRTC");
|
||||
return false;
|
||||
}
|
||||
if ($scope.memberCount() != 2) {
|
||||
alert("WebRTC calls are currently only supported on rooms with two members");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
$scope.startVoiceCall = function() {
|
||||
if (!$scope.checkWebRTC()) return;
|
||||
var call = new MatrixCall($scope.room_id);
|
||||
call.onError = $rootScope.onCallError;
|
||||
call.onHangup = $rootScope.onCallHangup;
|
||||
|
@ -916,6 +929,8 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
|||
};
|
||||
|
||||
$scope.startVideoCall = function() {
|
||||
if (!$scope.checkWebRTC()) return;
|
||||
|
||||
var call = new MatrixCall($scope.room_id);
|
||||
call.onError = $rootScope.onCallError;
|
||||
call.onHangup = $rootScope.onCallHangup;
|
||||
|
|
|
@ -15,6 +15,15 @@
|
|||
|
||||
<script type="text/ng-template" id="roomInfoTemplate.html">
|
||||
<div class="modal-body">
|
||||
<span>
|
||||
Invite a user:
|
||||
<input ng-model="userIDToInvite" size="32" type="text" ng-enter="inviteUser()" ng-disabled="state.permission_denied" placeholder="User ID (ex:@user:homeserver)"/>
|
||||
<button ng-click="inviteUser()" ng-disabled="state.permission_denied">Invite</button>
|
||||
</span>
|
||||
<br/>
|
||||
<br/>
|
||||
<button ng-click="leaveRoom()" ng-disabled="state.permission_denied">Leave Room</button>
|
||||
</br/>
|
||||
<table class="room-info">
|
||||
<tr ng-repeat="(key, event) in roomInfo.stateEvents" class="room-info-event">
|
||||
<td class="room-info-event-meta" width="30%">
|
||||
|
@ -57,6 +66,26 @@
|
|||
|
||||
<div id="roomHeader">
|
||||
<a href ng-click="goToPage('/')"><img src="img/logo-small.png" width="100" height="43" alt="[matrix]"/></a>
|
||||
|
||||
<div id="controlButtons">
|
||||
<button ng-click="startVoiceCall()" class="controlButton"
|
||||
style="background: url('img/voice.png')"
|
||||
ng-show="(currentCall == undefined || currentCall.state == 'ended')"
|
||||
ng-disabled="state.permission_denied"
|
||||
>
|
||||
</button>
|
||||
<button ng-click="startVideoCall()" class="controlButton"
|
||||
style="background: url('img/video.png')"
|
||||
ng-show="(currentCall == undefined || currentCall.state == 'ended')"
|
||||
ng-disabled="state.permission_denied"
|
||||
>
|
||||
</button>
|
||||
<button ng-click="openRoomInfo()" class="controlButton"
|
||||
style="background: url('img/settings.png')"
|
||||
>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="roomHeaderInfo">
|
||||
|
||||
<div class="roomNameSection">
|
||||
|
@ -93,30 +122,28 @@
|
|||
</div>
|
||||
|
||||
<div id="usersTableWrapper" ng-hide="state.permission_denied">
|
||||
<table id="usersTable">
|
||||
<tr ng-repeat="member in members | orderMembersList">
|
||||
<td class="userAvatar mouse-pointer" ng-click="$parent.goToUserPage(member.id)" ng-class="member.membership == 'invite' ? 'invited' : ''">
|
||||
<img class="userAvatarImage"
|
||||
ng-src="{{member.avatar_url || 'img/default-profile.png'}}"
|
||||
alt="{{ member.displayname || member.id.substr(0, member.id.indexOf(':')) }}"
|
||||
title="{{ member.id }} - power: {{ member.powerLevel }}"
|
||||
width="80" height="80"/>
|
||||
<img class="userAvatarGradient" src="img/gradient.png" title="{{ member.id }}" width="80" height="24"/>
|
||||
<div class="userPowerLevel" ng-style="{'width': member.powerLevelNorm +'%'}"></div>
|
||||
<div class="userName">
|
||||
<div ng-show="member.displayname">
|
||||
{{ member.id | mUserDisplayName: room_id }}
|
||||
</div>
|
||||
<div ng-hide="member.displayname">
|
||||
{{ member.id.substr(0, member.id.indexOf(':')) }}<br/>
|
||||
{{ member.id.substr(member.id.indexOf(':')) }}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="userPresence" ng-class="(member.presence === 'online' ? 'online' : (member.presence === 'unavailable' ? 'unavailable' : '')) + ' ' + (member.membership == 'invite' ? 'invited' : '')">
|
||||
<span ng-show="member.last_active_ago">{{ member.last_active_ago + (now - member.last_updated) | duration }}<br/>ago</span>
|
||||
</td>
|
||||
</table>
|
||||
<div ng-repeat="member in members | orderMembersList" class="userAvatar">
|
||||
<div class="userAvatarFrame" ng-class="(member.presence === 'online' ? 'online' : (member.presence === 'unavailable' ? 'unavailable' : '')) + ' ' + (member.membership == 'invite' ? 'invited' : '')">
|
||||
<img class="userAvatarImage mouse-pointer"
|
||||
ng-click="$parent.goToUserPage(member.id)"
|
||||
ng-src="{{member.avatar_url || 'img/default-profile.png'}}"
|
||||
alt="{{ member.displayname || member.id.substr(0, member.id.indexOf(':')) }}"
|
||||
title="{{ member.id }} - power: {{ member.powerLevel }}"
|
||||
width="80" height="80"/>
|
||||
<!-- <div class="userPowerLevel" ng-style="{'width': member.powerLevelNorm +'%'}"></div> -->
|
||||
</div>
|
||||
<div class="userName">
|
||||
<pie-chart ng-show="member.powerLevelNorm" data="[ (member.powerLevelNorm + 0), (100 - member.powerLevelNorm) ]"></pie-chart>
|
||||
<span ng-show="member.displayname">
|
||||
{{ member.id | mUserDisplayName: room_id }}
|
||||
</span>
|
||||
<span ng-hide="member.displayname">
|
||||
{{ member.id.substr(0, member.id.indexOf(':')) }}<br/>
|
||||
{{ member.id.substr(member.id.indexOf(':')) }}
|
||||
</span>
|
||||
<span ng-show="member.last_active_ago" style="color: #aaa">({{ member.last_active_ago + (now - member.last_updated) | duration }})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="messageTableWrapper"
|
||||
|
@ -126,19 +153,20 @@
|
|||
<table id="messageTable" infinite-scroll="paginateMore()">
|
||||
<tr ng-repeat="msg in room.events"
|
||||
ng-class="(room.events[$index + 1].user_id !== msg.user_id ? 'differentUser' : '') + (msg.user_id === state.user_id ? ' mine' : '')" scroll-item>
|
||||
<td class="leftBlock">
|
||||
<div class="sender" ng-hide="room.events[$index - 1].user_id === msg.user_id"> {{ msg.__room_member.cnt.displayname || msg.user_id | mUserDisplayName: room_id }}</div>
|
||||
<td class="leftBlock" ng-mouseover="state.showTs = 1" ng-mouseout="state.showTs = 0">
|
||||
<div class="timestamp"
|
||||
ng-style="{ 'opacity': state.showTs ? 1.0 : 0.0 }"
|
||||
ng-class="msg.echo_msg_state">
|
||||
{{ (msg.origin_server_ts) | date:'MMM d HH:mm' }}
|
||||
</div>
|
||||
<div class="sender" ng-hide="room.events[$index - 1].user_id === msg.user_id || msg.user_id === state.user_id"> {{ msg.__room_member.cnt.displayname || msg.user_id | mUserDisplayName: room_id }}</div>
|
||||
</td>
|
||||
<td class="avatar">
|
||||
<!-- msg.__room_member.avatar_url is just backwards compat, and can be removed in the future. -->
|
||||
<img class="avatarImage" ng-src="{{ msg.__room_member.cnt.avatar_url || msg.__room_member.avatar_url || 'img/default-profile.png' }}" width="32" height="32" title="{{msg.user_id}}"
|
||||
ng-hide="room.events[$index - 1].user_id === msg.user_id || msg.user_id === state.user_id"/>
|
||||
</td>
|
||||
<td ng-class="(!msg.content.membership && ('m.room.topic' !== msg.type && 'm.room.name' !== msg.type))? (msg.content.msgtype === 'm.emote' ? 'emote text' : 'text') : 'membership text'">
|
||||
<td style="vertical-align: bottom" ng-class="(!msg.content.membership && ('m.room.topic' !== msg.type && 'm.room.name' !== msg.type))? (msg.content.msgtype === 'm.emote' ? 'emote text' : 'text') : 'membership text'">
|
||||
<div class="bubble" ng-dblclick="openJson(msg)">
|
||||
<span ng-if="'join' === msg.content.membership && msg.changedKey === 'membership'">
|
||||
{{ msg.content.displayname || members[msg.state_key].displayname || msg.state_key }} joined
|
||||
|
@ -222,49 +250,10 @@
|
|||
|
||||
<div id="controlPanel">
|
||||
<div id="controls">
|
||||
<table id="inputBarTable">
|
||||
<tr>
|
||||
<td id="userIdCell" width="1px">
|
||||
{{ state.user_id }}
|
||||
</td>
|
||||
<td width="*">
|
||||
<textarea id="mainInput" rows="1" ng-enter="send()"
|
||||
ng-disabled="state.permission_denied"
|
||||
ng-focus="true" autocomplete="off" tab-complete command-history/>
|
||||
</td>
|
||||
<td id="buttonsCell">
|
||||
<button ng-click="send()" ng-disabled="state.permission_denied">Send</button>
|
||||
<button m-file-input="imageFileToSend" class="extraControls" ng-disabled="state.permission_denied">Image</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="extraControls">
|
||||
<span>
|
||||
Invite a user:
|
||||
<input ng-model="userIDToInvite" size="32" type="text" ng-enter="inviteUser()" ng-disabled="state.permission_denied" placeholder="User ID (ex:@user:homeserver)"/>
|
||||
<button ng-click="inviteUser()" ng-disabled="state.permission_denied">Invite</button>
|
||||
</span>
|
||||
<button ng-click="leaveRoom()" ng-disabled="state.permission_denied">Leave</button>
|
||||
<button ng-click="startVoiceCall()"
|
||||
ng-show="(currentCall == undefined || currentCall.state == 'ended')"
|
||||
ng-disabled="state.permission_denied || !isWebRTCSupported() || memberCount() != 2"
|
||||
title ="{{ !isWebRTCSupported() ? 'VoIP requires webRTC but your browser does not support it' : (memberCount() == 2 ? '' : 'VoIP calls can only be made in rooms with two participants') }}"
|
||||
>
|
||||
Voice Call
|
||||
</button>
|
||||
<button ng-click="startVideoCall()"
|
||||
ng-show="(currentCall == undefined || currentCall.state == 'ended')"
|
||||
ng-disabled="state.permission_denied || !isWebRTCSupported() || memberCount() != 2"
|
||||
title ="{{ !isWebRTCSupported() ? 'VoIP requires webRTC but your browser does not support it' : (memberCount() == 2 ? '' : 'VoIP calls can only be made in rooms with two participants') }}"
|
||||
>
|
||||
Video Call
|
||||
</button>
|
||||
<button ng-click="openRoomInfo()">
|
||||
Room Info
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button id="attachButton" m-file-input="imageFileToSend" class="extraControls" ng-disabled="state.permission_denied"></button>
|
||||
<textarea id="mainInput" rows="1" ng-enter="send()"
|
||||
ng-disabled="state.permission_denied"
|
||||
ng-focus="true" autocomplete="off" tab-complete command-history/>
|
||||
{{ feedback }}
|
||||
<div ng-show="state.stream_failure">
|
||||
{{ state.stream_failure.data.error || "Connection failure" }}
|
||||
|
|
Loading…
Reference in New Issue