ref(toolbar): remove contact list

This commit is contained in:
Leonard Kim 2018-04-09 20:16:43 -07:00 committed by Saúl Ibarra Corretgé
parent 7d86e3f8e7
commit 1eee20dd5a
22 changed files with 2 additions and 460 deletions

View File

@ -1,59 +0,0 @@
#contacts_container {
cursor: default;
#contacts {
font-size: 12px;
bottom: 0px;
margin: 0;
margin-top: 12px;
padding: 0px;
width: 100%;
}
.clickable {
cursor: pointer;
}
}
#contacts {
.contact-list-item {
align-items: center;
border-radius: 3px;
color: $baseLight;
display: flex;
font-size: 14px;
height: 36px;
list-style-type: none;
padding: 0 10%;
text-align: left;
white-space: nowrap;
&:hover,
&:active {
background: $toolbarSelectBackground;
}
.contact-list-item-name {
overflow: hidden;
text-overflow: ellipsis;
}
.avatar {
cursor: pointer;
height: 24px;
margin: 0 8px 0 4px;
width: 24px;
}
}
}
.avatar {
padding: 0px;
margin-right: 10px;
vertical-align: middle;
font-size: 22pt;
border-radius: 20px;
max-height: 30px;
max-width: 30px;
}

View File

@ -75,7 +75,7 @@
} }
/** /**
* Inner container, for example contact list, settings or profile. * Inner container, for example settings or profile.
*/ */
.sideToolbarContainer__inner { .sideToolbarContainer__inner {
display: none; display: none;

View File

@ -48,7 +48,6 @@
@import 'popup_menu'; @import 'popup_menu';
@import 'recording'; @import 'recording';
@import 'login_menu'; @import 'login_menu';
@import 'contact_list';
@import 'chat'; @import 'chat';
@import 'ringing/ringing'; @import 'ringing/ringing';
@import 'welcome_page'; @import 'welcome_page';

View File

@ -97,11 +97,6 @@ api.executeCommand('toggleFilmStrip')
api.executeCommand('toggleChat') api.executeCommand('toggleChat')
``` ```
* **toggleContactList** - Hides / shows the contact list. No arguments are required.
```javascript
api.executeCommand('toggleContactList')
```
* **toggleShareScreen** - Starts / stops screen sharing. No arguments are required. * **toggleShareScreen** - Starts / stops screen sharing. No arguments are required.
```javascript ```javascript
api.executeCommand('toggleShareScreen') api.executeCommand('toggleShareScreen')

View File

@ -44,16 +44,11 @@ var interfaceConfig = {
'microphone', 'camera', 'desktop', 'fullscreen', 'fodeviceselection', 'hangup', 'microphone', 'camera', 'desktop', 'fullscreen', 'fodeviceselection', 'hangup',
// extended toolbar // extended toolbar
'profile', 'contacts', 'info', 'chat', 'recording', 'etherpad', 'profile', 'info', 'chat', 'recording', 'etherpad',
'sharedvideo', 'settings', 'raisehand', 'videoquality', 'filmstrip', 'sharedvideo', 'settings', 'raisehand', 'videoquality', 'filmstrip',
'invite', 'feedback', 'stats', 'shortcuts' 'invite', 'feedback', 'stats', 'shortcuts'
], ],
/**
* Main Toolbar Buttons
* All of them should be in TOOLBAR_BUTTONS
*/
MAIN_TOOLBAR_BUTTONS: [ 'microphone', 'camera', 'desktop', 'fullscreen', 'fodeviceselection', 'hangup' ],
SETTINGS_SECTIONS: [ 'language', 'devices', 'moderator' ], SETTINGS_SECTIONS: [ 'language', 'devices', 'moderator' ],
INVITE_OPTIONS: [ 'invite', 'dialout', 'addtocall' ], INVITE_OPTIONS: [ 'invite', 'dialout', 'addtocall' ],
@ -62,7 +57,6 @@ var interfaceConfig = {
// screen, 'width' would fit the original video width to the width of the // screen, 'width' would fit the original video width to the width of the
// screen respecting ratio. // screen respecting ratio.
VIDEO_LAYOUT_FIT: 'both', VIDEO_LAYOUT_FIT: 'both',
SHOW_CONTACTLIST_AVATARS: true,
/** /**
* Whether to only show the filmstrip (and hide the toolbar). * Whether to only show the filmstrip (and hide the toolbar).

View File

@ -1,5 +1,4 @@
{ {
"contactlist": "__count__ Member",
"contactlist_plural": "__count__ Members", "contactlist_plural": "__count__ Members",
"passwordSetRemotely": "set by another member", "passwordSetRemotely": "set by another member",
"poweredby": "powered by", "poweredby": "powered by",
@ -114,11 +113,6 @@
"downloadApp": "Download the app", "downloadApp": "Download the app",
"openApp": "Continue to __app__" "openApp": "Continue to __app__"
}, },
"bottomtoolbar": {
"chat": "Open / close chat",
"filmstrip": "Show / hide videos",
"contactlist": "View and invite members"
},
"chat":{ "chat":{
"nickname": { "nickname": {
"title": "Enter a nickname in the box below", "title": "Enter a nickname in the box below",

View File

@ -81,10 +81,6 @@ function initCommands() {
sendAnalytics(createApiEvent('chat.toggled')); sendAnalytics(createApiEvent('chat.toggled'));
APP.UI.toggleChat(); APP.UI.toggleChat();
}, },
'toggle-contact-list': () => {
sendAnalytics(createApiEvent('contact.list.toggled'));
APP.UI.toggleContactList();
},
'toggle-share-screen': () => { 'toggle-share-screen': () => {
sendAnalytics(createApiEvent('screen.sharing.toggled')); sendAnalytics(createApiEvent('screen.sharing.toggled'));
toggleScreenSharing(); toggleScreenSharing();

View File

@ -24,7 +24,6 @@ const commands = {
submitFeedback: 'submit-feedback', submitFeedback: 'submit-feedback',
toggleAudio: 'toggle-audio', toggleAudio: 'toggle-audio',
toggleChat: 'toggle-chat', toggleChat: 'toggle-chat',
toggleContactList: 'toggle-contact-list',
toggleFilmStrip: 'toggle-film-strip', toggleFilmStrip: 'toggle-film-strip',
toggleShareScreen: 'toggle-share-screen', toggleShareScreen: 'toggle-share-screen',
toggleVideo: 'toggle-video' toggleVideo: 'toggle-video'
@ -551,7 +550,6 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
* toggleVideo - mutes / unmutes video. no arguments * toggleVideo - mutes / unmutes video. no arguments
* toggleFilmStrip - hides / shows the filmstrip. no arguments * toggleFilmStrip - hides / shows the filmstrip. no arguments
* toggleChat - hides / shows chat. no arguments. * toggleChat - hides / shows chat. no arguments.
* toggleContactList - hides / shows contact list. no arguments.
* toggleShareScreen - starts / stops screen sharing. no arguments. * toggleShareScreen - starts / stops screen sharing. no arguments.
* *
* @param {Object} commandList - The object with commands to be executed. * @param {Object} commandList - The object with commands to be executed.

View File

@ -111,9 +111,6 @@ const UIListeners = new Map([
UI.toggleSidePanel('settings_container'); UI.toggleSidePanel('settings_container');
} }
} }
], [
UIEvents.TOGGLE_CONTACT_LIST,
() => UI.toggleContactList()
], [ ], [
UIEvents.TOGGLE_PROFILE, UIEvents.TOGGLE_PROFILE,
() => UI.toggleSidePanel('profile_container') () => UI.toggleSidePanel('profile_container')
@ -628,11 +625,6 @@ UI.isChatVisible = () => Chat.isVisible();
*/ */
UI.toggleChat = () => UI.toggleSidePanel('chat_container'); UI.toggleChat = () => UI.toggleSidePanel('chat_container');
/**
* Toggles contact list panel.
*/
UI.toggleContactList = () => UI.toggleSidePanel('contacts_container');
/** /**
* Toggles the given side panel. * Toggles the given side panel.
* *

View File

@ -1,7 +1,6 @@
import Chat from './chat/Chat'; import Chat from './chat/Chat';
import SettingsMenu from './settings/SettingsMenu'; import SettingsMenu from './settings/SettingsMenu';
import Profile from './profile/Profile'; import Profile from './profile/Profile';
import ContactListView from './contactlist/ContactListView';
import { isButtonEnabled } from '../../../react/features/toolbox'; import { isButtonEnabled } from '../../../react/features/toolbox';
const SidePanels = { const SidePanels = {
@ -20,11 +19,6 @@ const SidePanels = {
if (isButtonEnabled('profile')) { if (isButtonEnabled('profile')) {
Profile.init(eventEmitter); Profile.init(eventEmitter);
} }
// Initialize contact list view
if (isButtonEnabled('contacts')) {
ContactListView.init();
}
} }
}; };

View File

@ -1,56 +0,0 @@
/* global $, APP */
/* eslint-disable no-unused-vars */
import React from 'react';
import ReactDOM from 'react-dom';
import { I18nextProvider } from 'react-i18next';
import { Provider } from 'react-redux';
import { i18next } from '../../../../react/features/base/i18n';
import { ContactListPanel } from '../../../../react/features/contact-list';
/* eslint-enable no-unused-vars */
import UIUtil from '../../util/UIUtil';
/**
* Contact list.
*
* FIXME: One day this view should no longer be called "contact list" because
* the term "contact" is not used elsewhere. Normally people in the conference
* are internally refered to as "participants" or externally as "members".
*/
const ContactListView = {
/**
* Creates and appends the contact list to the side panel.
*
* @returns {void}
*/
init() {
const contactListPanelContainer = document.createElement('div');
contactListPanelContainer.id = 'contacts_container';
contactListPanelContainer.className = 'sideToolbarContainer__inner';
$('#sideToolbarContainer').append(contactListPanelContainer);
ReactDOM.render(
<Provider store = { APP.store }>
<I18nextProvider i18n = { i18next }>
<ContactListPanel />
</I18nextProvider>
</Provider>,
contactListPanelContainer
);
},
/**
* Indicates if the contact list is currently visible.
*
* @return {boolean) true if the contact list is currently visible.
*/
isVisible() {
return UIUtil.isVisible(document.getElementById('contactlist'));
}
};
export default ContactListView;

View File

@ -66,9 +66,6 @@ const VideoLayout = {
init(emitter) { init(emitter) {
eventEmitter = emitter; eventEmitter = emitter;
// Unregister listeners in case of reinitialization
this.unregisterListeners();
localVideoThumbnail = new LocalVideo(VideoLayout, emitter); localVideoThumbnail = new LocalVideo(VideoLayout, emitter);
// sets default video type of local video // sets default video type of local video
@ -104,20 +101,6 @@ const VideoLayout = {
registerListeners() { registerListeners() {
eventEmitter.addListener(UIEvents.LOCAL_FLIPX_CHANGED, eventEmitter.addListener(UIEvents.LOCAL_FLIPX_CHANGED,
onLocalFlipXChanged); onLocalFlipXChanged);
eventEmitter.addListener(UIEvents.CONTACT_CLICKED,
this.handleVideoThumbClicked);
},
/**
* Unregistering listeners for UI events in Video layout component.
*
* @returns {void}
*/
unregisterListeners() {
if (this._onContactClicked) {
eventEmitter.removeListener(UIEvents.CONTACT_CLICKED,
this.handleVideoThumbClicked);
}
}, },
initLargeVideo() { initLargeVideo() {

View File

@ -22,7 +22,6 @@ const LEGACY_INCOMING_METHODS = [
'email', 'email',
'toggle-audio', 'toggle-audio',
'toggle-chat', 'toggle-chat',
'toggle-contact-list',
'toggle-film-strip', 'toggle-film-strip',
'toggle-share-screen', 'toggle-share-screen',
'toggle-video', 'toggle-video',

View File

@ -1,101 +0,0 @@
/* global APP */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import UIEvents from '../../../../service/UI/UIEvents';
import { Avatar } from '../../base/participants';
/**
* Implements a React {@code Component} for showing a participant's avatar and
* name and emits an event when it has been clicked.
*
* @extends Component
*/
class ContactListItem extends Component {
/**
* Default values for {@code ContactListItem} component's properties.
*
* @static
*/
static propTypes = {
/**
* The link to the participant's avatar image.
*/
avatarURI: PropTypes.string,
/**
* An id attribute to set on the root of {@code ContactListItem}. Used
* by the torture tests.
*/
id: PropTypes.string,
/**
* The participant's display name.
*/
name: PropTypes.string
};
/**
* Initializes new {@code ContactListItem} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
super(props);
// Bind event handler so it is only bound once for every instance.
this._onClick = this._onClick.bind(this);
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
return (
<li
className = 'clickable contact-list-item'
id = { this.props.id }
onClick = { this._onClick }>
{ this.props.avatarURI ? this._renderAvatar() : null }
<p className = 'contact-list-item-name'>
{ this.props.name }
</p>
</li>
);
}
/**
* Emits an event notifying the contact list item for the passed in
* participant ID has been clicked.
*
* @private
* @returns {void}
*/
_onClick() {
// FIXME move this call to a pinning action, which is what's happening
// on the listener end, when the listener is properly hooked into redux.
APP.UI.emitEvent(UIEvents.CONTACT_CLICKED, this.props.id);
}
/**
* Renders the React Element for displaying the participant's avatar image.
*
* @private
* @returns {ReactElement}
*/
_renderAvatar() {
return (
<Avatar
className = 'icon-avatar avatar'
uri = { this.props.avatarURI } />
);
}
}
export default ContactListItem;

View File

@ -1,122 +0,0 @@
/* @flow */
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { translate } from '../../base/i18n';
import { getAvatarURL, getParticipants } from '../../base/participants';
import ContactListItem from './ContactListItem';
declare var interfaceConfig: Object;
/**
* React component for showing a list of current conference participants.
*
* @extends Component
*/
class ContactListPanel extends Component<*> {
/**
* Default values for {@code ContactListPanel} component's properties.
*
* @static
*/
static propTypes = {
/**
* The participants to show in the contact list.
*/
_participants: PropTypes.array,
/**
* Whether or not participant avatars should be displayed.
*/
_showAvatars: PropTypes.bool,
/**
* Invoked to obtain translated strings.
*/
t: PropTypes.func
};
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
*/
render() {
const { _participants, t } = this.props;
return (
<div className = 'contact-list-panel'>
<div className = 'title'>
{ t('contactlist', { count: _participants.length }) }
</div>
<ul id = 'contacts'>
{ this._renderContacts() }
</ul>
</div>
);
}
/**
* Renders React Elements for displaying information about each participant
* in the contact list.
*
* @private
* @returns {ReactElement[]}
*/
_renderContacts() {
const { t } = this.props;
const meString = t('me');
return this.props._participants.map(participant => {
const { id, local, name } = participant;
let displayName;
// FIXME this duplicates the logic from SpeakerStats.js, but
// currently it seems that the
// interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME is freely used in
// multiple other places. A proper fix should take care of all
// usages. Also conference.js has getParticipantDisplayName which
// generates HTML span making things even harder to be cleaned up
// properly.
if (local) {
displayName
= name ? `${name} (${meString})` : meString;
} else {
displayName
= name ? name : interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME;
}
return (
<ContactListItem
avatarURI = { this.props._showAvatars
? getAvatarURL(participant) : null }
id = { id }
key = { id }
name = { displayName } />
);
});
}
}
/**
* Maps (parts of) the Redux state to the associated {@code ContactListPanel}'s
* props.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _locked: boolean,
* _participants: Array
* }}
*/
function _mapStateToProps(state) {
return {
_participants: getParticipants(state),
_showAvatars: interfaceConfig.SHOW_CONTACTLIST_AVATARS
};
}
export default translate(connect(_mapStateToProps)(ContactListPanel));

View File

@ -1,59 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { getParticipantCount } from '../../base/participants';
/**
* React component for showing a badge with the current count of conference
* participants.
*
* @extends Component
*/
class ParticipantCounter extends Component {
/**
* {@code ParticipantCounter} component's property types.
*
* @static
*/
static propTypes = {
/**
* The number of participants in the conference.
*/
_count: PropTypes.number
};
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
return (
<span className = 'badge-round'>
<span id = 'numberOfParticipants'>
{ this.props._count }
</span>
</span>
);
}
}
/**
* Maps (parts of) the Redux state to the associated
* {@code ParticipantCounter}'s props.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _count: number
* }}
*/
function _mapStateToProps(state) {
return {
_count: getParticipantCount(state)
};
}
export default connect(_mapStateToProps)(ParticipantCounter);

View File

@ -1,2 +0,0 @@
export { default as ContactListPanel } from './ContactListPanel';
export { default as ParticipantCounter } from './ParticipantCounter';

View File

@ -1 +0,0 @@
export * from './components';

View File

@ -38,7 +38,6 @@ export default {
TOGGLE_AUDIO_ONLY: 'UI.toggle_audioonly', TOGGLE_AUDIO_ONLY: 'UI.toggle_audioonly',
TOGGLE_CHAT: 'UI.toggle_chat', TOGGLE_CHAT: 'UI.toggle_chat',
TOGGLE_SETTINGS: 'UI.toggle_settings', TOGGLE_SETTINGS: 'UI.toggle_settings',
TOGGLE_CONTACT_LIST: 'UI.toggle_contact_list',
/** /**
* Notifies that the profile toolbar button has been clicked. * Notifies that the profile toolbar button has been clicked.
@ -69,7 +68,6 @@ export default {
TOGGLE_RECORDING: 'UI.toggle_recording', TOGGLE_RECORDING: 'UI.toggle_recording',
TOGGLE_SCREENSHARING: 'UI.toggle_screensharing', TOGGLE_SCREENSHARING: 'UI.toggle_screensharing',
TOGGLED_SHARED_DOCUMENT: 'UI.toggled_shared_document', TOGGLED_SHARED_DOCUMENT: 'UI.toggled_shared_document',
CONTACT_CLICKED: 'UI.contact_clicked',
HANGUP: 'UI.hangup', HANGUP: 'UI.hangup',
LOGOUT: 'UI.logout', LOGOUT: 'UI.logout',
RECORDING_TOGGLED: 'UI.recording_toggled', RECORDING_TOGGLED: 'UI.recording_toggled',