Browse Source

feat: help centre

master
Bettenbuk Zoltan 5 years ago
parent
commit
57d14d9517

+ 4
- 0
lang/main.json View File

757
         "connectCalendarButton": "Connect your calendar",
757
         "connectCalendarButton": "Connect your calendar",
758
         "connectCalendarText": "Connect your calendar to view all your meetings in {{app}}. Plus, add {{provider}} meetings to your calendar and start them with one click.",
758
         "connectCalendarText": "Connect your calendar to view all your meetings in {{app}}. Plus, add {{provider}} meetings to your calendar and start them with one click.",
759
         "enterRoomTitle": "Start a new meeting",
759
         "enterRoomTitle": "Start a new meeting",
760
+        "getHelp": "Get help",
760
         "roomNameAllowedChars": "Meeting name should not contain any of these characters: ?, &, :, ', \", %, #.",
761
         "roomNameAllowedChars": "Meeting name should not contain any of these characters: ?, &, :, ', \", %, #.",
761
         "go": "GO",
762
         "go": "GO",
762
         "goSmall": "GO",
763
         "goSmall": "GO",
776
     "lonelyMeetingExperience": {
777
     "lonelyMeetingExperience": {
777
         "button": "Invite others",
778
         "button": "Invite others",
778
         "youAreAlone": "You are the only one in the meeting"
779
         "youAreAlone": "You are the only one in the meeting"
780
+    },
781
+    "helpView": {
782
+        "header": "Help centre"
779
     }
783
     }
780
 }
784
 }

+ 12
- 0
react/features/app/components/AbstractApp.js View File

89
         return (
89
         return (
90
             <Fragment>
90
             <Fragment>
91
                 <OverlayContainer />
91
                 <OverlayContainer />
92
+                { this._createExtraPlatformSpecificElement() }
92
             </Fragment>
93
             </Fragment>
93
         );
94
         );
94
     }
95
     }
95
 
96
 
97
+    /**
98
+     * Renders platform specific extra elements to be added alongside with the main element, if need be.
99
+     *
100
+     * NOTE: Overridden by child components.
101
+     *
102
+     * @returns {React$Element}
103
+     */
104
+    _createExtraPlatformSpecificElement() {
105
+        return null;
106
+    }
107
+
96
     _createMainElement: (React$Element<*>, Object) => ?React$Element<*>;
108
     _createMainElement: (React$Element<*>, Object) => ?React$Element<*>;
97
 
109
 
98
     /**
110
     /**

+ 12
- 0
react/features/app/components/App.native.js View File

12
 import '../../base/responsive-ui';
12
 import '../../base/responsive-ui';
13
 import { updateSettings } from '../../base/settings';
13
 import { updateSettings } from '../../base/settings';
14
 import '../../google-api';
14
 import '../../google-api';
15
+import { HelpView } from '../../help';
15
 import '../../mobile/audio-mode';
16
 import '../../mobile/audio-mode';
16
 import '../../mobile/back-button';
17
 import '../../mobile/back-button';
17
 import '../../mobile/background';
18
 import '../../mobile/background';
107
         });
108
         });
108
     }
109
     }
109
 
110
 
111
+    /**
112
+     * Renders platform specific extra elements to be added alongside with the main element, if need be.
113
+     *
114
+     * @inheritdoc
115
+     */
116
+    _createExtraPlatformSpecificElement() {
117
+        return (
118
+            <HelpView />
119
+        );
120
+    }
121
+
110
     /**
122
     /**
111
      * Attempts to disable the use of React Native
123
      * Attempts to disable the use of React Native
112
      * {@link ExceptionsManager#handleException} on platforms and in
124
      * {@link ExceptionsManager#handleException} on platforms and in

+ 1
- 0
react/features/base/color-scheme/defaultScheme.js View File

39
         statusBarContent: ColorPalette.white,
39
         statusBarContent: ColorPalette.white,
40
         text: ColorPalette.white
40
         text: ColorPalette.white
41
     },
41
     },
42
+    'Modal': {},
42
     'LargeVideo': {
43
     'LargeVideo': {
43
         background: 'rgb(42, 58, 75)'
44
         background: 'rgb(42, 58, 75)'
44
     },
45
     },

+ 6
- 0
react/features/base/modal/actionTypes.js View File

1
+// @flow
2
+
3
+/**
4
+ * Action type to set the ID of the active modal (or undefined if needs to be hidden).
5
+ */
6
+export const SET_ACTIVE_MODAL_ID = 'SET_ACTIVE_MODAL_ID';

