ref(RecentList): Improvements after review.
This commit is contained in:
parent
046b06e436
commit
fb75180632
|
@ -38,7 +38,6 @@ import {
|
|||
conferenceWillLeave,
|
||||
dataChannelOpened,
|
||||
EMAIL_COMMAND,
|
||||
getCurrentConference,
|
||||
lockStateChanged,
|
||||
onStartMutedPolicyChanged,
|
||||
p2pStatusChanged,
|
||||
|
@ -307,10 +306,6 @@ class ConferenceConnector {
|
|||
_onConferenceFailed(err, ...params) {
|
||||
APP.store.dispatch(conferenceFailed(room, err, ...params));
|
||||
logger.error('CONFERENCE FAILED:', err, ...params);
|
||||
const state = APP.store.getState();
|
||||
|
||||
// The conference we have already joined or are joining.
|
||||
const conference = getCurrentConference(state);
|
||||
|
||||
switch (err) {
|
||||
case JitsiConferenceErrors.CONNECTION_ERROR: {
|
||||
|
@ -378,10 +373,11 @@ class ConferenceConnector {
|
|||
|
||||
case JitsiConferenceErrors.FOCUS_LEFT:
|
||||
case JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE:
|
||||
APP.store.dispatch(conferenceWillLeave(room));
|
||||
|
||||
// FIXME the conference should be stopped by the library and not by
|
||||
// the app. Both the errors above are unrecoverable from the library
|
||||
// perspective.
|
||||
APP.store.dispatch(conferenceWillLeave(conference));
|
||||
room.leave().then(() => connection.disconnect());
|
||||
break;
|
||||
|
||||
|
@ -475,12 +471,7 @@ function _connectionFailedHandler(error) {
|
|||
JitsiConnectionEvents.CONNECTION_FAILED,
|
||||
_connectionFailedHandler);
|
||||
if (room) {
|
||||
const state = APP.store.getState();
|
||||
|
||||
// The conference we have already joined or are joining.
|
||||
const conference = getCurrentConference(state);
|
||||
|
||||
APP.store.dispatch(conferenceWillLeave(conference));
|
||||
APP.store.dispatch(conferenceWillLeave(room));
|
||||
room.leave();
|
||||
}
|
||||
}
|
||||
|
@ -2478,12 +2469,6 @@ export default {
|
|||
* requested
|
||||
*/
|
||||
hangup(requestFeedback = false) {
|
||||
const state = APP.store.getState();
|
||||
|
||||
// The conference we have already joined or are joining.
|
||||
const conference = getCurrentConference(state);
|
||||
|
||||
APP.store.dispatch(conferenceWillLeave(conference));
|
||||
eventEmitter.emit(JitsiMeetConferenceEvents.BEFORE_HANGUP);
|
||||
APP.UI.removeLocalMedia();
|
||||
|
||||
|
@ -2512,13 +2497,24 @@ export default {
|
|||
// before all operations are done.
|
||||
Promise.all([
|
||||
requestFeedbackPromise,
|
||||
room.leave().then(disconnect, disconnect)
|
||||
this.leaveRoomAndDisconnect()
|
||||
]).then(values => {
|
||||
APP.API.notifyReadyToClose();
|
||||
maybeRedirectToWelcomePage(values[0]);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Leaves the room and calls JitsiConnection.disconnect.
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
leaveRoomAndDisconnect() {
|
||||
APP.store.dispatch(conferenceWillLeave(room));
|
||||
|
||||
return room.leave().then(disconnect, disconnect);
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the email for the local user
|
||||
* @param email {string} the new email
|
||||
|
|
|
@ -79,4 +79,4 @@
|
|||
@import 'deep-linking/main';
|
||||
@import 'transcription-subtitles';
|
||||
@import 'navigate_section_list';
|
||||
@import 'transcription-subtitles';
|
||||
/* Modules END */
|
||||
|
|
|
@ -10502,6 +10502,11 @@
|
|||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.19.4.tgz",
|
||||
"integrity": "sha512-1xFTAknSLfc47DIxHDUbnJWC+UwgWxATmymaxIPQpmMh7LBm7ZbwVEsuushqwL2GYZU0jie4xO+TK44hJPjNSQ=="
|
||||
},
|
||||
"moment-duration-format": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/moment-duration-format/-/moment-duration-format-2.2.2.tgz",
|
||||
"integrity": "sha1-uVdhLeJgFsmtnrYIfAVFc+USd3k="
|
||||
},
|
||||
"morgan": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
|
||||
|
|
|
@ -24,12 +24,14 @@ import { TRACK_ADDED, TRACK_REMOVED } from '../tracks';
|
|||
import {
|
||||
conferenceFailed,
|
||||
conferenceLeft,
|
||||
conferenceWillLeave,
|
||||
createConference,
|
||||
setLastN
|
||||
} from './actions';
|
||||
import {
|
||||
CONFERENCE_FAILED,
|
||||
CONFERENCE_JOINED,
|
||||
CONFERENCE_WILL_LEAVE,
|
||||
DATA_CHANNEL_OPENED,
|
||||
SET_AUDIO_ONLY,
|
||||
SET_LASTN,
|
||||
|
@ -46,6 +48,11 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
|
|||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* Handler for before unload event.
|
||||
*/
|
||||
let beforeUnloadHandler;
|
||||
|
||||
/**
|
||||
* Implements the middleware of the feature base/conference.
|
||||
*
|
||||
|
@ -66,6 +73,10 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
case CONNECTION_FAILED:
|
||||
return _connectionFailed(store, next, action);
|
||||
|
||||
case CONFERENCE_WILL_LEAVE:
|
||||
_conferenceWillLeave();
|
||||
break;
|
||||
|
||||
case DATA_CHANNEL_OPENED:
|
||||
return _syncReceiveVideoQuality(store, next, action);
|
||||
|
||||
|
@ -135,6 +146,11 @@ function _conferenceFailed(store, next, action) {
|
|||
// conference is handled by /conference.js and appropriate failure handlers
|
||||
// are set there.
|
||||
if (typeof APP !== 'undefined') {
|
||||
if (typeof beforeUnloadHandler !== 'undefined') {
|
||||
window.removeEventListener('beforeunload', beforeUnloadHandler);
|
||||
beforeUnloadHandler = undefined;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -175,6 +191,16 @@ function _conferenceJoined({ dispatch, getState }, next, action) {
|
|||
// and the LastN value needs to be synchronized here.
|
||||
audioOnly && conference.getLastN() !== 0 && dispatch(setLastN(0));
|
||||
|
||||
// FIXME: Very dirty solution. This will work on web only.
|
||||
// When the user closes the window or quits the browser, lib-jitsi-meet
|
||||
// handles the process of leaving the conference. This is temporary solution
|
||||
// that should cover the described use case as part of the effort to
|
||||
// implement the conferenceWillLeave action for web.
|
||||
beforeUnloadHandler = () => {
|
||||
dispatch(conferenceWillLeave(conference));
|
||||
};
|
||||
window.addEventListener('beforeunload', beforeUnloadHandler);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -227,6 +253,11 @@ function _connectionFailed({ dispatch, getState }, next, action) {
|
|||
|
||||
const result = next(action);
|
||||
|
||||
if (typeof beforeUnloadHandler !== 'undefined') {
|
||||
window.removeEventListener('beforeunload', beforeUnloadHandler);
|
||||
beforeUnloadHandler = undefined;
|
||||
}
|
||||
|
||||
// FIXME: Workaround for the web version. Currently, the creation of the
|
||||
// conference is handled by /conference.js and appropriate failure handlers
|
||||
// are set there.
|
||||
|
@ -266,6 +297,21 @@ function _connectionFailed({ dispatch, getState }, next, action) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the feature base/conference that the action
|
||||
* {@code CONFERENCE_WILL_LEAVE} is being dispatched within a specific redux
|
||||
* store.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _conferenceWillLeave() {
|
||||
if (typeof beforeUnloadHandler !== 'undefined') {
|
||||
window.removeEventListener('beforeunload', beforeUnloadHandler);
|
||||
beforeUnloadHandler = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not a CONNECTION_FAILED action is for a possible split
|
||||
* brain error. A split brain error occurs when at least two users join a
|
||||
|
|
|
@ -114,6 +114,15 @@ function _visitNode(node, callback) {
|
|||
global.addEventListener = () => {};
|
||||
}
|
||||
|
||||
// removeEventListener
|
||||
//
|
||||
// Required by:
|
||||
// - features/base/conference/middleware
|
||||
if (typeof global.removeEventListener === 'undefined') {
|
||||
// eslint-disable-next-line no-empty-function
|
||||
global.removeEventListener = () => {};
|
||||
}
|
||||
|
||||
// Array.prototype[@@iterator]
|
||||
//
|
||||
// Required by:
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
// @flow
|
||||
/**
|
||||
* item data for NavigateSectionList
|
||||
*/
|
||||
import type {
|
||||
ComponentType,
|
||||
Element
|
||||
} from 'react';
|
||||
|
||||
import type { ComponentType, Element } from 'react';
|
||||
|
||||
/**
|
||||
* Item data for <tt>NavigateSectionList</tt>.
|
||||
*/
|
||||
export type Item = {
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { translate } from '../../i18n';
|
||||
|
||||
// TODO: Maybe try to make all NavigateSectionList components to work for both
|
||||
// mobile and web, and move them to NavigateSectionList component.
|
||||
import {
|
||||
NavigateSectionListEmptyComponent,
|
||||
NavigateSectionListItem,
|
||||
|
@ -19,11 +19,6 @@ type Props = {
|
|||
*/
|
||||
disabled: boolean,
|
||||
|
||||
/**
|
||||
* The translate function.
|
||||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* Function to be invoked when an item is pressed. The item's URL is passed.
|
||||
*/
|
||||
|
@ -59,7 +54,7 @@ class NavigateSectionList extends Component<Props> {
|
|||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
static createSection(title, key) {
|
||||
static createSection(title: string, key: string) {
|
||||
return {
|
||||
data: [],
|
||||
key,
|
||||
|
@ -166,7 +161,7 @@ class NavigateSectionList extends Component<Props> {
|
|||
* @private
|
||||
* @returns {Component}
|
||||
*/
|
||||
_renderItem(listItem, key = '') {
|
||||
_renderItem(listItem, key: string = '') {
|
||||
const { item } = listItem;
|
||||
const { url } = item;
|
||||
|
||||
|
@ -197,12 +192,11 @@ class NavigateSectionList extends Component<Props> {
|
|||
* @returns {React$Node}
|
||||
*/
|
||||
_renderListEmptyComponent() {
|
||||
const { t, onRefresh } = this.props;
|
||||
const { onRefresh } = this.props;
|
||||
|
||||
if (typeof onRefresh === 'function') {
|
||||
return (
|
||||
<NavigateSectionListEmptyComponent
|
||||
t = { t } />
|
||||
<NavigateSectionListEmptyComponent />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -226,4 +220,4 @@ class NavigateSectionList extends Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
export default translate(NavigateSectionList);
|
||||
export default NavigateSectionList;
|
||||
|
|
|
@ -34,6 +34,7 @@ export default class Container extends AbstractContainer {
|
|||
accessible,
|
||||
onClick,
|
||||
touchFeedback = onClick,
|
||||
underlayColor,
|
||||
visible = true,
|
||||
...props
|
||||
} = this.props;
|
||||
|
@ -62,7 +63,8 @@ export default class Container extends AbstractContainer {
|
|||
{
|
||||
accessibilityLabel,
|
||||
accessible,
|
||||
onPress: onClick
|
||||
onPress: onClick,
|
||||
underlayColor
|
||||
},
|
||||
element);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
Text,
|
||||
View
|
||||
} from 'react-native';
|
||||
import { Text, View } from 'react-native';
|
||||
|
||||
import { Icon } from '../../../font-icons/index';
|
||||
import { translate } from '../../../i18n/index';
|
||||
import { Icon } from '../../../font-icons';
|
||||
import { translate } from '../../../i18n';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { TouchableHighlight } from 'react-native';
|
||||
|
||||
import {
|
||||
Text,
|
||||
Container
|
||||
} from './index';
|
||||
import Container from './Container';
|
||||
import Text from './Text';
|
||||
import styles, { UNDERLAY_COLOR } from './styles';
|
||||
import type { Item } from '../../Types';
|
||||
|
||||
|
@ -110,36 +107,35 @@ export default class NavigateSectionListItem extends Component<Props> {
|
|||
*/
|
||||
render() {
|
||||
const { colorBase, lines, title } = this.props.item;
|
||||
const avatarStyles = {
|
||||
...styles.avatar,
|
||||
...this._getAvatarColor(colorBase)
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableHighlight
|
||||
onPress = { this.props.onPress }
|
||||
<Container
|
||||
onClick = { this.props.onPress }
|
||||
style = { styles.listItem }
|
||||
underlayColor = { UNDERLAY_COLOR }>
|
||||
<Container style = { styles.listItem }>
|
||||
<Container style = { styles.avatarContainer }>
|
||||
<Container
|
||||
style = { [
|
||||
styles.avatar,
|
||||
this._getAvatarColor(colorBase)
|
||||
] }>
|
||||
<Text style = { styles.avatarContent }>
|
||||
{title.substr(0, 1).toUpperCase()}
|
||||
</Text>
|
||||
</Container>
|
||||
</Container>
|
||||
<Container style = { styles.listItemDetails }>
|
||||
<Text
|
||||
numberOfLines = { 1 }
|
||||
style = { [
|
||||
styles.listItemText,
|
||||
styles.listItemTitle
|
||||
] }>
|
||||
{title}
|
||||
<Container style = { styles.avatarContainer }>
|
||||
<Container style = { avatarStyles }>
|
||||
<Text style = { styles.avatarContent }>
|
||||
{title.substr(0, 1).toUpperCase()}
|
||||
</Text>
|
||||
{this._renderItemLines(lines)}
|
||||
</Container>
|
||||
</Container>
|
||||
</TouchableHighlight>
|
||||
<Container style = { styles.listItemDetails }>
|
||||
<Text
|
||||
numberOfLines = { 1 }
|
||||
style = {{
|
||||
...styles.listItemText,
|
||||
...styles.listItemTitle
|
||||
}}>
|
||||
{title}
|
||||
</Text>
|
||||
{this._renderItemLines(lines)}
|
||||
</Container>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { Text, Container } from './index';
|
||||
import Container from './Container';
|
||||
import styles from './styles';
|
||||
import Text from './Text';
|
||||
import type { SetionListSection } from '../../Types';
|
||||
|
||||
type Props = {
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { Text, Container } from './index';
|
||||
import Container from './Container';
|
||||
import Text from './Text';
|
||||
import type { Item } from '../../Types';
|
||||
|
||||
type Props = {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { Text } from './index';
|
||||
import Text from './Text';
|
||||
import type { Section } from '../../Types';
|
||||
|
||||
type Props = {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { Container } from './index';
|
||||
import Container from './Container';
|
||||
import type { Section } from '../../Types';
|
||||
|
||||
type Props = {
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
export * from './components';
|
||||
export { default as Platform } from './Platform';
|
||||
export * from './Types';
|
||||
|
|
|
@ -20,6 +20,15 @@ const throttledPersistState
|
|||
state => PersistenceRegistry.persistState(state),
|
||||
PERSIST_STATE_DELAY);
|
||||
|
||||
// Web only code.
|
||||
// We need the <tt>if</tt> beacuse it appears that on mobile the polyfill is not
|
||||
// executed yet.
|
||||
if (typeof window.addEventListener === 'function') {
|
||||
window.addEventListener('unload', () => {
|
||||
throttledPersistState.flush();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A master MiddleWare to selectively persist state. Please use the
|
||||
* {@link persisterconfig.json} to set which subtrees of the redux state should
|
||||
|
@ -37,8 +46,3 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
|
||||
return result;
|
||||
});
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
// Stop the LogCollector
|
||||
throttledPersistState.flush();
|
||||
});
|
||||
|
|
|
@ -4,10 +4,10 @@ import { connect } from 'react-redux';
|
|||
|
||||
import { appNavigate, getDefaultURL } from '../../app';
|
||||
import { translate } from '../../base/i18n';
|
||||
import type { Section } from '../../base/react/Types';
|
||||
import { NavigateSectionList } from '../../base/react';
|
||||
import type { Section } from '../../base/react';
|
||||
|
||||
import { toDisplayableList } from '../functions';
|
||||
import { isRecentListEnabled, toDisplayableList } from '../functions';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link RecentList}
|
||||
|
@ -62,6 +62,9 @@ class RecentList extends Component<Props> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
if (!isRecentListEnabled()) {
|
||||
return null;
|
||||
}
|
||||
const { disabled, t, _defaultServerURL, _recentList } = this.props;
|
||||
const recentList = toDisplayableList(_recentList, t, _defaultServerURL);
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
/**
|
||||
* Everything about recent list on web should be behind a feature flag and in
|
||||
* order to share code, this alias for the feature flag on mobile is always true
|
||||
* because we dont need a feature flag for recent list on mobile
|
||||
* @type {boolean}
|
||||
*/
|
||||
export const RECENT_LIST_ENABLED = true;
|
|
@ -1,10 +0,0 @@
|
|||
// @flow
|
||||
declare var interfaceConfig: Object;
|
||||
|
||||
/**
|
||||
* Everything about recent list on web should be behind a feature flag and in
|
||||
* order to share code, this alias for the feature flag on mobile is set to the
|
||||
* value defined in interface_config
|
||||
* @type {boolean}
|
||||
*/
|
||||
export const { RECENT_LIST_ENABLED } = interfaceConfig;
|
|
@ -1,6 +1,8 @@
|
|||
import { getLocalizedDateFormatter, getLocalizedDurationFormatter }
|
||||
from '../base/i18n/index';
|
||||
import { parseURIString } from '../base/util/index';
|
||||
import {
|
||||
getLocalizedDateFormatter,
|
||||
getLocalizedDurationFormatter
|
||||
} from '../base/i18n';
|
||||
import { parseURIString } from '../base/util';
|
||||
|
||||
/**
|
||||
* Creates a displayable list item of a recent list entry.
|
||||
|
@ -12,7 +14,6 @@ import { parseURIString } from '../base/util/index';
|
|||
* @returns {Object}
|
||||
*/
|
||||
export function toDisplayableItem(item, defaultServerURL, t) {
|
||||
// const { _defaultServerURL } = this.props;
|
||||
const location = parseURIString(item.conference);
|
||||
const baseURL = `${location.protocol}//${location.host}`;
|
||||
const serverName = baseURL === defaultServerURL ? null : location.host;
|
||||
|
@ -54,26 +55,20 @@ export function _toDurationString(duration) {
|
|||
* @returns {string}
|
||||
*/
|
||||
export function _toDateString(itemDate, t) {
|
||||
const date = new Date(itemDate);
|
||||
const dateString = date.toDateString();
|
||||
const m = getLocalizedDateFormatter(itemDate);
|
||||
const yesterday = new Date();
|
||||
const date = new Date(itemDate);
|
||||
const dateInMs = date.getTime();
|
||||
const now = new Date();
|
||||
const todayInMs = (new Date()).setHours(0, 0, 0, 0);
|
||||
const yesterdayInMs = todayInMs - 86400000; // 1 day = 86400000ms
|
||||
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
const yesterdayString = yesterday.toDateString();
|
||||
const today = new Date();
|
||||
const todayString = today.toDateString();
|
||||
const currentYear = today.getFullYear();
|
||||
const year = date.getFullYear();
|
||||
|
||||
if (dateString === todayString) {
|
||||
// The date is today, we use fromNow format.
|
||||
if (dateInMs >= todayInMs) {
|
||||
return m.fromNow();
|
||||
} else if (dateString === yesterdayString) {
|
||||
} else if (dateInMs >= yesterdayInMs) {
|
||||
return t('dateUtils.yesterday');
|
||||
} else if (year !== currentYear) {
|
||||
// we only want to include the year in the date if its not the current
|
||||
// year
|
||||
} else if (date.getFullYear() !== now.getFullYear()) {
|
||||
// We only want to include the year in the date if its not the current
|
||||
// year.
|
||||
return m.format('ddd, MMMM DD h:mm A, gggg');
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { NavigateSectionList } from '../base/react/index';
|
||||
import { NavigateSectionList } from '../base/react';
|
||||
|
||||
import { toDisplayableItem } from './functions.all';
|
||||
import { toDisplayableItem } from './functions.any';
|
||||
|
||||
/**
|
||||
* Transforms the history list to a displayable list
|
||||
|
@ -60,3 +60,12 @@ export function toDisplayableList(recentList, t, defaultServerURL) {
|
|||
return displayableList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if recent list is enabled and <tt>false</tt> otherwise.
|
||||
*
|
||||
* @returns {boolean} <tt>true</tt> if recent list is enabled and <tt>false</tt>
|
||||
* otherwise.
|
||||
*/
|
||||
export function isRecentListEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { NavigateSectionList } from '../base/react/index';
|
||||
/* global interfaceConfig */
|
||||
|
||||
import { NavigateSectionList } from '../base/react';
|
||||
|
||||
import { toDisplayableItem } from './functions.any';
|
||||
|
||||
import { toDisplayableItem } from './functions.all';
|
||||
|
||||
/**
|
||||
* Transforms the history list to a displayable list
|
||||
|
@ -14,10 +17,11 @@ import { toDisplayableItem } from './functions.all';
|
|||
*/
|
||||
export function toDisplayableList(recentList, t, defaultServerURL) {
|
||||
const { createSection } = NavigateSectionList;
|
||||
const section = createSection(t('recentList.joinPastMeeting'), 'all');
|
||||
const section
|
||||
= createSection(t('recentList.joinPastMeeting'), 'joinPastMeeting');
|
||||
|
||||
// we only want the last three conferences we were in for web
|
||||
for (const item of recentList.slice(1).slice(-3)) {
|
||||
// We only want the last three conferences we were in for web.
|
||||
for (const item of recentList.slice(-3)) {
|
||||
const displayableItem = toDisplayableItem(item, defaultServerURL, t);
|
||||
|
||||
section.data.push(displayableItem);
|
||||
|
@ -32,3 +36,12 @@ export function toDisplayableList(recentList, t, defaultServerURL) {
|
|||
return displayableList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if recent list is enabled and <tt>false</tt> otherwise.
|
||||
*
|
||||
* @returns {boolean} <tt>true</tt> if recent list is enabled and <tt>false</tt>
|
||||
* otherwise.
|
||||
*/
|
||||
export function isRecentListEnabled() {
|
||||
return interfaceConfig.RECENT_LIST_ENABLED;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
// @flow
|
||||
|
||||
import { APP_WILL_MOUNT } from '../base/app';
|
||||
import { CONFERENCE_WILL_LEAVE, SET_ROOM } from '../base/conference';
|
||||
import { JITSI_CONFERENCE_URL_KEY } from '../base/conference/constants';
|
||||
import {
|
||||
CONFERENCE_WILL_LEAVE,
|
||||
SET_ROOM,
|
||||
JITSI_CONFERENCE_URL_KEY
|
||||
} from '../base/conference';
|
||||
import { addKnownDomains } from '../base/known-domains';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import { parseURIString } from '../base/util';
|
||||
import { RECENT_LIST_ENABLED } from './featureFlag';
|
||||
|
||||
import { _storeCurrentConference, _updateConferenceDuration } from './actions';
|
||||
import { isRecentListEnabled } from './functions';
|
||||
|
||||
/**
|
||||
* used in order to get the device because there is a different way to get the
|
||||
* location URL on web and on native
|
||||
*/
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
|
@ -24,7 +23,7 @@ declare var APP: Object;
|
|||
* @returns {Function}
|
||||
*/
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
if (RECENT_LIST_ENABLED) {
|
||||
if (isRecentListEnabled()) {
|
||||
switch (action.type) {
|
||||
case APP_WILL_MOUNT:
|
||||
return _appWillMount(store, next, action);
|
||||
|
@ -89,7 +88,8 @@ function _appWillMount({ dispatch, getState }, next, action) {
|
|||
function _conferenceWillLeave({ dispatch, getState }, next, action) {
|
||||
let locationURL;
|
||||
|
||||
/** FIXME
|
||||
/**
|
||||
* FIXME:
|
||||
* It is better to use action.conference[JITSI_CONFERENCE_URL_KEY]
|
||||
* in order to make sure we get the url the conference is leaving
|
||||
* from (i.e. the room we are leaving from) because if the order of events
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
_STORE_CURRENT_CONFERENCE,
|
||||
_UPDATE_CONFERENCE_DURATION
|
||||
} from './actionTypes';
|
||||
import { RECENT_LIST_ENABLED } from './featureFlag';
|
||||
import { isRecentListEnabled } from './functions';
|
||||
|
||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||
|
||||
|
@ -50,7 +50,7 @@ PersistenceRegistry.register(STORE_NAME);
|
|||
ReducerRegistry.register(
|
||||
STORE_NAME,
|
||||
(state = _getLegacyRecentRoomList(), action) => {
|
||||
if (RECENT_LIST_ENABLED) {
|
||||
if (isRecentListEnabled()) {
|
||||
switch (action.type) {
|
||||
case APP_WILL_MOUNT:
|
||||
return _appWillMount(state);
|
||||
|
@ -62,9 +62,9 @@ ReducerRegistry.register(
|
|||
default:
|
||||
return state;
|
||||
}
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -100,7 +100,7 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
*/
|
||||
render() {
|
||||
const { t } = this.props;
|
||||
const { APP_NAME, RECENT_LIST_ENABLED } = interfaceConfig;
|
||||
const { APP_NAME } = interfaceConfig;
|
||||
const showAdditionalContent = this._shouldShowAdditionalContent();
|
||||
|
||||
return (
|
||||
|
@ -147,7 +147,7 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
{ t('welcomepage.go') }
|
||||
</Button>
|
||||
</div>
|
||||
{ RECENT_LIST_ENABLED ? <RecentList /> : null }
|
||||
<RecentList />
|
||||
</div>
|
||||
{ showAdditionalContent
|
||||
? <div
|
||||
|
|
Loading…
Reference in New Issue