Skip to content

Commit

Permalink
Add complete transitions support
Browse files Browse the repository at this point in the history
  • Loading branch information
safrazik committed Jul 25, 2020
1 parent 9242f1d commit 2131250
Show file tree
Hide file tree
Showing 4 changed files with 387 additions and 22 deletions.
37 changes: 35 additions & 2 deletions packages/core/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
crossorigin="anonymous"
/> -->
<link rel="stylesheet" href="../dist/file-agent.css" />
<style type="text/css">
body {
background-color: #333;
color: #fff;
}
</style>
</head>

<body>
Expand Down Expand Up @@ -74,6 +80,16 @@ <h3>File Preview</h3>
url: 'files/House Sparrow.jpg',
progress: 67,
},
{
name: 'UNDELETABLE System file.sys',
lastModified: 1583992794341,
sizeText: '14 KB',
size: 14403,
type: 'system/file',
ext: 'sys',
url: 'files/UNDELETABLE System file.sys',
progress: 10,
},
{
name: 'Golf.mp4',
lastModified: 1576563996233,
Expand Down Expand Up @@ -104,9 +120,26 @@ <h3>File Preview</h3>

var maxSize = '4MB';

FileRecord.fromRawArray(rawFileRecords, { read: false, maxSize: maxSize }).then(function (fileRecords) {
// var secFileRecord = rawFileRecords[1];

// setTimeout(() => {
// FileRecord.fromRawArray([secFileRecord], {}).then(function (secFileRecords) {
// window.fileRecords = window.fileRecords
// .slice(0, 1)
// .concat(secFileRecords)
// .concat(window.fileRecords.slice(1));
// window.fileAgent.$props.fileRecords = window.fileRecords;
// window.fileAgent.update();
// });
// }, 2000);

FileRecord.fromRawArray(rawFileRecords.slice(0, 1).concat(rawFileRecords.slice(2)), {
read: false,
maxSize: maxSize,
}).then(function (fileRecords) {
window.fileRecords = fileRecords;
var fileAgent = new FileAgent({
window.fileAgent = new FileAgent({
auto: false,
uploadUrl: 'https://master.tus.io/files/',
resumable: true,
multiple: true,
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/components/file-agent.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
<div data-ref="container" class="grid-block-wrapper vue-file-agent file-input-wrapper">
<div data-slot="beforeInner"></div>
<div data-ref="file-preview-list" class="file-preview-list">
<div data-ref="file-preview-new" class="file-preview-wrapper grid-box-item grid-block file-preview-new">
<div
data-ref="file-preview-new"
class="file-preview-wrapper grid-box-item-for-transition grid-block file-preview-new"
>
<span class="file-preview">
<span style="position: absolute; top: 0; right: 0; bottom: 0; left: 0;">
<icon name="system-file-preview-new"></icon>
Expand Down
202 changes: 183 additions & 19 deletions packages/core/src/components/file-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import utils from '../lib/utils';
// import uploader from '../lib/uploader/upload-helper';
import uploader from '../lib/uploader/uploader';
import plugins from '../lib/plugins';
import { FileAgentProps } from '../lib/props';
import { FileAgentProps, filePreviewProps } from '../lib/props';
import { ConfigureFn } from '../lib/uploader/ajax-request';
import { TransitionManager } from '../lib/transition-manager';

let fileAgentEl: Element;
let newFilePreviewEl: Element;
Expand All @@ -21,6 +22,11 @@ plugins.uploader = uploader;
export { FileAgentProps };

export class FileAgent extends Component {
private cachedElements: {
fileRecord: FileRecord;
filePreview: FilePreview;
child: HTMLElement;
}[] = [];
isDragging = false;
isSorting = false;
isSortingActive = false;
Expand Down Expand Up @@ -57,6 +63,35 @@ export class FileAgent extends Component {
return 'Choose ' + (this.hasMultiple ? 'files' : 'file') + ' or drag & drop here';
}

getFilePreviewForFileRecord(fileRecord: FileRecord) {
const cachedElement = this.cachedElements.filter((ch) => ch.fileRecord === fileRecord)[0];
if (cachedElement) {
return cachedElement.filePreview;
}
return undefined;
}

getChildForFileRecord(fileRecord: FileRecord) {
const cachedElement = this.cachedElements.filter((ch) => ch.fileRecord === fileRecord)[0];
if (cachedElement) {
return cachedElement.child;
}
return undefined;
}

setFilePreviewForFileRecord(fileRecord: FileRecord, filePreview: FilePreview, child: HTMLElement) {
const cachedElement = this.cachedElements.filter((ch) => ch.fileRecord === fileRecord)[0];
if (cachedElement) {
cachedElement.filePreview = filePreview;
return;
}
this.cachedElements.push({
fileRecord,
filePreview,
child,
});
}

equalFiles(file1: File, file2: File): boolean {
return (
true &&
Expand Down Expand Up @@ -704,42 +739,79 @@ export class FileAgent extends Component {
this.updateWrapper();
// const container = this.getRef('file-preview-wrapper-container');
const container = this.getRef('file-preview-list');
// console.log('this.$props.fileRecords', this.$props.fileRecords);
container.innerHTML = '';
const slotContent = this.getSlotContent('filePreviewNew');
if (slotContent) {
container.appendChild(slotContent);
} else {
container.appendChild(newFilePreviewEl);
}
if (!(this as any).isAddedNewFilePreview) {
// console.log('this.$props.fileRecords', this.$props.fileRecords);
container.innerHTML = '';
const slotContent = this.getSlotContent('filePreviewNew');
if (slotContent) {
container.appendChild(slotContent);
} else {
container.appendChild(newFilePreviewEl);
}
(this as any).isAddedNewFilePreview = true;
}
// const newFileElement = container.lastElementChild as HTMLElement;
// const newFileElementFirst = newFileElement.getBoundingClientRect();
const newFileChild = container.lastElementChild as HTMLElement;
// const newFileElement = {
// rect: newFileChild.getBoundingClientRect(),
// child: newFileChild,
// };
this.getRef('help-text').innerText = this.helpTextComputed;

this.insertSlotBefore(this.$el, 'beforeOuter');
this.insertSlotBefore('container', 'beforeInner');
this.insertSlotAfter('container', 'afterInner');
this.insertSlotAfter(this.$el, 'afterOuter');

let index = 0;
for (const fileRecord of this.$props.fileRecords.concat([]).reverse()) {
const child = document.createElement('div');
child.className = 'file-preview-wrapper grid-box-item grid-block';
const fileRecords = this.$props.fileRecords.concat([]).reverse();
const newChildren: HTMLElement[] = [];
// const otherElements: { rect: DOMRect; child: HTMLElement }[] = [];
const otherChildren: HTMLElement[] = [];
const childRects: { rect: DOMRect; child: HTMLElement }[] = [];
// tslint:disable-next-line
for (let i = 0; i < container.children.length; i++) {
const child = container.children[i] as HTMLElement;
childRects.push({ child, rect: child.getBoundingClientRect() });
}
for (const fileRecord of fileRecords) {
let child = this.getChildForFileRecord(fileRecord) as HTMLElement;
if (child) {
if (container.firstChild) {
container.insertBefore(child, container.firstChild);
} else {
container.appendChild(child);
}
// otherElements.push({ child, rect: child.getBoundingClientRect() });
otherChildren.push(child);
continue;
}
if (!child) {
child = document.createElement('div');
}
child.className = 'file-preview-wrapper grid-box-item-for-transition grid-block';
if (this.$props.slots?.filePreview) {
const previewSlotContent = this.getSlotContentParsed(this.$props.slots.filePreview(fileRecord, index));
child.appendChild(previewSlotContent);
} else {
let filePreview: FilePreview = (fileRecord as any)._filePreview;
// let filePreview: FilePreview = (fileRecord as any)._filePreview;
let filePreview = this.getFilePreviewForFileRecord(fileRecord) as FilePreview;
if (!filePreview) {
console.log('new filePreview...');
filePreview = new FilePreview({
fileRecord,
averageColor: this.$props.averageColor,
deletable: this.$props.deletable,
editable: this.$props.editable,
linkable: this.$props.linkable,
disabled: this.$props.disabled,
fileRecord,
onRename: (fr) => {
this.onRenameFileRecord(fr);
},
onDelete: (fr) => {
this.onDeleteFileRecord(fr);
},
// errorText: this.$props.errorText,
});
// (fileRecord as any)._filePreview = filePreview;
fileRecord.onChange.progress = () => {
Expand All @@ -760,24 +832,116 @@ export class FileAgent extends Component {
fileRecord.onChange.error = () => {
filePreview.updateError();
};
// child.classList.add('grid-box-enter');
// setTimeout(() => {
// child.classList.remove('grid-box-enter');
// }, 10);
this.setFilePreviewForFileRecord(fileRecord, filePreview, child);
newChildren.push(child);
} else {
console.log('EXISTING filePreview...');
filePreview.updateWrapper();
// filePreview.updateProgress();
filePreview.updateError();
}
filePreview.render(child);
}
// animation:test:begin
// setTimeout(() => {
// child.classList.remove('grid-box-enter');
// }, 10);
// animation:test:end
if (container.firstChild) {
container.insertBefore(child, container.firstChild);
} else {
container.appendChild(child);
}
index++;
}
// newFileElementFirst;
const removedElements = this.cachedElements.filter((ch) => fileRecords.indexOf(ch.fileRecord) === -1);
const removedChildren = removedElements.map((ch) => ch.child);
const enableTransitions = true;
if (!enableTransitions) {
removedChildren.map((child) => container.removeChild(child));
} else {
// let displayValue = 'inline-block';
// removedChildren.map((child) => {
// displayValue = child.style.display;
// child.style.display = 'none';
// });

// transitionManager.addElements(newChildren);
// transitionManager.transformNewElement(newFileElement, newFileElementFirst);
// removedChildren.map((child) => {
// child.style.position = 'absolute';
// child.style.display = displayValue;
// child.style.opacity = '0.25';
// });
// transitionManager.removeElements(removedChildren);
const transitionManager = new TransitionManager(this.$props.theme);
transitionManager.applyTransitions(
newChildren,
removedChildren,
// otherElements.concat([newFileElement]),
otherChildren.concat(newFileChild),
childRects,
);
}

// setTimeout(() => {
// }, 1);
// removedChildren.map((child) => container.removeChild(child));
// const newEl = container.lastElementChild as HTMLElement;
// const first = newEl.getBoundingClientRect();
const removeElement = (ch: typeof removedElements[0]) => {
return new Promise((resolve, reject) => {
const removedChild = ch.filePreview.$el.parentElement;
if (!removedChild) {
return;
}
// console.log('removedChildremovedChild', removedChild, removedChild?.parentElement, ch.filePreview);
// removedChild.classList.add('grid-box-leave-active');
removedChild.classList.add('grid-box-leave-to');
// setTimeout(() => {
removedChild.addEventListener('transitionend', () => {
removedChild?.parentElement?.removeChild(removedChild);
resolve();
});
// }, 300);
requestAnimationFrame(() => {
// remove after 1 frame
requestAnimationFrame(() => {
// removedChild.classList.remove('grid-box-leave-to');
});
});
});
};
// Promise.all(removedElements.map((ch) => removeElement(ch))).then(() => {
// requestAnimationFrame(() => {
// const last = newEl.getBoundingClientRect();
// console.log('ok complete2', first, last);
// // Invert.
// const transform = `translate3d(${first.left - last.left}px, ${first.top - last.top}px, 0)`;
// newEl.style.transform = transform;
// console.log('newEl.style.transform', transform);
// // Wait for the next frame so we
// // know all the style changes have
// // taken hold.
// requestAnimationFrame(() => {
// // Switch on animations.
// // newEl.classList.add('animate-on-transforms');
// // GO GO GOOOOOO!
// newEl.style.transform = '';
// });
// });
// // setTimeout(() => {
// // }, 100);

// // Capture the end with transitionend
// newEl.addEventListener('transitionend', () => {
// // newEl.style.transform = '';
// //
// });
// //
// });
this.cachedElements = this.cachedElements.filter((ch) => removedElements.indexOf(ch) === -1);
const input = this.getRef<HTMLInputElement>('file-input');
input.disabled = this.$props.disabled === true || (this.hasMultiple && !this.canAddMore);
input.multiple = this.hasMultiple;
Expand Down
Loading

0 comments on commit 2131250

Please sign in to comment.