diff --git a/syweb/webclient/room/room-controller.js b/syweb/webclient/room/room-controller.js
deleted file mode 100644
index df05a8e573..0000000000
--- a/syweb/webclient/room/room-controller.js
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
-Copyright 2014 OpenMarket Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput', 'angular-peity'])
-.controller('RoomController', ['$modal', '$filter', '$scope', '$timeout', '$routeParams', '$location', '$rootScope', 'matrixService', 'mPresence', 'eventHandlerService', 'mFileUpload', 'matrixPhoneService', 'MatrixCall', 'modelService', 'recentsService', 'commandsService', 'mUserDisplayNameFilter',
- function($modal, $filter, $scope, $timeout, $routeParams, $location, $rootScope, matrixService, mPresence, eventHandlerService, mFileUpload, matrixPhoneService, MatrixCall, modelService, recentsService, commandsService, mUserDisplayNameFilter) {
- 'use strict';
- var MESSAGES_PER_PAGINATION = 30;
- var THUMBNAIL_SIZE = 320;
-
- // .html needs this
- $scope.containsBingWord = eventHandlerService.eventContainsBingWord;
-
- // Room ids. Computed and resolved in onInit
- $scope.room_id = undefined;
-
- $scope.state = {
- user_id: matrixService.config().user_id,
- permission_denied: undefined, // If defined, this string contains the reason why the user cannot join the room
- first_pagination: true, // this is toggled off when the first pagination is done
- can_paginate: false, // this is toggled off when we are not ready yet to paginate or when we run out of items
- paginating: false, // used to avoid concurrent pagination requests pulling in dup contents
- stream_failure: undefined, // the response when the stream fails
- waiting_for_joined_event: false, // true when the join request is pending. Back to false once the corresponding m.room.member event is received
- messages_visibility: "hidden", // In order to avoid flickering when scrolling down the message table at the page opening, delay the message table display
- };
-
- $scope.imageURLToSend = "";
-
-
- // vars and functions for updating the name
- $scope.name = {
- isEditing: false,
- newNameText: "",
- editName: function() {
- if ($scope.name.isEditing) {
- console.log("Warning: Already editing name.");
- return;
- };
-
- var nameEvent = $scope.room.current_room_state.state_events['m.room.name'];
- if (nameEvent) {
- $scope.name.newNameText = nameEvent.content.name;
- }
- else {
- $scope.name.newNameText = "";
- }
-
- // Force focus to the input
- $timeout(function() {
- angular.element('.roomNameInput').focus();
- }, 0);
-
- $scope.name.isEditing = true;
- },
- updateName: function() {
- console.log("Updating name to "+$scope.name.newNameText);
- matrixService.setName($scope.room_id, $scope.name.newNameText).then(
- function() {
- },
- function(error) {
- $scope.feedback = "Request failed: " + error.data.error;
- }
- );
-
- $scope.name.isEditing = false;
- },
- cancelEdit: function() {
- $scope.name.isEditing = false;
- }
- };
-
- // vars and functions for updating the topic
- $scope.topic = {
- isEditing: false,
- newTopicText: "",
- editTopic: function() {
- if ($scope.topic.isEditing) {
- console.log("Warning: Already editing topic.");
- return;
- }
- var topicEvent = $scope.room.current_room_state.state_events['m.room.topic'];
- if (topicEvent) {
- $scope.topic.newTopicText = topicEvent.content.topic;
- }
- else {
- $scope.topic.newTopicText = "";
- }
-
- // Force focus to the input
- $timeout(function() {
- angular.element('.roomTopicInput').focus();
- }, 0);
-
- $scope.topic.isEditing = true;
- },
- updateTopic: function() {
- console.log("Updating topic to "+$scope.topic.newTopicText);
- matrixService.setTopic($scope.room_id, $scope.topic.newTopicText).then(
- function() {
- },
- function(error) {
- $scope.feedback = "Request failed: " + error.data.error;
- }
- );
-
- $scope.topic.isEditing = false;
- },
- cancelEdit: function() {
- $scope.topic.isEditing = false;
- }
- };
-
- var scrollToBottom = function(force) {
- console.log("Scrolling to bottom");
-
- // Do not autoscroll to the bottom to display the new event if the user is not at the bottom.
- // Exception: in case where the event is from the user, we want to force scroll to the bottom
- var objDiv = document.getElementById("messageTableWrapper");
- // add a 10px buffer to this check so if the message list is not *quite*
- // at the bottom it still scrolls since it basically is at the bottom.
- if ((10 + objDiv.offsetHeight + objDiv.scrollTop >= objDiv.scrollHeight) || force) {
-
- $timeout(function() {
- objDiv.scrollTop = objDiv.scrollHeight;
-
- // Show the message table once the first scrolldown is done
- if ("visible" !== $scope.state.messages_visibility) {
- $timeout(function() {
- $scope.state.messages_visibility = "visible";
- }, 0);
- }
- }, 0);
- }
- };
-
- $scope.$on(eventHandlerService.MSG_EVENT, function(ngEvent, event, isLive) {
- if (isLive && event.room_id === $scope.room_id) {
- scrollToBottom();
- }
- });
-
- $scope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) {
- // if there is a live event affecting us
- if (isLive && event.room_id === $scope.room_id && event.state_key === $scope.state.user_id) {
- // if someone else changed our state..
- if (event.user_id !== $scope.state.user_id && "invite" !== event.content.membership && "join" !== event.content.membership) {
- if ("ban" === event.content.membership) {
- $scope.state.permission_denied = "You have been banned by " + mUserDisplayNameFilter(event.user_id);
- }
- else {
- $scope.state.permission_denied = "You have been kicked by " + mUserDisplayNameFilter(event.user_id);
- }
- }
- else {
- scrollToBottom();
- }
- }
- });
-
- $scope.memberCount = function() {
- return Object.keys($scope.room.now.members).length;
- };
-
- $scope.paginateMore = function() {
- if ($scope.state.can_paginate) {
- // console.log("Paginating more.");
- paginate(MESSAGES_PER_PAGINATION);
- }
- };
-
- var paginate = function(numItems) {
- //console.log("paginate " + numItems + " and first_pagination is " + $scope.state.first_pagination);
- if ($scope.state.paginating || !$scope.room_id) {
- return;
- }
- else {
- $scope.state.paginating = true;
- }
-
- console.log("paginateBackMessages from " + $scope.room.old_room_state.pagination_token + " for " + numItems);
- var originalTopRow = $("#messageTable>tbody>tr:first")[0];
-
- // Paginate events from the point in cache
- matrixService.paginateBackMessages($scope.room_id, $scope.room.old_room_state.pagination_token, numItems).then(
- function(response) {
-
- eventHandlerService.handleRoomMessages($scope.room_id, response.data, false, 'b');
- if (response.data.chunk.length < MESSAGES_PER_PAGINATION) {
- // no more messages to paginate. this currently never gets turned true again, as we never
- // expire paginated contents in the current implementation.
- $scope.state.can_paginate = false;
- }
-
- $scope.state.paginating = false;
-
- var wrapper = $("#messageTableWrapper")[0];
- var table = $("#messageTable")[0];
- // console.log("wrapper height=" + wrapper.clientHeight + ", table scrollHeight=" + table.scrollHeight);
-
- if ($scope.state.can_paginate) {
- // check we don't have to pull in more messages
- // n.b. we dispatch through a timeout() to allow the digest to run otherwise the .height methods are stale
- $timeout(function() {
- if (table.scrollHeight < wrapper.clientHeight) {
- paginate(MESSAGES_PER_PAGINATION);
- scrollToBottom();
- }
- }, 0);
- }
-
- if ($scope.state.first_pagination) {
- scrollToBottom(true);
- $scope.state.first_pagination = false;
- }
- else {
- // lock the scroll position
- $timeout(function() {
- // FIXME: this risks a flicker before the scrollTop is actually updated, but we have to
- // dispatch it into a function in order to first update the layout. The right solution
- // might be to implement it as a directive, more like
- // http://stackoverflow.com/questions/23736647/how-to-retain-scroll-position-of-ng-repeat-in-angularjs
- // however, this specific solution breaks because it measures the rows height before
- // the contents are interpolated.
- wrapper.scrollTop = originalTopRow ? (originalTopRow.offsetTop + wrapper.scrollTop) : 0;
- }, 0);
- }
- },
- function(error) {
- console.log("Failed to paginateBackMessages: " + JSON.stringify(error));
- $scope.state.paginating = false;
- }
- );
- };
-
- var updatePresenceTimes = function() {
- $scope.now = new Date().getTime();
- // TODO: don't bother polling every 5s if we know none of our counters are younger than 1 minute
- $timeout(updatePresenceTimes, 5 * 1000);
- };
-
- $scope.send = function() {
- var input = $('#mainInput').val();
-
- if (undefined === input || input === "") {
- return;
- }
-
- scrollToBottom(true);
-
- // Store the command in the history
- $rootScope.$broadcast("commandHistory:BROADCAST_NEW_HISTORY_ITEM(item)",
- input);
-
- var isEmote = input.indexOf("/me ") === 0;
- var promise;
- if (!isEmote) {
- promise = commandsService.processInput($scope.room_id, input);
- }
- var echo = false;
-
-
- if (!promise) { // not a non-echoable command
- echo = true;
- if (isEmote) {
- promise = matrixService.sendEmoteMessage($scope.room_id, input.substring(4));
- }
- else {
- promise = matrixService.sendTextMessage($scope.room_id, input);
- }
- }
-
- if (echo) {
- // Echo the message to the room
- // To do so, create a minimalist fake text message event and add it to the in-memory list of room messages
- var echoMessage = {
- content: {
- body: (isEmote ? input.substring(4) : input),
- msgtype: (isEmote ? "m.emote" : "m.text"),
- },
- origin_server_ts: new Date().getTime(), // fake a timestamp
- room_id: $scope.room_id,
- type: "m.room.message",
- user_id: $scope.state.user_id,
- echo_msg_state: "messagePending" // Add custom field to indicate the state of this fake message to HTML
- };
-
- $('#mainInput').val('');
- $scope.room.addMessageEvent(echoMessage);
- scrollToBottom();
- }
-
- if (promise) {
- // Reset previous feedback
- $scope.feedback = "";
-
- promise.then(
- function(response) {
- console.log("Request successfully sent");
-
- if (echo) {
- // Mark this fake message event with its allocated event_id
- // When the true message event will come from the events stream (in handleMessage),
- // we will be able to replace the fake one by the true one
- echoMessage.event_id = response.data.event_id;
- }
- else {
- $('#mainInput').val('');
- }
- },
- function(error) {
- $scope.feedback = error.data.error;
-
- if (echoMessage) {
- // Mark the message as unsent for the rest of the page life
- echoMessage.origin_server_ts = "Unsent";
- echoMessage.echo_msg_state = "messageUnSent";
- }
- });
- }
- };
-
- // Tries to find a suitable room ID for this room.
- $scope.onInit = function() {
- console.log("onInit");
-
- // Extract the room identifier being loaded
- var room_id_or_alias;
- if ($routeParams.room_id_or_alias) { // provided in the url
- room_id_or_alias = decodeURIComponent($routeParams.room_id_or_alias);
- }
-
- eventHandlerService.joinRoom(room_id_or_alias).then(function(roomId) {
- $scope.room_id = roomId;
- $scope.room = modelService.getRoom($scope.room_id);
-
- var messages = $scope.room.events;
-
- if (0 === messages.length
- || (1 === messages.length && "m.room.member" === messages[0].type && "invite" === messages[0].content.membership && $scope.state.user_id === messages[0].state_key)) {
- // If we just joined a room, we won't have this history from initial sync, so we should try to paginate it anyway
- $scope.state.first_pagination = true;
- }
- else {
- // There is no need to do a 1st pagination (initialSync provided enough to fill a page)
- $scope.state.first_pagination = false;
- }
-
- // Make recents highlight the current room
- recentsService.setSelectedRoomId($scope.room_id);
-
- updatePresenceTimes();
-
- // Allow pagination
- $scope.state.can_paginate = true;
-
- // Do a first pagination only if it is required (e.g. we've JUST joined a room and have no messages to display.)
- // FIXME: Should be no more require when initialSync/{room_id} will be available
- if ($scope.state.first_pagination) {
- paginate(MESSAGES_PER_PAGINATION);
- }
-
- // Scroll down as soon as possible so that we point to the last message
- // if it already exists in memory
- scrollToBottom(true);
- },
- function(err) {
- if (err.data.errcode === "M_FORBIDDEN") {
- $scope.state.permission_denied = "You do not have permission to join this room";
- }
- else {
- console.log("Error: cannot join room: "+JSON.stringify(err));
- $location.url("/");
- }
- });
- };
-
- $scope.leaveRoom = function() {
-
- matrixService.leave($scope.room_id).then(
- function(response) {
- console.log("Left room " + $scope.room_id);
- $location.url("home");
- },
- function(error) {
- $scope.feedback = "Failed to leave room: " + error.data.error;
- });
- };
-
- // used to send an image based on just a URL, rather than uploading one
- $scope.sendImage = function(url, body) {
- scrollToBottom(true);
-
- matrixService.sendImageMessage($scope.room_id, url, body).then(
- function() {
- console.log("Image sent");
- },
- function(error) {
- $scope.feedback = "Failed to send image: " + error.data.error;
- });
- };
-
- $scope.fileToSend;
- $scope.$watch("fileToSend", function(newValue, oldValue) {
- if ($scope.fileToSend) {
- // Upload this file
- mFileUpload.uploadFileAndThumbnail($scope.fileToSend, THUMBNAIL_SIZE).then(
- function(fileMessage) {
- // fileMessage is complete message structure, send it as is
- matrixService.sendMessage($scope.room_id, undefined, fileMessage).then(
- function() {
- console.log("File message sent");
- },
- function(error) {
- $scope.feedback = "Failed to send file message: " + error.data.error;
- });
- },
- function(error) {
- $scope.feedback = "Can't upload file";
- }
- );
- }
- });
-
- $scope.loadMoreHistory = function() {
- 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;
- // remote video element is used for playing audio in voice calls
- call.remoteVideoSelector = angular.element('#remoteVideo')[0];
- call.placeVoiceCall();
- $rootScope.currentCall = call;
- };
-
- $scope.startVideoCall = function() {
- if (!$scope.checkWebRTC()) return;
-
- var call = new MatrixCall($scope.room_id);
- call.onError = $rootScope.onCallError;
- call.onHangup = $rootScope.onCallHangup;
- call.localVideoSelector = '#localVideo';
- call.remoteVideoSelector = '#remoteVideo';
- call.placeVideoCall();
- $rootScope.currentCall = call;
- };
-
- $scope.openJson = function(content) {
- $scope.event_selected = angular.copy(content);
-
- // FIXME: Pre-calculated event data should be stripped in a nicer way.
- $scope.event_selected.__room_member = undefined;
- $scope.event_selected.__target_room_member = undefined;
-
- // scope this so the template can check power levels and enable/disable
- // buttons
- $scope.pow = modelService.getUserPowerLevel;
-
- var modalInstance = $modal.open({
- templateUrl: 'eventInfoTemplate.html',
- controller: 'EventInfoController',
- scope: $scope
- });
-
- modalInstance.result.then(function(action) {
- if (action === "redact") {
- var eventId = $scope.event_selected.event_id;
- console.log("Redacting event ID " + eventId);
- matrixService.redactEvent(
- $scope.event_selected.room_id,
- eventId
- ).then(function(response) {
- console.log("Redaction = " + JSON.stringify(response));
- }, function(error) {
- console.error("Failed to redact event: "+JSON.stringify(error));
- if (error.data.error) {
- $scope.feedback = error.data.error;
- }
- });
- }
- }, function() {
- // any dismiss code
- });
- };
-
- $scope.openRoomInfo = function() {
- $scope.roomInfo = {};
- $scope.roomInfo.newEvent = {
- content: {},
- type: "",
- state_key: ""
- };
-
- var stateEvents = $scope.room.current_room_state.state_events;
- // The modal dialog will 2-way bind this field, so we MUST make a deep
- // copy of the state events else we will be *actually adjusing our view
- // of the world* when fiddling with the JSON!! Apparently parse/stringify
- // is faster than jQuery's extend when doing deep copies.
- $scope.roomInfo.stateEvents = JSON.parse(JSON.stringify(stateEvents));
- var modalInstance = $modal.open({
- templateUrl: 'roomInfoTemplate.html',
- controller: 'RoomInfoController',
- size: 'lg',
- scope: $scope
- });
- };
-
-}])
-.controller('EventInfoController', function($scope, $modalInstance) {
- console.log("Displaying modal dialog for >>>> " + JSON.stringify($scope.event_selected));
- $scope.redact = function() {
- console.log("User level = "+$scope.pow($scope.room_id, $scope.state.user_id)+
- " Redact level = "+$scope.room.current_room_state.state_events["m.room.ops_levels"].content.redact_level);
- console.log("Redact event >> " + JSON.stringify($scope.event_selected));
- $modalInstance.close("redact");
- };
- $scope.dismiss = $modalInstance.dismiss;
-})
-.controller('RoomInfoController', function($scope, $modalInstance, $filter, matrixService) {
- console.log("Displaying room info.");
-
- $scope.userIDToInvite = "";
-
- $scope.inviteUser = function() {
-
- matrixService.invite($scope.room_id, $scope.userIDToInvite).then(
- function() {
- console.log("Invited.");
- $scope.feedback = "Invite successfully sent to " + $scope.userIDToInvite;
- $scope.userIDToInvite = "";
- },
- function(reason) {
- $scope.feedback = "Failure: " + reason.data.error;
- });
- };
-
- $scope.submit = function(event) {
- if (event.content) {
- console.log("submit >>> " + JSON.stringify(event.content));
- matrixService.sendStateEvent($scope.room_id, event.type,
- event.content, event.state_key).then(function(response) {
- $modalInstance.dismiss();
- }, function(err) {
- $scope.feedback = err.data.error;
- }
- );
- }
- };
-
- $scope.dismiss = $modalInstance.dismiss;
-
-});
|