Skip to content

Commit

Permalink
馃洜 Drive with TailwindUI (#2647)
Browse files Browse the repository at this point in the history
* Create hooks for new Drive in node

* Built UI components for Drive

* Fix https://huntr.dev/bounties/e0aaded8-dd59-49f0-b079-291bb7571493/

* FIx unix() is not a function

* Fix some cassandra related stuff

* Fix rebase

* Continuing drive

* Finished basic working version of Drive

* Temp fix for size of document

* Create zip is back
  • Loading branch information
RomaricMourgues committed Jan 17, 2023
1 parent fd4694f commit d90fab7
Show file tree
Hide file tree
Showing 48 changed files with 1,364 additions and 2,043 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,6 @@ export class DriveFile {
@Column("hidden_data", "encoded_json")
hidden_data: unknown;

@Type(() => String)
@Column("workspace_id", "uuid")
workspace_id: string;

@Type(() => String)
@Column("public_access_key", "string")
public_access_key: string;

@Type(() => String)
@Column("root_group_folder", "string")
root_group_folder: string;
Expand Down Expand Up @@ -124,7 +116,7 @@ export class DriveFile {
}

type AccessInformation = {
public: {
public?: {
token: string;
level: publicAccessLevel;
};
Expand Down
6 changes: 2 additions & 4 deletions twake/backend/node/src/services/documents/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const getDefaultDriveItem = (
},
],
public: {
level: "read",
level: "none",
token: generateAccessToken(),
},
},
Expand All @@ -63,8 +63,6 @@ export const getDefaultDriveItem = (
size: item.size || 0,
tags: item.tags || [],
url: item.url || "",
public_access_key: item.public_access_key || generateAccessToken(),
workspace_id: item.workspace_id || "",
});

if (item.id) {
Expand Down Expand Up @@ -113,7 +111,7 @@ export const getDefaultDriveItemVersion = (
* @returns {String} - the random access token ( sha1 hex digest ).
*/
const generateAccessToken = (): string => {
const randomBytes = crypto.randomBytes(32);
const randomBytes = crypto.randomBytes(64);

return crypto.createHash("sha1").update(randomBytes).digest("hex");
};
Expand Down
2 changes: 0 additions & 2 deletions twake/backend/node/src/services/documents/web/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ const documentSchema = {
},
content_keywords: { type: "string" },
hidden_data: {},
public_access_key: { type: "string" },
workspace_id: { type: "string" },
root_group_folder: { type: "string" },
creator: { type: "string" },
size: { type: "number" },
Expand Down
10 changes: 4 additions & 6 deletions twake/frontend/src/app/components/drive/ui/file.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import FileType from './file-type';
import TagPicker from 'components/tag-picker/tag-picker';
import { addApiUrlIfNeeded } from 'app/features/global/utils/URLUtils';
import '../drive.scss';
import { formatTime } from '@features/global/utils/Numbers';

export default class File extends React.Component {
constructor() {
Expand All @@ -20,16 +21,13 @@ export default class File extends React.Component {
render() {
var date = false;
if (this.props.data.modified) {
date = moment(this.props.data.modified * 1000);
date = new Date(this.props.data.modified * 1000);
}
if (this.props.data.added && this.props.isVersion) {
date = moment(this.props.data.added * 1000);
date = new Date(this.props.data.added * 1000);
}

var date_string = date ? date.format('L') : '-';
if (new Date().getTime() - date.unix() * 1000 < 1000 * 23 * 60 * 60) {
date_string = date ? date.format('LT') : '-';
}
var date_string = date ? formatTime(date) : '-';

return [
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const ChannelAccessForm = (props: {
const [loading, setLoading] = useState(false);

return (
<div className="w-screen max-w-xs">
<div className="w-screen max-w-sm p-4 -m-4">
<Block
className="my-4"
avatar={<></>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const ChannelGroupSelector = (props: { group: string; onChange: (str: string) =>
}, [groups]);

return (
<div className="w-screen max-w-xs">
<div className="w-screen max-w-sm p-4 -m-4">
<hr className="my-1 -mx-4 mb-3" />

{groups.map(g => (
Expand Down Expand Up @@ -117,7 +117,7 @@ export const ChannelInformationForm = (props: {
const [icon, setIcon] = useState(props.channel?.icon || '');

return (
<div className="w-screen max-w-xs">
<div className="w-screen max-w-sm p-4 -m-4">
<Modal open={channelGroupModal !== false} onClose={() => setChannelGroupModal(false)}>
<ModalContent title={Languages.t('scenes.app.channelsbar.channel_information.group.title')}>
<ChannelGroupSelector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const ChannelNotificationsForm = (props: { channel?: ChannelType; onBack:
};

return (
<div className="w-screen max-w-xs">
<div className="w-screen max-w-sm p-4 -m-4">
<Block
className="my-4"
avatar={<></>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const ChannelSettingsMenu = (props: {
user?.id === props.channel?.owner || workspaceUserRightsService.hasWorkspacePrivilege();

return (
<div className="w-screen max-w-xs">
<div className="w-screen max-w-sm p-4 -m-4">
{!isDirect && (
<>
<Block
Expand Down
4 changes: 1 addition & 3 deletions twake/frontend/src/app/components/edit-channel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const EditChannelModal = () => {
<Modal
open={channelModal.open}
onClose={() => setChannelModal({ ...channelModal, open: false })}
className="int-channel-edit-modal"
className="int-channel-edit-modal !max-w-sm"
>
{!channelModal.channelId && <CreateChannelForm />}
{!!channelModal.channelId && <EditChannelForm />}
Expand Down Expand Up @@ -77,7 +77,6 @@ const EditChannelForm = () => {
style={{
display: 'grid',
gridTemplate: '1fr / 1fr',
placeItems: 'center',
}}
>
<Transition
Expand Down Expand Up @@ -207,7 +206,6 @@ const CreateChannelForm = () => {
style={{
display: 'grid',
gridTemplate: '1fr / 1fr',
placeItems: 'center',
}}
>
<Transition
Expand Down
206 changes: 206 additions & 0 deletions twake/frontend/src/app/components/uploads/file-tree-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
type TreeItem = { [key: string]: File | TreeItem };

export type FileTreeObject = {
tree: TreeItem;
documentsCount: number;
totalSize: number;
};

export const getFilesTree = (
event: Event & { dataTransfer: DataTransfer },
fcb?: (tree: any, documentsCount: number, totalSize: number) => void,
): Promise<FileTreeObject> => {
return new Promise<FileTreeObject>(function (resolve) {
function newDirectoryApi(input: DataTransfer, cb: (files?: File[], paths?: string[]) => void) {
const fd: any[] = [],
files: any[] = [];
const iterate = function (entries: any[], path: string, resolve: (v: any[]) => void) {
const promises: any[] = [];
entries.forEach(function (entry: any) {
promises.push(
new Promise(function (resolve) {
if ('getFilesAndDirectories' in entry) {
entry.getFilesAndDirectories().then(function (entries: any[]) {
iterate(entries, entry.path + '/', resolve);
});
} else {
if (entry.name) {
const p = (path + entry.name).replace(/^[/\\]/, '');
fd.push(entry);
files.push(p);

if (files.length > 1000000) {
return false;
}
}
resolve(true);
}
}),
);
});

if (files.length > 1000000) {
return false;
}

Promise.all(promises).then(resolve);
};
(input as any).getFilesAndDirectories().then(function (entries: any) {
new Promise(function (resolve) {
iterate(entries, '/', resolve);
}).then(cb.bind(null, fd, files));
});
}

// old prefixed API implemented in Chrome 11+ as well as array fallback
function arrayApi(input: DataTransfer, cb: (files?: File[], paths?: string[]) => void) {
const fd: any[] = [],
files: any[] = [];
[].slice.call(input.files).forEach(function (file: File) {
fd.push(file);
files.push(file.webkitRelativePath || file.name);

if (files.length > 1000000) {
return false;
}
});

if (files.length > 1000000) {
return false;
}

cb(fd, files);
}

// old drag and drop API implemented in Chrome 11+
function entriesApi(
items: DataTransferItemList,
cb: (files?: File[], paths?: string[]) => void,
) {
const fd: any[] = [],
files: any[] = [],
rootPromises: any[] = [];

function readEntries(entry: any, reader: any, oldEntries: any, cb: any) {
const dirReader = reader || entry.createReader();
dirReader.readEntries(function (entries: any) {
const newEntries = oldEntries ? oldEntries.concat(entries) : entries;
if (entries.length) {
setTimeout(readEntries.bind(null, entry, dirReader, newEntries, cb), 0);
} else {
cb(newEntries);
}
});
}

function readDirectory(entry: any, path: null | string, resolve: (v: any) => void) {
if (!path) path = entry.name;
readEntries(entry, 0, 0, function (entries: any[]) {
const promises: Promise<any>[] = [];
entries.forEach(function (entry: any) {
promises.push(
new Promise(function (resolve) {
if (entry.isFile) {
entry.file(function (file: File) {
const p = path + '/' + file.name;
fd.push(file);
files.push(p);
if (files.length > 1000000) {
return false;
}
resolve(true);
}, resolve.bind(null, true));
} else readDirectory(entry, path + '/' + entry.name, resolve);
}),
);
});
Promise.all(promises).then(resolve.bind(null, true));
});
}

[].slice.call(items).forEach(function (entry: any) {
entry = entry.webkitGetAsEntry();
if (entry) {
rootPromises.push(
new Promise(function (resolve) {
if (entry.isFile) {
entry.file(function (file: File) {
fd.push(file);
files.push(file.name);
if (files.length > 1000000) {
return false;
}
resolve(true);
}, resolve.bind(null, true));
} else if (entry.isDirectory) {
readDirectory(entry, null, resolve);
}
}),
);
}
});

if (files.length > 1000000) {
return false;
}

Promise.all(rootPromises).then(cb.bind(null, fd, files));
}

const cb = function (event: Event, files: File[], paths?: string[]) {
const documents_number = paths ? paths.length : 0;
let total_size = 0;
const tree: any = {};
(paths || []).forEach(function (path, file_index) {
let dirs = tree;
const real_file = files[file_index];

total_size += real_file.size;

path.split('/').forEach(function (dir, dir_index) {
if (dir.indexOf('.') === 0) {
return;
}
if (dir_index === path.split('/').length - 1) {
dirs[dir] = real_file;
} else {
if (!dirs[dir]) {
dirs[dir] = {};
}
dirs = dirs[dir];
}
});
});

fcb && fcb(tree, documents_number, total_size);
resolve({ tree, documentsCount: documents_number, totalSize: total_size });
};

if (event.dataTransfer) {
const dt = event.dataTransfer;
if (dt.items && dt.items.length && 'webkitGetAsEntry' in dt.items[0]) {
entriesApi(dt.items, (files, paths) => cb(event, files || [], paths));
} else if ('getFilesAndDirectories' in dt) {
newDirectoryApi(dt, (files, paths) => cb(event, files || [], paths));
} else if (dt.files) {
arrayApi(dt, (files, paths) => cb(event, files || [], paths));
} else cb(event, [], []);
} else if (event.target) {
const t = event.target as any;
if (t.files && t.files.length) {
arrayApi(t, (files, paths) => cb(event, files || [], paths));
} else if ('getFilesAndDirectories' in t) {
newDirectoryApi(t, (files, paths) => cb(event, files || [], paths));
} else {
cb(event, [], []);
}
} else {
fcb && fcb([(event.target as any).files[0]], 1, (event.target as any).files[0].size);
resolve({
tree: (event.target as any).files[0],
documentsCount: 1,
totalSize: (event.target as any).files[0].size,
});
}
});
};
Loading

0 comments on commit d90fab7

Please sign in to comment.