+ 19
- 0
react/features/base/modal/actions.js View File

1
+// @flow
2
+
3
+import { SET_ACTIVE_MODAL_ID } from './actionTypes';
4
+
5
+/**
6
+ * Action to set the ID of the active modal (or undefined if needs to be hidden).
7
+ *
8
+ * @param {string} activeModalId - The new modal ID or undefined.
9
+ * @returns {{
10
+ *     activeModalId: string,
11
+ *     type: SET_ACTIVE_MODAL_ID
12
+ * }}
13
+ */
14
+export function setActiveModalId(activeModalId: ?string) {
15
+    return {
16
+        activeModalId,
17
+        type: SET_ACTIVE_MODAL_ID
18
+    };
19
+}

+ 151
- 0
react/features/base/modal/components/JitsiModal.js View File

1
+// @flow
2
+
3
+import React, { PureComponent } from 'react';
4
+import { SafeAreaView, View } from 'react-native';
5
+
6
+import { ColorSchemeRegistry } from '../../color-scheme';
7
+import { HeaderWithNavigation, SlidingView } from '../../react';
8
+import { connect } from '../../redux';
9
+import { StyleType } from '../../styles';
10
+
11
+import { setActiveModalId } from '../actions';
12
+
13
+import styles from './styles';
14
+
15
+type Props = {
16
+
17
+    /**
18
+     * The color schemed style of the common header component.
19
+     */
20
+    _headerStyles: StyleType,
21
+
22
+    /**
23
+     * True if the modal should be shown, false otherwise.
24
+     */
25
+    _show: boolean,
26
+
27
+    /**
28
+     * The color schemed style of the modal.
29
+     */
30
+    _styles: StyleType,
31
+
32
+    /**
33
+     * The children component(s) of the Modal, to be rendered.
34
+     */
35
+    children: React$Node,
36
+
37
+    /**
38
+     * The Redux Dispatch function.
39
+     */
40
+    dispatch: Function,
41
+
42
+    /**
43
+     * The i18n label key of the header title.
44
+     */
45
+    headerLabelKey: string,
46
+
47
+    /**
48
+     * The ID of the modal that is being rendered. This is used to show/hide the modal.
49
+     */
50
+    modalId: string,
51
+
52
+    /**
53
+     * Callback to be invoked when the modal closes.
54
+     */
55
+    onClose?: Function,
56
+
57
+    /**
58
+     * The position from where the modal should be opened. This is derived from the
59
+     * props of the {@code SlidingView} with the same name.
60
+     */
61
+    position?: string
62
+};
63
+
64
+/**
65
+ * Implements a custom Jitsi Modal that doesn't use the built in native
66
+ * Modal component of React Native.
67
+ */
68
+class JitsiModal extends PureComponent<Props> {
69
+    static defaultProps = {
70
+        position: 'bottom'
71
+    };
72
+
73
+    /**
74
+     * Instantiates a new component.
75
+     *
76
+     * @inheritdoc
77
+     */
78
+    constructor(props: Props) {
79
+        super(props);
80
+
81
+        this._onRequestClose = this._onRequestClose.bind(this);
82
+    }
83
+
84
+    /**
85
+     * Implements {@code PureComponent#render}.
86
+     *
87
+     * @inheritdoc
88
+     */
89
+    render() {
90
+        const { _headerStyles, _show, _styles, children, headerLabelKey, position } = this.props;
91
+
92
+        return (
93
+            <SlidingView
94
+                onHide = { this._onRequestClose }
95
+                position = { position }
96
+                show = { _show }>
97
+                <View
98
+                    style = { [
99
+                        _headerStyles.page,
100
+                        _styles.page
101
+                    ] }>
102
+                    <HeaderWithNavigation
103
+                        headerLabelKey = { headerLabelKey }
104
+                        onPressBack = { this._onRequestClose } />
105
+                    <SafeAreaView style = { styles.safeArea }>
106
+                        { children }
107
+                    </SafeAreaView>
108
+                </View>
109
+            </SlidingView>
110
+        );
111
+    }
112
+
113
+    _onRequestClose: () => boolean;
114
+
115
+    /**
116
+     * Callback to be invoked when the SlidingView requests closing.
117
+     *
118
+     * @returns {boolean}
119
+     */
120
+    _onRequestClose() {
121
+        const { _show, dispatch, onClose } = this.props;
122
+
123
+        if (_show) {
124
+            if (typeof onClose === 'function') {
125
+                onClose();
126
+            }
127
+            dispatch(setActiveModalId());
128
+
129
+            return true;
130
+        }
131
+
132
+        return false;
133
+    }
134
+}
135
+
136
+/**
137
+ * Maps part of the Redix state to the props of this component.
138
+ *
139
+ * @param {Object} state - The Redux state.
140
+ * @param {Props} ownProps - The own props of the component.
141
+ * @returns {Props}
142
+ */
143
+function _mapStateToProps(state, ownProps): $Shape<Props> {
144
+    return {
145
+        _headerStyles: ColorSchemeRegistry.get(state, 'Header'),
146
+        _show: state['features/base/modal'].activeModalId === ownProps.modalId,
147
+        _styles: ColorSchemeRegistry.get(state, 'Modal')
148
+    };
149
+}
150
+
151
+export default connect(_mapStateToProps)(JitsiModal);

