From b69fff5b01d54ab9230e0498661c5b9fef1c612c Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 12:02:31 +0000 Subject: [PATCH 1/4] Define component directories. Merge MemberAvatar and RoomAvatar to new-style components. Spoken to @ara4n about names/conventions. Settled on the following layout: src/components |_____________views | |____ tiles | | |___ MTextTile.js | | |___ MNoticeTile.js | | |___ ... | | | |____ avatars | | |____ RoomAvatar.js | | |____ MemberAvatar.js | | |____ ... | | | |____ ... | |_____________structures |____ RoomView.js |____ UserSettings.js |____ CreateRoom.js |____ ... Views are the "pure UI" components which can be reused. Structures are the wire components which give important contextual information to the views e.g. a view may be MemberList, but it's where it is in the structure that defines that it is a *Room* MemberList. --- .../views}/MemberAvatar.js | 55 ++++++++++++++- .../atoms => components/views}/RoomAvatar.js | 69 ++++++++++++++++--- src/controllers/atoms/UserSettingsButton.js | 27 -------- 3 files changed, 111 insertions(+), 40 deletions(-) rename src/{controllers/atoms => components/views}/MemberAvatar.js (57%) rename src/{controllers/atoms => components/views}/RoomAvatar.js (66%) delete mode 100644 src/controllers/atoms/UserSettingsButton.js diff --git a/src/controllers/atoms/MemberAvatar.js b/src/components/views/MemberAvatar.js similarity index 57% rename from src/controllers/atoms/MemberAvatar.js rename to src/components/views/MemberAvatar.js index e170d2e04c..9a7b171221 100644 --- a/src/controllers/atoms/MemberAvatar.js +++ b/src/components/views/MemberAvatar.js @@ -17,9 +17,12 @@ limitations under the License. 'use strict'; var React = require('react'); +var Avatar = require('../../../../Avatar'); var MatrixClientPeg = require('../../MatrixClientPeg'); -module.exports = { +module.exports = React.createClass({ + displayName: 'MemberAvatar', + propTypes: { member: React.PropTypes.object.isRequired, width: React.PropTypes.number, @@ -87,5 +90,53 @@ module.exports = { return { imageUrl: this._computeUrl() }; + }, + + + /////////////// + + + avatarUrlForMember: function(member) { + return Avatar.avatarUrlForMember( + member, + this.props.member, + this.props.width, + this.props.height, + this.props.resizeMethod + ); + }, + + skinnedDefaultAvatarUrl: function(member, width, height, resizeMethod) { + return Avatar.defaultAvatarUrlForString(member.userId); + }, + + render: function() { + // XXX: recalculates default avatar url constantly + if (this.state.imageUrl === this.defaultAvatarUrl(this.props.member)) { + var initial; + if (this.props.member.name[0]) + initial = this.props.member.name[0].toUpperCase(); + if (initial === '@' && this.props.member.name[1]) + initial = this.props.member.name[1].toUpperCase(); + + return ( + + + + + ); + } + return ( + + ); } -}; +}); diff --git a/src/controllers/atoms/RoomAvatar.js b/src/components/views/RoomAvatar.js similarity index 66% rename from src/controllers/atoms/RoomAvatar.js rename to src/components/views/RoomAvatar.js index 57c9a71842..086136fa1b 100644 --- a/src/controllers/atoms/RoomAvatar.js +++ b/src/components/views/RoomAvatar.js @@ -13,18 +13,12 @@ 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'; - +var React = require('react'); var MatrixClientPeg = require('../../MatrixClientPeg'); -/* - * View class should provide: - * - getUrlList() returning an array of URLs to try for the room avatar - in order of preference from the most preferred at index 0. null entries - in the array will be skipped over. - */ -module.exports = { +module.exports = React.createClass({ + displayName: 'RoomAvatar', + getDefaultProps: function() { return { width: 36, @@ -124,5 +118,58 @@ module.exports = { this.setState({ imageUrl: this._nextUrl() }); + }, + + + + //////////// + + + getUrlList: function() { + return [ + this.roomAvatarUrl(), + this.getOneToOneAvatar(), + this.getFallbackAvatar() + ]; + }, + + getFallbackAvatar: function() { + var images = [ '76cfa6', '50e2c2', 'f4c371' ]; + var total = 0; + for (var i = 0; i < this.props.room.roomId.length; ++i) { + total += this.props.room.roomId.charCodeAt(i); + } + return 'img/' + images[total % images.length] + '.png'; + }, + + render: function() { + var style = { + width: this.props.width, + height: this.props.height, + }; + + // XXX: recalculates fallback avatar constantly + if (this.state.imageUrl === this.getFallbackAvatar()) { + var initial; + if (this.props.room.name[0]) + initial = this.props.room.name[0].toUpperCase(); + if ((initial === '@' || initial === '#') && this.props.room.name[1]) + initial = this.props.room.name[1].toUpperCase(); + + return ( + + + + + ); + } + else { + return + } } -}; +}); diff --git a/src/controllers/atoms/UserSettingsButton.js b/src/controllers/atoms/UserSettingsButton.js deleted file mode 100644 index 5138111ef8..0000000000 --- a/src/controllers/atoms/UserSettingsButton.js +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2015 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. -*/ - -'use strict'; - -var dis = require("../../dispatcher"); - -module.exports = { - onClick: function() { - dis.dispatch({ - action: 'view_user_settings' - }); - }, -}; From 776369299d0a705a135162576fbb0cbb76c1acb2 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 13:27:52 +0000 Subject: [PATCH 2/4] Move login components to views --- src/components/{ => views}/login/CaptchaForm.js | 0 src/components/{ => views}/login/CasLogin.js | 0 src/components/{ => views}/login/PasswordLogin.js | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/components/{ => views}/login/CaptchaForm.js (100%) rename src/components/{ => views}/login/CasLogin.js (100%) rename src/components/{ => views}/login/PasswordLogin.js (100%) diff --git a/src/components/login/CaptchaForm.js b/src/components/views/login/CaptchaForm.js similarity index 100% rename from src/components/login/CaptchaForm.js rename to src/components/views/login/CaptchaForm.js diff --git a/src/components/login/CasLogin.js b/src/components/views/login/CasLogin.js similarity index 100% rename from src/components/login/CasLogin.js rename to src/components/views/login/CasLogin.js diff --git a/src/components/login/PasswordLogin.js b/src/components/views/login/PasswordLogin.js similarity index 100% rename from src/components/login/PasswordLogin.js rename to src/components/views/login/PasswordLogin.js From 7846d49403841dc374a055136d6fa4486a076d84 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 13:45:04 +0000 Subject: [PATCH 3/4] Add missing deps; Move stuff in 'views' to have functional descriptors --- src/Avatar.js | 53 +++++++++++++++++++ .../views/{ => avatars}/MemberAvatar.js | 2 +- .../views/{ => avatars}/RoomAvatar.js | 0 src/components/views/login/CasLogin.js | 2 +- 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/Avatar.js rename src/components/views/{ => avatars}/MemberAvatar.js (99%) rename src/components/views/{ => avatars}/RoomAvatar.js (100%) diff --git a/src/Avatar.js b/src/Avatar.js new file mode 100644 index 0000000000..afc5e9dd6d --- /dev/null +++ b/src/Avatar.js @@ -0,0 +1,53 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); + +module.exports = { + avatarUrlForMember: function(member, width, height, resizeMethod) { + var url = member.getAvatarUrl( + MatrixClientPeg.get().getHomeserverUrl(), + width, + height, + resizeMethod + ); + if (!url) { + // member can be null here currently since on invites, the JS SDK + // does not have enough info to build a RoomMember object for + // the inviter. + url = this.defaultAvatarUrlForString(member ? member.userId : ''); + } + return url; + }, + + defaultAvatarUrlForString: function(s) { + var total = 0; + for (var i = 0; i < s.length; ++i) { + total += s.charCodeAt(i); + } + switch (total % 3) { + case 0: + return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9QjNbxSKP4eagAFnTseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAABSwCRWJw31gAAAAASUVORK5CYII="; + case 1: + return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9chOaxgCP4eagAFk9seHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAtKMCks/JG8MAAAAASUVORK5CYII="; + case 2: + return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9YzNayQCP4eagADldseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAyiACeHwPiu4AAAAASUVORK5CYII="; + } + } +} + diff --git a/src/components/views/MemberAvatar.js b/src/components/views/avatars/MemberAvatar.js similarity index 99% rename from src/components/views/MemberAvatar.js rename to src/components/views/avatars/MemberAvatar.js index 9a7b171221..8cfeaa98d2 100644 --- a/src/components/views/MemberAvatar.js +++ b/src/components/views/avatars/MemberAvatar.js @@ -17,7 +17,7 @@ limitations under the License. 'use strict'; var React = require('react'); -var Avatar = require('../../../../Avatar'); +var Avatar = require('../../Avatar'); var MatrixClientPeg = require('../../MatrixClientPeg'); module.exports = React.createClass({ diff --git a/src/components/views/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js similarity index 100% rename from src/components/views/RoomAvatar.js rename to src/components/views/avatars/RoomAvatar.js diff --git a/src/components/views/login/CasLogin.js b/src/components/views/login/CasLogin.js index 8a45fa0643..9380db9788 100644 --- a/src/components/views/login/CasLogin.js +++ b/src/components/views/login/CasLogin.js @@ -16,7 +16,7 @@ limitations under the License. 'use strict'; -var MatrixClientPeg = require("../../MatrixClientPeg"); +var MatrixClientPeg = require("../../../MatrixClientPeg"); var React = require('react'); var url = require("url"); From 1dc4e14606bf01865c4478bb0c3fc77a6f5ad164 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 26 Nov 2015 13:49:39 +0000 Subject: [PATCH 4/4] Import things at the right levels --- src/Avatar.js | 2 +- src/components/views/avatars/MemberAvatar.js | 4 ++-- src/components/views/avatars/RoomAvatar.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Avatar.js b/src/Avatar.js index afc5e9dd6d..02025a9384 100644 --- a/src/Avatar.js +++ b/src/Avatar.js @@ -16,7 +16,7 @@ limitations under the License. 'use strict'; -var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); +var MatrixClientPeg = require('./MatrixClientPeg'); module.exports = { avatarUrlForMember: function(member, width, height, resizeMethod) { diff --git a/src/components/views/avatars/MemberAvatar.js b/src/components/views/avatars/MemberAvatar.js index 8cfeaa98d2..f65f11256b 100644 --- a/src/components/views/avatars/MemberAvatar.js +++ b/src/components/views/avatars/MemberAvatar.js @@ -17,8 +17,8 @@ limitations under the License. 'use strict'; var React = require('react'); -var Avatar = require('../../Avatar'); -var MatrixClientPeg = require('../../MatrixClientPeg'); +var Avatar = require('../../../Avatar'); +var MatrixClientPeg = require('../../../MatrixClientPeg'); module.exports = React.createClass({ displayName: 'MemberAvatar', diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index 086136fa1b..55f0e92cc1 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ var React = require('react'); -var MatrixClientPeg = require('../../MatrixClientPeg'); +var MatrixClientPeg = require('../../../MatrixClientPeg'); module.exports = React.createClass({ displayName: 'RoomAvatar',