diff --git a/css/_recording.scss b/css/_recording.scss index 165cf75bc..58c8b1284 100644 --- a/css/_recording.scss +++ b/css/_recording.scss @@ -4,7 +4,6 @@ .recording-dialog { .authorization-panel { - align-items: center; border-bottom: 2px solid rgba(0, 0, 0, 0.3); display: flex; flex-direction: column; @@ -12,18 +11,23 @@ padding-bottom: 10px; .dropbox-sign-in { - background-color: #4285f4; + align-items: center; + border: 1px solid #4285f4; + background-color: white; border-radius: 2px; cursor: pointer; display: inline-flex; - padding: 1px; + padding: 10px; + font-size: 18px; + font-weight: 600; margin: 10px 0px; + color: #4285f4; .dropbox-logo { background-color: white; border-radius: 2px; display: inline-block; - padding: 8px; + padding-right: 5px; height: 18px; } } diff --git a/lang/main.json b/lang/main.json index e0dac53c6..282fbaf7e 100644 --- a/lang/main.json +++ b/lang/main.json @@ -456,10 +456,11 @@ "on": "Recording", "pending": "Preparing to record the meeting...", "rec": "REC", - "authDropboxText": "To start the recording you need to first authorize our Dropbox recording app. After the recording is finished the file will be uploaded to your Dropbox account.", - "authDropboxCompletedText": "Our Dropbox app has been authorized successfully. You should see the recorded file in your Dropbox account shortly after the recording has finished.", + "authDropboxText": "Upload your recording to Dropbox.", + "authDropboxCompletedText": "Your recording file will appear in your Dropbox shortly after the recording has finished.", "serviceName": "Recording service", "signOut": "Sign Out", + "signIn": "sign in", "loggedIn": "Logged in as __userName__", "availableSpace": "Available space: __spaceLeft__ MB (approximately __duration__ minutes of recording)", "startRecordingBody": "Are you sure you would like to start recording?", diff --git a/react/features/base/oauth/functions.js b/react/features/base/oauth/functions.js deleted file mode 100644 index 23768a4c6..000000000 --- a/react/features/base/oauth/functions.js +++ /dev/null @@ -1,29 +0,0 @@ -// @flow - -import { getJitsiMeetGlobalNS } from '../util'; - - -/** - * Executes the oauth flow. - * - * @param {string} authUrl - The URL to oauth service. - * @returns {Promise} - The URL with the authorization details. - */ -export function authorize(authUrl: string): Promise { - const windowName = `oauth${Date.now()}`; - const gloabalNS = getJitsiMeetGlobalNS(); - - gloabalNS.oauthCallbacks = gloabalNS.oauthCallbacks || {}; - - return new Promise(resolve => { - const popup = window.open(authUrl, windowName); - - gloabalNS.oauthCallbacks[windowName] = () => { - const returnURL = popup.location.href; - - popup.close(); - delete gloabalNS.oauthCallbacks.windowName; - resolve(returnURL); - }; - }); -} diff --git a/react/features/base/oauth/reducer.js b/react/features/base/oauth/reducer.js deleted file mode 100644 index d6d6f3f12..000000000 --- a/react/features/base/oauth/reducer.js +++ /dev/null @@ -1,38 +0,0 @@ -// @flow - -import { ReducerRegistry } from '../redux'; -import { PersistenceRegistry } from '../storage'; - -import { UPDATE_DROPBOX_TOKEN } from './actionTypes'; - -/** - * The default state. - */ -const DEFAULT_STATE = { - dropbox: {} -}; - -/** - * The redux subtree of this feature. - */ -const STORE_NAME = 'features/base/oauth'; - -/** - * Sets up the persistence of the feature {@code oauth}. - */ -PersistenceRegistry.register(STORE_NAME); - -ReducerRegistry.register('features/base/oauth', -(state = DEFAULT_STATE, action) => { - switch (action.type) { - case UPDATE_DROPBOX_TOKEN: - return { - ...state, - dropbox: { - token: action.token - } - }; - default: - return state; - } -}); diff --git a/react/features/base/oauth/actionTypes.js b/react/features/dropbox/actionTypes.js similarity index 100% rename from react/features/base/oauth/actionTypes.js rename to react/features/dropbox/actionTypes.js diff --git a/react/features/base/oauth/actions.js b/react/features/dropbox/actions.js similarity index 58% rename from react/features/base/oauth/actions.js rename to react/features/dropbox/actions.js index e8da19db4..ab66e5d28 100644 --- a/react/features/base/oauth/actions.js +++ b/react/features/dropbox/actions.js @@ -2,12 +2,40 @@ import { Dropbox } from 'dropbox'; -import { getLocationContextRoot, parseStandardURIString } from '../util'; -import { parseURLParams } from '../config'; +import { + getJitsiMeetGlobalNS, + getLocationContextRoot, + parseStandardURIString +} from '../base/util'; +import { parseURLParams } from '../base/config'; -import { authorize } from './functions'; import { UPDATE_DROPBOX_TOKEN } from './actionTypes'; +/** + * Executes the oauth flow. + * + * @param {string} authUrl - The URL to oauth service. + * @returns {Promise} - The URL with the authorization details. + */ +function authorize(authUrl: string): Promise { + const windowName = `oauth${Date.now()}`; + const gloabalNS = getJitsiMeetGlobalNS(); + + gloabalNS.oauthCallbacks = gloabalNS.oauthCallbacks || {}; + + return new Promise(resolve => { + const popup = window.open(authUrl, windowName); + + gloabalNS.oauthCallbacks[windowName] = () => { + const returnURL = popup.location.href; + + popup.close(); + delete gloabalNS.oauthCallbacks.windowName; + resolve(returnURL); + }; + }); +} + /** * Action to authorize the Jitsi Recording app in dropbox. * diff --git a/react/features/dropbox/functions.js b/react/features/dropbox/functions.js new file mode 100644 index 000000000..156c544c4 --- /dev/null +++ b/react/features/dropbox/functions.js @@ -0,0 +1,39 @@ +// @flow + +import { Dropbox } from 'dropbox'; + +const logger = require('jitsi-meet-logger').getLogger(__filename); + +/** + * Fetches information about the user's dropbox account. + * + * @param {string} token - The dropbox access token. + * @param {string} clientId - The Jitsi Recorder dropbox app ID. + * @returns {Promise} + */ +export function getDropboxData( + token: string, + clientId: string +): Promise { + const dropboxAPI = new Dropbox({ + accessToken: token, + clientId + }); + + return Promise.all( + [ dropboxAPI.usersGetCurrentAccount(), dropboxAPI.usersGetSpaceUsage() ] + ).then(([ account, space ]) => { + const { allocation, used } = space; + const { allocated } = allocation; + + return { + userName: account.name.display_name, + spaceLeft: Math.floor((allocated - used) / 1048576)// 1MiB=1048576B + }; + + }, error => { + logger.error(error); + + return undefined; + }); +} diff --git a/react/features/base/oauth/index.js b/react/features/dropbox/index.js similarity index 62% rename from react/features/base/oauth/index.js rename to react/features/dropbox/index.js index f70f2a44f..20b2cbc74 100644 --- a/react/features/base/oauth/index.js +++ b/react/features/dropbox/index.js @@ -1,3 +1,4 @@ export * from './actions'; +export * from './functions'; import './reducer'; diff --git a/react/features/dropbox/reducer.js b/react/features/dropbox/reducer.js new file mode 100644 index 000000000..c38006814 --- /dev/null +++ b/react/features/dropbox/reducer.js @@ -0,0 +1,28 @@ +// @flow + +import { ReducerRegistry } from '../base/redux'; +import { PersistenceRegistry } from '../base/storage'; + +import { UPDATE_DROPBOX_TOKEN } from './actionTypes'; + +/** + * The redux subtree of this feature. + */ +const STORE_NAME = 'features/dropbox'; + +/** + * Sets up the persistence of the feature {@code dropbox}. + */ +PersistenceRegistry.register(STORE_NAME); + +ReducerRegistry.register(STORE_NAME, (state = {}, action) => { + switch (action.type) { + case UPDATE_DROPBOX_TOKEN: + return { + ...state, + token: action.token + }; + default: + return state; + } +}); diff --git a/react/features/recording/components/Recording/StartRecordingDialog.js b/react/features/recording/components/Recording/StartRecordingDialog.js index f158dd1c1..917ba9d9c 100644 --- a/react/features/recording/components/Recording/StartRecordingDialog.js +++ b/react/features/recording/components/Recording/StartRecordingDialog.js @@ -11,7 +11,7 @@ import { Dialog } from '../../../base/dialog'; import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet'; import StartRecordingDialogContent from './StartRecordingDialogContent'; -import { getDropboxData } from '../../functions'; +import { getDropboxData } from '../../../dropbox'; type Props = { @@ -41,7 +41,6 @@ type Props = { t: Function } - type State = { /** @@ -54,15 +53,15 @@ type State = { */ isValidating: boolean, - /** - * The display name of the user's Dropbox account. - */ - userName: ?string, - /** * Number of MiB of available space in user's Dropbox account. */ - spaceLeft: ?number + spaceLeft: ?number, + + /** + * The display name of the user's Dropbox account. + */ + userName: ?string }; /** @@ -217,14 +216,16 @@ class StartRecordingDialog extends Component { * @param {Object} state - The Redux state. * @private * @returns {{ - * _conference: JitsiConference + * _clientId: string, + * _conference: JitsiConference, + * _token: string * }} */ function mapStateToProps(state: Object) { return { + _clientId: state['features/base/config'].dropbox.clientId, _conference: state['features/base/conference'].conference, - _token: state['features/base/oauth'].dropbox.token, - _clientId: state['features/base/config'].dropbox.clientId + _token: state['features/dropbox'].token }; } diff --git a/react/features/recording/components/Recording/StartRecordingDialogContent.web.js b/react/features/recording/components/Recording/StartRecordingDialogContent.web.js index 60517df36..da3ea8033 100644 --- a/react/features/recording/components/Recording/StartRecordingDialogContent.web.js +++ b/react/features/recording/components/Recording/StartRecordingDialogContent.web.js @@ -9,7 +9,7 @@ import { sendAnalytics } from '../../../analytics'; import { translate } from '../../../base/i18n'; -import { authorizeDropbox, updateDropboxToken } from '../../../base/oauth'; +import { authorizeDropbox, updateDropboxToken } from '../../../dropbox'; type Props = { @@ -111,17 +111,21 @@ class StartRecordingDialogContent extends Component { * @returns {React$Component} */ _renderSignIn() { + const { t } = this.props; + return (
-
{ this.props.t('recording.authDropboxText') }
+
{ t('recording.authDropboxText') }
+ { t('recording.signIn') }
-
); + + ); } /** @@ -135,7 +139,7 @@ class StartRecordingDialogContent extends Component { return (
{ t('recording.authDropboxCompletedText') }
- ); +
+ ); } _onSignInClick: () => {}; diff --git a/react/features/recording/functions.js b/react/features/recording/functions.js index bdd1fa13b..7ef67c7de 100644 --- a/react/features/recording/functions.js +++ b/react/features/recording/functions.js @@ -1,11 +1,7 @@ // @flow -import { Dropbox } from 'dropbox'; - import { JitsiRecordingConstants } from '../base/lib-jitsi-meet'; -const logger = require('jitsi-meet-logger').getLogger(__filename); - /** * Searches in the passed in redux state for an active recording session of the * passed in mode. @@ -35,37 +31,3 @@ export function getSessionById(state: Object, id: string) { return state['features/recording'].sessionDatas.find( sessionData => sessionData.id === id); } - -/** - * Fetches information about the user's dropbox account. - * - * @param {string} token - The dropbox access token. - * @param {string} clientId - The Jitsi Recorder dropbox app ID. - * @returns {Promise} - */ -export function getDropboxData( - token: string, - clientId: string -): Promise { - const dropboxAPI = new Dropbox({ - accessToken: token, - clientId - }); - - return Promise.all( - [ dropboxAPI.usersGetCurrentAccount(), dropboxAPI.usersGetSpaceUsage() ] - ).then(([ account, space ]) => { - const { allocation, used } = space; - const { allocated } = allocation; - - return { - userName: account.name.display_name, - spaceLeft: Math.floor((allocated - used) / 1048576)// 1MiB=1048576B - }; - - }, error => { - logger.error(error); - - return undefined; - }); -} diff --git a/static/oauth.html b/static/oauth.html index a4ff5e904..c876db56d 100644 --- a/static/oauth.html +++ b/static/oauth.html @@ -6,30 +6,22 @@ - + +