+ 3
- 0
react/features/base/modal/components/index.native.js View File

1
+// @flow
2
+
3
+export { default as JitsiModal } from './JitsiModal';

+ 6
- 0
react/features/base/modal/components/index.web.js View File

1
+// @flow
2
+
3
+import { Component } from 'react';
4
+
5
+export const JitsiModal = Component;
6
+

+ 15
- 0
react/features/base/modal/components/styles.js View File

1
+// @flow
2
+
3
+import { ColorSchemeRegistry, schemeColor } from '../../color-scheme';
4
+
5
+export default {
6
+    safeArea: {
7
+        flex: 1
8
+    }
9
+};
10
+
11
+ColorSchemeRegistry.register('Modal', {
12
+    page: {
13
+        backgroundColor: schemeColor('background')
14
+    }
15
+});

+ 7
- 0
react/features/base/modal/index.js View File

1
+// @flow
2
+
3
+import './reducer';
4
+
5
+export * from './actions';
6
+export * from './actionTypes';
7
+export * from './components';

+ 17
- 0
react/features/base/modal/reducer.js View File

1
+// @flow
2
+
3
+import { ReducerRegistry } from '../redux';
4
+
5
+import { SET_ACTIVE_MODAL_ID } from './actionTypes';
6
+
7
+ReducerRegistry.register('features/base/modal', (state = {}, action) => {
8
+    switch (action.type) {
9
+    case SET_ACTIVE_MODAL_ID:
10
+        return {
11
+            ...state,
12
+            activeModalId: action.activeModalId
13
+        };
14
+    }
15
+
16
+    return state;
17
+});

+ 54
- 0
react/features/help/components/HelpView.js View File

1
+// @flow
2
+
3
+import React, { PureComponent } from 'react';
4
+import WebView from 'react-native-webview';
5
+
6
+import { JitsiModal } from '../../base/modal';
7
+import { connect } from '../../base/redux';
8
+
9
+import { HELP_VIEW_MODAL_ID } from '../constants';
10
+
11
+const DEFAULT_HELP_CENTRE_URL = 'https://web-cdn.jitsi.net/faq/meet-faq.html';
12
+
13
+type Props = {
14
+
15
+    /**
16
+     * The URL to display in the Help Centre.
17
+     */
18
+    _url: string
19
+}
20
+
21
+/**
22
+ * Implements a page that renders the help content for the app.
23
+ */
24
+class HelpView extends PureComponent<Props> {
25
+    /**
26
+     * Implements {@code PureComponent#render()}.
27
+     *
28
+     * @inheritdoc
29
+     * @returns {ReactElement}
30
+     */
31
+    render() {
32
+        return (
33
+            <JitsiModal
34
+                headerLabelKey = 'helpView.header'
35
+                modalId = { HELP_VIEW_MODAL_ID }>
36
+                <WebView source = {{ uri: this.props._url }} />
37
+            </JitsiModal>
38
+        );
39
+    }
40
+}
41
+
42
+/**
43
+ * Maps part of the Redux state to the props of this component.
44
+ *
45
+ * @param {Object} state - The Redux state.
46
+ * @returns {Props}
47
+ */
48
+function _mapStateToProps(state) {
49
+    return {
50
+        _url: state['features/base/config'].helpCentreURL || DEFAULT_HELP_CENTRE_URL
51
+    };
52
+}
53
+
54
+export default connect(_mapStateToProps)(HelpView);

