diff --git a/webclient/app-controller.js b/webclient/app-controller.js index 92ad01e4f..84cb94dc7 100644 --- a/webclient/app-controller.js +++ b/webclient/app-controller.js @@ -31,31 +31,15 @@ angular.module('MatrixWebClientController', ['matrixService']) $rootScope.$on('$routeChangeSuccess', function (event, current, previous) { $scope.location = $location.path(); }); - - - // Manage the display of the current config - $scope.config; - - // Toggles the config display - $scope.showConfig = function() { - if ($scope.config) { - $scope.config = undefined; - } - else { - $scope.config = matrixService.config(); - } - }; - - $scope.closeConfig = function() { - if ($scope.config) { - $scope.config = undefined; - } - }; if (matrixService.isUserLoggedIn()) { // eventStreamService.resume(); } + $scope.go = function(url) { + $location.url(url); + }; + // Logs the user out $scope.logout = function() { // kill the event stream diff --git a/webclient/app.css b/webclient/app.css index 207f35f5f..72b38cd95 100644 --- a/webclient/app.css +++ b/webclient/app.css @@ -308,18 +308,6 @@ h1 { float: right; } -#config { - position: absolute; - z-index: 100; - top: 100px; - left: 50%; - width: 500px; - margin-left: -250px; - text-align: center; - padding: 20px; - background-color: #aaa; -} - .text_entry_section { position: fixed; bottom: 0; diff --git a/webclient/app.js b/webclient/app.js index 944b8ec27..e5d851394 100644 --- a/webclient/app.js +++ b/webclient/app.js @@ -19,7 +19,8 @@ var matrixWebClient = angular.module('matrixWebClient', [ 'MatrixWebClientController', 'LoginController', 'RoomController', - 'RoomsController', + 'HomeController', + 'SettingsController', 'UserController', 'matrixService', 'eventStreamService', @@ -44,16 +45,20 @@ matrixWebClient.config(['$routeProvider', '$provide', '$httpProvider', templateUrl: 'room/room.html', controller: 'RoomController' }). - when('/rooms', { - templateUrl: 'rooms/rooms.html', - controller: 'RoomsController' + when('/home', { + templateUrl: 'home/home.html', + controller: 'HomeController' + }). + when('/settings', { + templateUrl: 'settings/settings.html', + controller: 'SettingsController' }). when('/user/:user_matrix_id', { templateUrl: 'user/user.html', controller: 'UserController' }). otherwise({ - redirectTo: '/rooms' + redirectTo: '/home' }); $provide.factory('AccessTokenInterceptor', ['$q', '$rootScope', diff --git a/webclient/home/home-controller.js b/webclient/home/home-controller.js new file mode 100644 index 000000000..35d0ef165 --- /dev/null +++ b/webclient/home/home-controller.js @@ -0,0 +1,162 @@ +/* +Copyright 2014 matrix.org + +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. +*/ + +'use strict'; + +angular.module('HomeController', ['matrixService', 'mFileInput', 'mFileUpload', 'eventHandlerService']) +.controller('HomeController', ['$scope', '$location', 'matrixService', 'mFileUpload', 'eventHandlerService', 'eventStreamService', + function($scope, $location, matrixService, mFileUpload, eventHandlerService, eventStreamService) { + + $scope.config = matrixService.config(); + $scope.rooms = {}; + $scope.public_rooms = []; + $scope.newRoomId = ""; + $scope.feedback = ""; + + $scope.newRoom = { + room_id: "", + private: false + }; + + $scope.goToRoom = { + room_id: "", + }; + + $scope.joinAlias = { + room_alias: "", + }; + + $scope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) { + var config = matrixService.config(); + if (event.target_user_id === config.user_id && event.content.membership === "invite") { + console.log("Invited to room " + event.room_id); + // FIXME push membership to top level key to match /im/sync + event.membership = event.content.membership; + // FIXME bodge a nicer name than the room ID for this invite. + event.room_display_name = event.user_id + "'s room"; + $scope.rooms[event.room_id] = event; + } + }); + + var assignRoomAliases = function(data) { + for (var i=0; i + +
+
+ +
+
+ + + + + +
+
+ +
+
+
+
{{ config.displayName }}
+
{{ config.user_id }}
+
+
+
+
+ +

