Skip to content

Commit

Permalink
#48 Implementing gdrive upload progress notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
Kirill Volkovich committed Nov 10, 2017
1 parent 2b7ea6e commit 4b3280a
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
padding: 8px 0;
}

.oc-fm--file-navigator__notifications {
width: 240px;
position: absolute;
right: 24px;
bottom: 12px;
z-index: 10;
}

@keyframes keyframes-oc-fm--file-navigator__view-loading-overlay-appearing {
0% { background-color: rgba(0, 0, 0, 0.0); }
100% { background-color: rgba(0, 0, 0, 0.78); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react';
import './FileNavigator.less';
import ListView from '../ListView';
import LocationBar from '../LocationBar';
import Notifications from '../Notifications';
import { SortDirection } from 'react-virtualized';
import { findIndex } from 'lodash';
import nanoid from 'nanoid';
Expand Down Expand Up @@ -38,19 +39,20 @@ class FileNavigator extends Component {
constructor(props) {
super(props);
this.state = {
apiInitialized: false,
apiSignedIn: false,
config: {},
error: null,
selection: [],
sortBy: 'title',
sortDirection: SortDirection.ASC,
dialogElement: null,
resource: {},
resourceLocation: [],
resourceChildren: [],
error: null,
loadingResourceLocation: false,
loadingView: false,
apiInitialized: false,
apiSignedIn: false
notifications: [],
resource: {},
resourceChildren: [],
resourceLocation: [],
selection: [],
sortBy: 'title',
sortDirection: SortDirection.ASC
};
}

Expand Down Expand Up @@ -255,33 +257,38 @@ class FileNavigator extends Component {
this.setState({ dialogElement: null });
}

updateNotifications = (notifications) => {
this.setState({ notifications });
}

render() {
let {
api,
apiOptions,
capabilities,
className,
id,
capabilities,
initialResourceId,
listViewLayout,
viewLayoutOptions,
signInRenderer
signInRenderer,
viewLayoutOptions
} = this.props;

let {
apiInitialized,
apiSignedIn,
config,
error,
dialogElement,
loadingView,
error,
loadingResourceLocation,
loadingView,
notifications,
resource,
resourceLocation,
resourceChildren,
resourceLocation,
selection,
sortBy,
sortDirection,
apiInitialized,
apiSignedIn
sortDirection
} = this.state;

let viewLoadingElement = null;
Expand Down Expand Up @@ -320,21 +327,24 @@ class FileNavigator extends Component {
let contextMenuChildren = capabilities(apiOptions, {
showDialog: this.showDialog,
hideDialog: this.hideDialog,
updateNotifications: this.updateNotifications,
forceUpdate: resource.id ? () => this.navigateToDir(resource.id) : () => {}
}).
filter(capability => capability.shouldBeAvailable(apiOptions, {
selection,
selectedResources,
resource,
resourceChildren,
resourceLocation
resourceLocation,
notifications
})).
map(capability => capability.contextMenuRenderer(apiOptions, {
selection,
selectedResources,
resource,
resourceChildren,
resourceLocation
resourceLocation,
notifications
}));

return (
Expand Down Expand Up @@ -369,7 +379,12 @@ class FileNavigator extends Component {
contextMenuChildren={contextMenuChildren}
layout={listViewLayout}
layoutOptions={viewLayoutOptions}
/>
>
<Notifications
className="oc-fm--file-navigator__notifications"
notifications={notifications}
/>
</ListView>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ class ListView extends Component {
<ContextMenu triggerId={contextMenuId}>
{contextMenuChildren.map((contextMenuChild, i) => ({ ...contextMenuChild, key: i }))}
</ContextMenu>
{this.props.children}
</div>
)}
</AutoSizer>
Expand Down
19 changes: 16 additions & 3 deletions client-react/src/client/components/Notification/Notification.less
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,31 @@
}

.oc-fm--notification {
border-radius: 4px;
border-radius: 2px;
overflow: hidden;
box-shadow: rgba(0, 0, 0, 0.25) 0px 2px 16px, rgba(0, 0, 0, 0.15) 0px 1px 4px;
animation: keyframes-oc-fm--notification-appearing 240ms;
animation-timing-function: ease-in-out;
background-color: #fff;
pointer-events: auto;
}

.oc-fm--notification__items {
max-height: 240px;
overflow: auto;
will-change: max-height;
transition: max-height 180ms ease-in-out;
}

.oc-fm--notification__items--minimized {
max-height: 0;
will-change: max-height;
transition: max-height 180ms ease-in-out;
}

.oc-fm--notification__header {
display: flex;
background-color: #3b4a56;
background-color: #333;
justify-content: space-between;
align-items: center;
padding: 8px 12px;
Expand All @@ -39,7 +53,6 @@
.oc-fm--notification__header-icon {
display: inline-flex;
align-items: center;
padding: 4px;
position: relative;
border-radius: 2px;
overflow: hidden;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React, { Component, Children, PropTypes } from 'react';
import './Notification.less';
import SVG from '@opuscapita/react-svg/lib/SVG';

let minimizeIcon = require('!!raw-loader!@opuscapita/svg-icons/lib/keyboard_arrow_up.svg');
let maximizeIcon = require('!!raw-loader!@opuscapita/svg-icons/lib/keyboard_arrow_down.svg');
let minimizeIcon = require('!!raw-loader!@opuscapita/svg-icons/lib/keyboard_arrow_down.svg');
let maximizeIcon = require('!!raw-loader!@opuscapita/svg-icons/lib/keyboard_arrow_up.svg');
let closeIcon = require('!!raw-loader!@opuscapita/svg-icons/lib/close.svg');

const propTypes = {
Expand All @@ -16,7 +16,7 @@ const propTypes = {
title: PropTypes.node
};
const defaultProps = {
closable: true,
closable: false,
minimizable: true,
onHide: () => {},
progressText: '',
Expand Down Expand Up @@ -70,8 +70,8 @@ class Notification extends Component {
</div>
) : null;

let itemsElement = (minimized || !children) ? null : (
<div className="oc-fm--notification__items">
let itemsElement = (
<div className={`oc-fm--notification__items ${minimized ? 'oc-fm--notification__items--minimized' : ''}`}>
{children.map((child, i) => ({ ...child, key: i }))}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,24 @@
display: flex;
width: 100%;
align-items: center;
padding: 8px 12px;
}

.oc-fm--notification-progress-item__title {
overflow: hidden;
text-overflow: ellipsis;
margin-right: 8px;
display: inline;
}

.oc-fm--notification-progress-item__icon,
.oc-fm--notification-progress-item__title,
.oc-fm--notification-progress-item__progress-icon {
display: inline-flex;
align-items: center;
}

.oc-fm--notification-progress-item__icon {
margin-right: 12px;
margin-right: 8px;
}

.oc-fm--notification-progress-item__progress-icon {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.oc-fm--notifications {

pointer-events: none;
}

.oc-fm--notifications__item {
margin-bottom: 24px;
margin-bottom: 12px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Notifications extends Component {
}

render() {
let { notifications } = this.props;
let { notifications, className } = this.props;

let notificationsElement = notifications.map((notification, i) => (
<div key={i} className="oc-fm--notifications__item">
Expand All @@ -26,7 +26,7 @@ class Notifications extends Component {
));

return (
<div className="oc-fm--notifications">
<div className={`oc-fm--notifications ${className || ''}`}>
{notificationsElement}
</div>
);
Expand Down
9 changes: 7 additions & 2 deletions client-react/src/client/components/Notifications/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { findIndex, extend } from 'lodash';
import { find, findIndex, extend } from 'lodash';

function addNotification(notifications, id, props) {
let index = findIndex(notifications, (o) => o.id === id);
Expand All @@ -19,12 +19,17 @@ function updateNotification(notifications, id, props) {
});
}

function getNotificationById(notifications, id) {
return find(notifications, (o) => o.id === id);
}

function removeNotification(notifications, id) {
return notifications.filter(o => o.id !== id);
}

export default {
addNotification,
updateNotification,
removeNotification
removeNotification,
getNotificationById
};
8 changes: 7 additions & 1 deletion client-react/src/client/connectors/google_drive_v2/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,12 @@ async function uploadChunk({ sessionUrl, size, startByte, content }) {
});
}

async function uploadFileToId(parentId) {
async function uploadFileToId(parentId, { onStart, onSuccess, onFail, onProgress }) {
let file = await readLocalFile();
let size = file.content.length;
let sessionUrl = await initResumableUploadSession({ name: file.name, size, parentId: 'root' });
let startByte = 0;
onStart({ name: file.name, size });

while(startByte < size) {
let res = await uploadChunk({
Expand All @@ -232,9 +233,14 @@ async function uploadFileToId(parentId) {
if (res.status === 308) {
let range = parseRange(size, res.headers['range']);
startByte = range[0].end + 1;

let progress = startByte / (size / 100);
console.log(progress);
onProgress(progress);
}

if (res.status === 200 || res.status === 201) {
onSuccess();
return res;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import download from './download';
import upload from './upload';
import rename from './rename';

export default (apiOptions, { showDialog, hideDialog, forceUpdate }) => ([
createFolder(apiOptions, { showDialog, hideDialog, forceUpdate }),
rename(apiOptions, { showDialog, hideDialog, forceUpdate }),
download(apiOptions, { showDialog, hideDialog, forceUpdate }),
upload(apiOptions, { showDialog, hideDialog, forceUpdate }),
deleteResource(apiOptions, { showDialog, hideDialog, forceUpdate })
export default (apiOptions, { showDialog, hideDialog, forceUpdate, updateNotifications }) => ([
createFolder(apiOptions, { showDialog, hideDialog, forceUpdate, updateNotifications }),
rename(apiOptions, { showDialog, hideDialog, forceUpdate, updateNotifications }),
download(apiOptions, { showDialog, hideDialog, forceUpdate, updateNotifications }),
upload(apiOptions, { showDialog, hideDialog, forceUpdate, updateNotifications }),
deleteResource(apiOptions, { showDialog, hideDialog, forceUpdate, updateNotifications })
]);
Loading

0 comments on commit 4b3280a

Please sign in to comment.