+ 3
- 0
react/features/help/components/index.js View File

1
+// @flow
2
+
3
+export { default as HelpView } from './HelpView';

+ 3
- 0
react/features/help/constants.js View File

1
+// @flow
2
+
3
+export const HELP_VIEW_MODAL_ID = 'helpView';

+ 4
- 0
react/features/help/index.js View File

1
+// @flow
2
+
3
+export * from './components';
4
+export * from './constants';

+ 21
- 9
react/features/welcome/components/WelcomePageSideBar.native.js View File

4
 import { SafeAreaView, ScrollView, Text } from 'react-native';
4
 import { SafeAreaView, ScrollView, Text } from 'react-native';
5
 
5
 
6
 import { Avatar } from '../../base/avatar';
6
 import { Avatar } from '../../base/avatar';
7
-import { IconInfo, IconSettings } from '../../base/icons';
7
+import { IconInfo, IconSettings, IconHelp } from '../../base/icons';
8
+import { setActiveModalId } from '../../base/modal';
8
 import {
9
 import {
9
     getLocalParticipant,
10
     getLocalParticipant,
10
     getParticipantDisplayName
11
     getParticipantDisplayName
14
     SlidingView
15
     SlidingView
15
 } from '../../base/react';
16
 } from '../../base/react';
16
 import { connect } from '../../base/redux';
17
 import { connect } from '../../base/redux';
18
+import { HELP_VIEW_MODAL_ID } from '../../help';
17
 import { setSettingsViewVisible } from '../../settings';
19
 import { setSettingsViewVisible } from '../../settings';
18
 
20
 
19
 import { setSideBarVisible } from '../actions';
21
 import { setSideBarVisible } from '../actions';
25
  */
27
  */
26
 const PRIVACY_URL = 'https://jitsi.org/meet/privacy';
28
 const PRIVACY_URL = 'https://jitsi.org/meet/privacy';
27
 
29
 
28
-/**
29
- * The URL at which the user may send feedback.
30
- */
31
-const SEND_FEEDBACK_URL = 'mailto:support@jitsi.org';
32
-
33
 /**
30
 /**
34
  * The URL at which the terms (of service/use) are available to the user.
31
  * The URL at which the terms (of service/use) are available to the user.
35
  */
32
  */
72
 
69
 
73
         // Bind event handlers so they are only bound once per instance.
70
         // Bind event handlers so they are only bound once per instance.
74
         this._onHideSideBar = this._onHideSideBar.bind(this);
71
         this._onHideSideBar = this._onHideSideBar.bind(this);
72
+        this._onOpenHelpPage = this._onOpenHelpPage.bind(this);
75
         this._onOpenSettings = this._onOpenSettings.bind(this);
73
         this._onOpenSettings = this._onOpenSettings.bind(this);
76
     }
74
     }
77
 
75
 
112
                             label = 'welcomepage.privacy'
110
                             label = 'welcomepage.privacy'
113
                             url = { PRIVACY_URL } />
111
                             url = { PRIVACY_URL } />
114
                         <SideBarItem
112
                         <SideBarItem
115
-                            icon = { IconInfo }
116
-                            label = 'welcomepage.sendFeedback'
117
-                            url = { SEND_FEEDBACK_URL } />
113
+                            icon = { IconHelp }
114
+                            label = 'welcomepage.getHelp'
115
+                            onPress = { this._onOpenHelpPage } />
118
                     </ScrollView>
116
                     </ScrollView>
119
                 </SafeAreaView>
117
                 </SafeAreaView>
120
             </SlidingView>
118
             </SlidingView>
133
         this.props.dispatch(setSideBarVisible(false));
131
         this.props.dispatch(setSideBarVisible(false));
134
     }
132
     }
135
 
133
 
134
+    _onOpenHelpPage: () => void;
135
+
136
+    /**
137
+     * Shows the {@link HelpView}.
138
+     *
139
+     * @returns {void}
140
+     */
141
+    _onOpenHelpPage() {
142
+        const { dispatch } = this.props;
143
+
144
+        dispatch(setSideBarVisible(false));
145
+        dispatch(setActiveModalId(HELP_VIEW_MODAL_ID));
146
+    }
147
+
136
     _onOpenSettings: () => void;
148
     _onOpenSettings: () => void;
137
 
149
 
138
     /**
150
     /**

Loading…
Cancel
Save