fix(dropbox): Address code review comments.
This commit is contained in:
parent
62544188bd
commit
2704b2f822
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
// @flow
|
||||
|
||||
import { getJitsiMeetGlobalNS } from '../util';
|
||||
|
||||
|
||||
/**
|
||||
* Executes the oauth flow.
|
||||
*
|
||||
* @param {string} authUrl - The URL to oauth service.
|
||||
* @returns {Promise<string>} - The URL with the authorization details.
|
||||
*/
|
||||
export function authorize(authUrl: string): Promise<string> {
|
||||
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);
|
||||
};
|
||||
});
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
});
|
|
@ -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<string>} - The URL with the authorization details.
|
||||
*/
|
||||
function authorize(authUrl: string): Promise<string> {
|
||||
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.
|
||||
*
|
|
@ -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<Object|undefined>}
|
||||
*/
|
||||
export function getDropboxData(
|
||||
token: string,
|
||||
clientId: string
|
||||
): Promise<?Object> {
|
||||
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;
|
||||
});
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
export * from './actions';
|
||||
export * from './functions';
|
||||
|
||||
import './reducer';
|
|
@ -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;
|
||||
}
|
||||
});
|
|
@ -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<Props, State> {
|
|||
* @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
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Props> {
|
|||
* @returns {React$Component}
|
||||
*/
|
||||
_renderSignIn() {
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>{ this.props.t('recording.authDropboxText') }</div>
|
||||
<div>{ t('recording.authDropboxText') }</div>
|
||||
<div
|
||||
className = 'dropbox-sign-in'
|
||||
onClick = { this._onSignInClick }>
|
||||
<img
|
||||
className = 'dropbox-logo'
|
||||
src = 'images/dropboxLogo.svg' />
|
||||
<span>{ t('recording.signIn') }</span>
|
||||
</div>
|
||||
</div>);
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,7 +139,7 @@ class StartRecordingDialogContent extends Component<Props> {
|
|||
return (
|
||||
<div>
|
||||
<div>{ t('recording.authDropboxCompletedText') }</div>
|
||||
<div className = 'logged-in-pannel'>
|
||||
<div className = 'logged-in-panel'>
|
||||
<div>
|
||||
{ t('recording.loggedIn', { userName }) } (
|
||||
<a onClick = { this._onSignOutClick }>
|
||||
|
@ -154,7 +158,8 @@ class StartRecordingDialogContent extends Component<Props> {
|
|||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>);
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
_onSignInClick: () => {};
|
||||
|
|
|
@ -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<Object|undefined>}
|
||||
*/
|
||||
export function getDropboxData(
|
||||
token: string,
|
||||
clientId: string
|
||||
): Promise<?Object> {
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<!--#include virtual="/base.html" -->
|
||||
<!--#include virtual="/title.html" -->
|
||||
<script>
|
||||
function getParentWindowCallback() {
|
||||
(function() {
|
||||
var windowName = window.name;
|
||||
var parentWindow = window.opener;
|
||||
if (parentWindow
|
||||
|
@ -16,20 +16,12 @@
|
|||
if (globalNS.oauthCallbacks
|
||||
&& typeof globalNS.oauthCallbacks[windowName]
|
||||
=== 'function') {
|
||||
return globalNS.oauthCallbacks[windowName];
|
||||
globalNS.oauthCallbacks[windowName]();
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var callback = getParentWindowCallback();
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
} else {
|
||||
alert('Something went wrong!');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body />
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue