From 67cd659712cdb2337184d9489237089e0d87dd09 Mon Sep 17 00:00:00 2001 From: or-else Date: Fri, 16 Jun 2017 17:44:17 -0700 Subject: [PATCH] better handling of avatars --- css/base.css | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++-- index.html | 70 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 123 insertions(+), 23 deletions(-) diff --git a/css/base.css b/css/base.css index 7179725f..7a082438 100644 --- a/css/base.css +++ b/css/base.css @@ -40,6 +40,13 @@ form { form label { font-size: 1rem; } + +img.avatar { + width: 100%; + height: 100%; + border-radius: 50%; +} + /* Input fields and buttons */ button { @@ -872,6 +879,71 @@ ul.tabbar li.active > a:after { color: #2196f3; /* blue 500 */ } +/* Letter tile base style */ +.lettertile { + display: flex; + color: rgba(250, 250, 250, 0.8); /* #FAFAFA, gray 50 */ + font-size: 1.8rem; + line-height: 1; + width: 3rem; + height: 3rem; + border-radius: 50%; + text-transform: uppercase; + align-items: center; + justify-content: center; + text-align: center; +} + +/* Colors of letter tiles */ +.lettertile.color0 { + background-color: #c5e1a5; +} +.lettertile.color1 { + background-color: #ef9a9a; +} +.lettertile.color2 { + background-color: #90caf9; +} +.lettertile.color3 { + background-color: #fff59d; +} +.lettertile.color4 { + background-color: #b0bec5; +} +.lettertile.color5 { + background-color: #f48fb1; +} +.lettertile.color6 { + background-color: #b39ddb; +} +.lettertile.color7 { + background-color: #9fa8da; +} +.lettertile.color8 { + background-color: #ffab91; +} +.lettertile.color9 { + background-color: #ffe082; +} +.lettertile.color10 { + background-color: #a5d6a7; +} +.lettertile.color11 { + background-color: #bcaaa4; +} +.lettertile.color12 { + background-color: #eeeeee; +} +.lettertile.color13 { + background-color: #80deea; +} +.lettertile.color14 { + background-color: #e6ee9c; +} +.lettertile.color15 { + background-color: #ce93d8; +} + /* Material icons resized from the default 24pt */ .material-icons { font-size: 1.4rem; @@ -882,10 +954,10 @@ ul.tabbar li.active > a:after { } #self-avatar.material-icons, .avatar-box .material-icons { - font-size: 2.8rem; + font-size: 3rem; } .avatar-box .material-icons { color: rgba(250, 250, 250, 0.8); /* #fafafa, gray 50 */ - background-color: #757575; + background-color: #c0c0c0; border-radius: 50%; } diff --git a/index.html b/index.html index 8aaad574..0368c083 100644 --- a/index.html +++ b/index.html @@ -70,6 +70,18 @@ 'data:image/' + photo.type + ';base64,' + photo.data : null; } + // Get 32 bit integer hash value for a string. Ideally it should produce the same value + // as Java's String#hash(). + function stringHash(value) { + var hash = 0; + value = "" + value; + for (var i = 0; i < value.length; i++) { + hash = ((hash<<5)-hash) + value.charCodeAt(i); + hash = hash & hash; // Convert to 32bit integer + } + return hash; + } + // Detect server address from the URL function detectServerAddress() { var host = DEFAULT_HOST; @@ -203,6 +215,28 @@ }; /* END Popup/dropdown menu */ + /* BEGIN Lettertile: Avatar box: either a bitmap or a letter tile or a stock icon. */ + var LetterTile = React.createClass({ + render: function() { + var avatar = null; + if (this.props.avatar === true) { + if (this.props.topic && this.props.title && this.props.title.trim()) { + var letter = this.props.title.trim().charAt(0); + var color = "lettertile color" + (Math.abs(stringHash(this.props.topic)) % 16); + avatar =
{letter}
+ } else { + avatar = (Tinode.getTopicType(this.props.topic) === "grp") ? + group : + person; + } + } else if (this.props.avatar) { + avatar = avatar; + } + return (
{avatar}
); + } + }); + /* END Lettertile */ + /* BEGIN Combobox for selecting host name */ var HostSelector = React.createClass({ getInitialState: function() { @@ -307,7 +341,6 @@ /* END Login */ /* BEGIN Account registration */ - var CreateAccountView = React.createClass({ getInitialState: function() { return { @@ -493,15 +526,10 @@ /* BEGIN Manage side panel - handle Login, Account Registration, Contacts, NewTopic views */ var SideNavbar = React.createClass({ render: function() { - var avatar = null; - if (this.props.avatar === true) { - avatar = account_box; - } else if (this.props.avatar) { - avatar = avatar; - } return (
- {avatar} +
{this.props.title}
{this.props.state === 'login' ? : @@ -591,6 +619,7 @@
: - (Tinode.getTopicType(this.props.topic) === "grp") ? - group : - person; + var avatar = this.props.avatar ? this.props.avatar : true; return (
  • - {avatar} +
    @@ -1212,7 +1238,6 @@ var component = null; if (this.state.topic) { var messageNodes = []; - var myUid = Tinode.getCurrentUserID(); var topic = Tinode.getTopic(this.state.topic); var previousFrom = null; for (var i=0; i 0) { @@ -1415,7 +1440,7 @@ contextMenuVisible: false, login: '', password: '', - loggedIn: false, + myUserId: null, errorText: '', topicSelected: '', loginDisabled: false, @@ -1496,7 +1521,7 @@ // Logged in fine, subscribe to 'me' attaching callbacks from the contacts view. var me = Tinode.getMeTopic(); me.onMetaDesc = instance.tnMeMetaDesc; - instance.setState({sidePanelSelected: "contacts", loggedIn: true}); + instance.setState({sidePanelSelected: "contacts", myUserId: Tinode.getCurrentUserID()}); // Subscribe, fetch topic desc, the list of subscriptions, and messages (invites). me.subscribe({get: {desc: {}, sub: {}, data: {}}}); }, @@ -1507,7 +1532,7 @@ sidePanelTitle: null, sidePanelAvatar: null, dialogSelected: null, - loggedIn: false, + myUserId: null, errorText: err && err.message ? err.message : 'disconnected', topicSelected: '', loginDisabled: false, @@ -1574,7 +1599,7 @@ }, // User chose Settings menu item. handleSettings: function() { - this.setState({sidePanelSelected: this.state.loggedIn ? 'edit-account' : 'settings'}); + this.setState({sidePanelSelected: this.state.myUserId ? 'edit-account' : 'settings'}); }, // User updated connection parameters - transport and server address handleConnectionSettings: function(serverAddress, transport) { @@ -1585,7 +1610,7 @@ }, // User clicked Cancel button in Setting or Sign Up panel. handleSidepanelCancel: function() { - if (this.state.loggedIn) { + if (this.state.myUserId) { this.setState({sidePanelSelected: 'contacts'}); } else { this.setState({sidePanelSelected: 'login'}); @@ -1686,6 +1711,7 @@ avatar={this.state.sidePanelAvatar} subscriptions={this.state.subscriptions} login={this.state.login} + myUserId={this.state.myUserId} loginDisabled={this.state.loginDisabled} errorText={this.state.errorText} topicSelected={this.state.topicSelected} @@ -1702,6 +1728,7 @@ onCreateTopic={this.handleNewTopicRequest} onNewTopic={this.handleNewTopic} onCancel={this.handleSidepanelCancel} + showContextMenu={this.handleShowContextMenu} />