forked-synapse/webclient/room/room.html
Kegan Dougal 9de9661baa SYWEB-12: More formatting and tweaking of state event JSON.
Use a proper elastic directive to make the <textarea> resize dynamically.
Use an 'asjson' directive to turn an ngModel of a JSON object into a
formatted JSON string so it can be displayed on the textarea. Also, deep
copy the state events being displayed, else it actually alters the underlying
data structures when playing around with the JSON in the textarea!
2014-10-30 16:21:27 +00:00

264 lines
15 KiB
HTML

<div ng-controller="RoomController" data-ng-init="onInit()" class="room" style="height: 100%;">
<script type="text/ng-template" id="eventInfoTemplate.html">
<div class="modal-body">
<pre> {{event_selected | json}} </pre>
</div>
<div class="modal-footer">
<button ng-click="redact()" type="button" class="btn btn-danger"
ng-disabled="!events.rooms[room_id]['m.room.ops_levels'].content.redact_level || !pow(room_id, state.user_id) || pow(room_id, state.user_id) < events.rooms[room_id]['m.room.ops_levels'].content.redact_level"
title="Delete this event on all home servers. This cannot be undone.">
Redact
</button>
</div>
</script>
<script type="text/ng-template" id="roomInfoTemplate.html">
<div class="modal-body">
<table class="room-info">
<tr ng-repeat="(key, event) in roomInfoStateEvents" class="room-info-event">
<td class="room-info-event-meta" width="30%">
<span class="monospace">{{ key }}</span>
<br/>
{{ (event.origin_server_ts) | date:'MMM d HH:mm' }}
<br/>
Set by: <span class="monospace">{{ event.user_id }}</span>
<br/>
<button ng-click="submit(event)" type="button" class="btn btn-success">
Submit
</button>
</td>
<td class="room-info-event-content" width="70%">
<textarea class="room-info-textarea-content" msd-elastic ng-model="event.content" asjson></textarea>
</td>
</tr>
</table>
</div>
<div class="modal-footer">
<button ng-click="dismiss()" type="button" class="btn">
Close
</button>
</div>
</script>
<div id="roomHeader">
<a href ng-click="goToPage('/')"><img src="img/logo-small.png" width="100" height="43" alt="[matrix]"/></a>
<div class="roomHeaderInfo">
<div class="roomNameSection">
<div ng-hide="name.isEditing" ng-dblclick="name.editName()" id="roomName">
{{ room_id | mRoomName }}
</div>
<form ng-submit="name.updateName()" ng-show="name.isEditing" class="roomNameForm">
<input ng-model="name.newNameText" ng-blur="name.cancelEdit()" class="roomNameInput" placeholder="Room name"/>
</form>
</div>
<div class="roomTopicSection">
<button ng-hide="events.rooms[room_id]['m.room.topic'].content.topic || topic.isEditing"
ng-click="topic.editTopic()" class="roomTopicSetNew">
Set Topic
</button>
<div ng-show="events.rooms[room_id]['m.room.topic'].content.topic || topic.isEditing">
<div ng-hide="topic.isEditing" ng-dblclick="topic.editTopic()" id="roomTopic">
{{ events.rooms[room_id]['m.room.topic'].content.topic | limitTo: 200}}
</div>
<form ng-submit="topic.updateTopic()" ng-show="topic.isEditing" class="roomTopicForm">
<input ng-model="topic.newTopicText" ng-blur="topic.cancelEdit()" class="roomTopicInput" placeholder="Topic"/>
</form>
</div>
</div>
</div>
</div>
<div id="roomPage">
<div id="roomWrapper">
<div id="roomRecentsTableWrapper">
<div ng-include="'recents/recents.html'"></div>
</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>
<div id="messageTableWrapper"
ng-hide="state.permission_denied"
ng-style="{ 'visibility': state.messages_visibility }"
keep-scroll>
<table id="messageTable" infinite-scroll="paginateMore()">
<tr ng-repeat="msg in events.rooms[room_id].messages"
ng-class="(events.rooms[room_id].messages[$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="events.rooms[room_id].messages[$index - 1].user_id === msg.user_id"> {{ msg.user_id | mUserDisplayName: room_id }}</div>
<div class="timestamp"
ng-class="msg.echo_msg_state">
{{ (msg.origin_server_ts) | date:'MMM d HH:mm' }}
</div>
</td>
<td class="avatar">
<img class="avatarImage" ng-src="{{ members[msg.user_id].avatar_url || 'img/default-profile.png' }}" width="32" height="32"
ng-hide="events.rooms[room_id].messages[$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'">
<div class="bubble" ng-click="openJson(msg)">
<span ng-if="'join' === msg.content.membership && msg.changedKey === 'membership'">
{{ members[msg.state_key].displayname || msg.state_key }} joined
</span>
<span ng-if="'leave' === msg.content.membership && msg.changedKey === 'membership'">
<span ng-if="msg.user_id === msg.state_key">
{{ members[msg.state_key].displayname || msg.state_key }} left
</span>
<span ng-if="msg.user_id !== msg.state_key && msg.prev_content">
{{ members[msg.user_id].displayname || msg.user_id }}
{{ {"invite": "kicked", "join": "kicked", "ban": "unbanned"}[msg.prev_content.membership] }}
{{ members[msg.state_key].displayname || msg.state_key }}
<span ng-if="'join' === msg.prev_content.membership && msg.content.reason">
: {{ msg.content.reason }}
</span>
</span>
</span>
<span ng-if="'invite' === msg.content.membership && msg.changedKey === 'membership' ||
'ban' === msg.content.membership && msg.changedKey === 'membership'">
{{ members[msg.user_id].displayname || msg.user_id }}
{{ {"invite": "invited", "ban": "banned"}[msg.content.membership] }}
{{ members[msg.state_key].displayname || msg.state_key }}
<span ng-if="msg.prev_content && 'ban' === msg.prev_content.membership && msg.content.reason">
: {{ msg.content.reason }}
</span>
</span>
<span ng-if="msg.changedKey === 'displayname'">
{{ msg.user_id }} changed their display name from {{ msg.prev_content.displayname }} to {{ msg.content.displayname }}
</span>
<span ng-show='msg.content.msgtype === "m.emote"'
ng-class="msg.echo_msg_state"
ng-bind-html="'* ' + (members[msg.user_id].displayname || msg.user_id) + ' ' + msg.content.body | linky:'_blank'"
/>
<span ng-show='msg.content.msgtype === "m.text"'
class="message"
ng-class="containsBingWord(msg.content.body) && msg.user_id != state.user_id ? msg.echo_msg_state + ' messageBing' : msg.echo_msg_state"
ng-bind-html="(msg.content.msgtype === 'm.text' && msg.type === 'm.room.message' && msg.content.format === 'org.matrix.custom.html') ?
(msg.content.formatted_body | unsanitizedLinky) :
(msg.content.msgtype === 'm.text' && msg.type === 'm.room.message') ? (msg.content.body | linky:'_blank') : '' "/>
<span ng-show='msg.type === "m.call.invite" && msg.user_id == state.user_id'>Outgoing Call{{ isWebRTCSupported ? '' : ' (But your browser does not support VoIP)' }}</span>
<span ng-show='msg.type === "m.call.invite" && msg.user_id != state.user_id'>Incoming Call{{ isWebRTCSupported ? '' : ' (But your browser does not support VoIP)' }}</span>
<div ng-show='msg.content.msgtype === "m.image"'>
<div ng-hide='msg.content.thumbnail_url' ng-style="msg.content.body.h && { 'height' : (msg.content.body.h < 320) ? msg.content.body.h : 320}">
<img class="image" ng-src="{{ msg.content.url }}"/>
</div>
<div ng-show='msg.content.thumbnail_url' ng-style="{ 'height' : msg.content.thumbnail_info.h }">
<img class="image mouse-pointer" ng-src="{{ msg.content.thumbnail_url }}"
ng-click="$parent.fullScreenImageURL = msg.content.url; $event.stopPropagation();"/>
</div>
</div>
<span ng-if="'m.room.topic' === msg.type">
{{ members[msg.user_id].displayname || msg.user_id }} changed the topic to: {{ msg.content.topic }}
</span>
<span ng-if="'m.room.name' === msg.type">
{{ members[msg.user_id].displayname || msg.user_id }} changed the room name to: {{ msg.content.name }}
</span>
</div>
</td>
<td class="rightBlock">
<img class="avatarImage" ng-src="{{ members[msg.user_id].avatar_url || 'img/default-profile.png' }}" width="32" height="32"
ng-hide="events.rooms[room_id].messages[$index - 1].user_id === msg.user_id || msg.user_id !== state.user_id"/>
</td>
</tr>
</table>
</div>
<div ng-show="state.permission_denied">
{{ state.permission_denied }}
</div>
</div>
</div>
<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>
{{ feedback }}
<div ng-show="state.stream_failure">
{{ state.stream_failure.data.error || "Connection failure" }}
</div>
</div>
</div>
<div id="room-fullscreen-image" ng-show="fullScreenImageURL" ng-click="fullScreenImageURL = undefined;">
<img ng-src="{{ fullScreenImageURL }}"/>
</div>
</div>