My rooms

+ +
+
+ {{ room.room_display_name }} {{room.membership === 'invite' ? ' (invited)' : ''}} +
+
+
+ +

Public rooms

+ + +
+ +
+
+ + private + +
+
+
+
+ + +
+
+
+ + {{ feedback }} + +
+
+ diff --git a/webclient/index.html b/webclient/index.html index 27d920819..ed1d9bb03 100644 --- a/webclient/index.html +++ b/webclient/index.html @@ -15,10 +15,11 @@ + - + @@ -33,22 +34,13 @@ -
-
Home server: {{ config.homeserver }}
-
User ID: {{ config.user_id }}
-
Access token: {{ config.access_token }}
-
-
-
- -
diff --git a/webclient/login/login-controller.js b/webclient/login/login-controller.js index e3d0eca94..51f9a3bdf 100644 --- a/webclient/login/login-controller.js +++ b/webclient/login/login-controller.js @@ -53,7 +53,7 @@ angular.module('LoginController', ['matrixService']) matrixService.saveConfig(); eventStreamService.resume(); // Go to the user's rooms list page - $location.url("rooms"); + $location.url("home"); }, function(error) { if (error.data) { @@ -86,7 +86,7 @@ angular.module('LoginController', ['matrixService']) }); matrixService.saveConfig(); eventStreamService.resume(); - $location.url("rooms"); + $location.url("home"); } else { $scope.feedback = "Failed to login: " + JSON.stringify(response.data); diff --git a/webclient/nbproject/licenseheader.txt b/webclient/nbproject/licenseheader.txt new file mode 100644 index 000000000..36e6dcf18 --- /dev/null +++ b/webclient/nbproject/licenseheader.txt @@ -0,0 +1,16 @@ +/* +Copyright 2014 matrix.org + +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. +*/ + diff --git a/webclient/nbproject/private/private.properties b/webclient/nbproject/private/private.properties new file mode 100644 index 000000000..3b1a22e6c --- /dev/null +++ b/webclient/nbproject/private/private.properties @@ -0,0 +1 @@ +browser=Chrome.INTEGRATED diff --git a/webclient/nbproject/private/private.xml b/webclient/nbproject/private/private.xml new file mode 100644 index 000000000..75bc70106 --- /dev/null +++ b/webclient/nbproject/private/private.xml @@ -0,0 +1,22 @@ + + + + + + file:/Users/manu/UC/matrix/github/synapse/webclient/components/matrix/matrix-service.js + file:/Users/manu/UC/matrix/github/synapse/webclient/app.css + file:/Users/manu/UC/matrix/github/synapse/webclient/components/matrix/event-handler-service.js + file:/Users/manu/UC/matrix/github/synapse/webclient/app-controller.js + file:/Users/manu/UC/matrix/github/synapse/webclient/room/room.html + file:/Users/manu/UC/matrix/github/synapse/webclient/login/login.html + file:/Users/manu/UC/matrix/github/synapse/webclient/components/matrix/event-stream-service.js + file:/Users/manu/UC/matrix/github/synapse/webclient/components/fileUpload/file-upload-service.js + file:/Users/manu/UC/matrix/github/synapse/webclient/index.html + file:/Users/manu/UC/matrix/github/synapse/webclient/room/room-controller.js + file:/Users/manu/UC/matrix/github/synapse/webclient/rooms/rooms.html + file:/Users/manu/UC/matrix/github/synapse/webclient/app.js + file:/Users/manu/UC/matrix/github/synapse/webclient/rooms/rooms-controller.js + file:/Users/manu/UC/matrix/github/synapse/webclient/components/fileInput/file-input-directive.js + + + diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js index 58ba432ce..331161882 100644 --- a/webclient/room/room-controller.js +++ b/webclient/room/room-controller.js @@ -372,7 +372,7 @@ angular.module('RoomController', ['ngSanitize', 'mUtilities']) matrixService.leave($scope.room_id).then( function(response) { console.log("Left room "); - $location.url("rooms"); + $location.url("home"); }, function(error) { $scope.feedback = "Failed to leave room: " + error.data.error; diff --git a/webclient/rooms/rooms-controller.js b/webclient/rooms/rooms-controller.js deleted file mode 100644 index d9c8baff4..000000000 --- a/webclient/rooms/rooms-controller.js +++ /dev/null @@ -1,300 +0,0 @@ -/* -Copyright 2014 matrix.org - -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. -*/ - -'use strict'; - -angular.module('RoomsController', ['matrixService', 'mFileInput', 'mFileUpload', 'eventHandlerService']) -.controller('RoomsController', ['$scope', '$location', 'matrixService', 'mFileUpload', 'eventHandlerService', 'eventStreamService', - function($scope, $location, matrixService, mFileUpload, eventHandlerService, eventStreamService) { - - $scope.rooms = {}; - $scope.public_rooms = []; - $scope.newRoomId = ""; - $scope.feedback = ""; - - $scope.newRoom = { - room_id: "", - private: false - }; - - $scope.goToRoom = { - room_id: "", - }; - - $scope.joinAlias = { - room_alias: "", - }; - - $scope.newProfileInfo = { - name: matrixService.config().displayName, - avatar: matrixService.config().avatarUrl, - avatarFile: undefined - }; - - $scope.linkedEmails = { - linkNewEmail: "", // the email entry box - emailBeingAuthed: undefined, // to populate verification text - authTokenId: undefined, // the token id from the IS - clientSecret: undefined, // our client secret - sendAttempt: 1, - emailCode: "", // the code entry box - linkedEmailList: matrixService.config().emailList // linked email list - }; - - $scope.$on(eventHandlerService.MEMBER_EVENT, function(ngEvent, event, isLive) { - var config = matrixService.config(); - if (event.target_user_id === config.user_id && event.content.membership === "invite") { - console.log("Invited to room " + event.room_id); - // FIXME push membership to top level key to match /im/sync - event.membership = event.content.membership; - // FIXME bodge a nicer name than the room ID for this invite. - event.room_display_name = event.user_id + "'s room"; - $scope.rooms[event.room_id] = event; - } - }); - - var assignRoomAliases = function(data) { - for (var i=0; i - -
-
- -
-
- - - - - -
-
- -
-
- -
- - -
-
-
-
- -
-
- - -
-
- -
- -
-
- - - {{ emailFeedback }} -
-
- Enter validation token for {{ linkedEmails.emailBeingAuthed }}: -
- - -
- Linked emails: - - - - -
{{address}}
-
-
- -

My rooms

- -
-
- {{ room.room_display_name }} {{room.membership === 'invite' ? ' (invited)' : ''}} -
-
-
- -

Public rooms

- - -
- -
-
- - private - -
-
-
-
- - -
-
-
- - {{ feedback }} - -
-
- diff --git a/webclient/settings/settings-controller.js b/webclient/settings/settings-controller.js new file mode 100644 index 000000000..5d3f7cb2b --- /dev/null +++ b/webclient/settings/settings-controller.js @@ -0,0 +1,146 @@ +/* +Copyright 2014 matrix.org + +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. +*/ + +'use strict'; + +angular.module('SettingsController', ['matrixService', 'mFileUpload']) +.controller('SettingsController', ['$scope', 'matrixService', 'mFileUpload', + function($scope, matrixService, mFileUpload) { + $scope.config = matrixService.config(); + + $scope.profile = { + displayName: $scope.config.displayName, + avatarUrl: $scope.config.avatarUrl + }; + + $scope.$watch("profile.avatarFile", function(newValue, oldValue) { + if ($scope.profile.avatarFile) { + console.log("Uploading new avatar file..."); + mFileUpload.uploadFile($scope.profile.avatarFile).then( + function(url) { + $scope.profile.avatarUrl = url; + }, + function(error) { + $scope.feedback = "Can't upload image"; + } + ); + } + }); + + $scope.saveProfile = function() { + if ($scope.profile.displayName !== $scope.config.displayName) { + setDisplayName($scope.profile.displayName); + } + if ($scope.profile.avatarUrl !== $scope.config.avatarUrl) { + setAvatar($scope.profile.avatarUrl); + } + }; + + var setDisplayName = function(displayName) { + matrixService.setDisplayName(displayName).then( + function(response) { + $scope.feedback = "Updated display name."; + + var config = matrixService.config(); + config.displayName = displayName; + matrixService.setConfig(config); + matrixService.saveConfig(); + }, + function(error) { + $scope.feedback = "Can't update display name: " + error.data; + } + ); + }; + + var setAvatar = function(avatarURL) { + console.log("Updating avatar to " + avatarURL); + matrixService.setProfilePictureUrl(avatarURL).then( + function(response) { + console.log("Updated avatar"); + $scope.feedback = "Updated avatar."; + + var config = matrixService.config(); + config.avatarUrl = avatarURL; + matrixService.setConfig(config); + matrixService.saveConfig(); + }, + function(error) { + $scope.feedback = "Can't update avatar: " + error.data; + } + ); + }; + + $scope.linkedEmails = { + linkNewEmail: "", // the email entry box + emailBeingAuthed: undefined, // to populate verification text + authTokenId: undefined, // the token id from the IS + emailCode: "", // the code entry box + linkedEmailList: matrixService.config().emailList // linked email list + }; + + $scope.linkEmail = function(email) { + matrixService.linkEmail(email).then( + function(response) { + if (response.data.success === true) { + $scope.linkedEmails.authTokenId = response.data.tokenId; + $scope.emailFeedback = "You have been sent an email."; + $scope.linkedEmails.emailBeingAuthed = email; + } + else { + $scope.emailFeedback = "Failed to send email."; + } + }, + function(error) { + $scope.emailFeedback = "Can't send email: " + error.data; + } + ); + }; + + $scope.submitEmailCode = function(code) { + var tokenId = $scope.linkedEmails.authTokenId; + if (tokenId === undefined) { + $scope.emailFeedback = "You have not requested a code with this email."; + return; + } + matrixService.authEmail(matrixService.config().user_id, tokenId, code).then( + function(response) { + if ("success" in response.data && response.data.success === false) { + $scope.emailFeedback = "Failed to authenticate email."; + return; + } + var config = matrixService.config(); + var emailList = {}; + if ("emailList" in config) { + emailList = config.emailList; + } + emailList[response.address] = response; + // save the new email list + config.emailList = emailList; + matrixService.setConfig(config); + matrixService.saveConfig(); + // invalidate the email being authed and update UI. + $scope.linkedEmails.emailBeingAuthed = undefined; + $scope.emailFeedback = ""; + $scope.linkedEmails.linkedEmailList = emailList; + $scope.linkedEmails.linkNewEmail = ""; + $scope.linkedEmails.emailCode = ""; + }, + function(reason) { + $scope.emailFeedback = "Failed to auth email: " + reason; + } + ); + }; +}]); \ No newline at end of file diff --git a/webclient/settings/settings.html b/webclient/settings/settings.html new file mode 100644 index 000000000..63b12c8f5 --- /dev/null +++ b/webclient/settings/settings.html @@ -0,0 +1,73 @@ +
+ +
+
+ +

Me

+
+
+ + + + + + +
+
+ +
+
+
+ +
+
+ +
+
+
+
+ +

Linked emails

+
+
+ + + {{ emailFeedback }} +
+
+ Enter validation token for {{ linkedEmails.emailBeingAuthed }}: +
+ + +
+ + + + +
{{address}}
+
+
+ +

Configuration

+
+
Home server: {{ config.homeserver }}
+
User ID: {{ config.user_id }}
+
Access token: {{ config.access_token }}
+
+
+ +
+
+
+
+ + {{ feedback }} + +
+
+