feat(ui): support sharing
This commit is contained in:
parent
86474e044f
commit
752768a916
8 changed files with 187 additions and 46 deletions
|
@ -16,8 +16,6 @@ import {
|
|||
import { Up } from "../worker/upload_mgr";
|
||||
import { UploadEntry } from "../worker/interface";
|
||||
|
||||
export const uploadCheckCycle = 1000;
|
||||
|
||||
export interface Item {
|
||||
name: string;
|
||||
size: number;
|
||||
|
@ -28,8 +26,10 @@ export interface Item {
|
|||
|
||||
export interface Props {
|
||||
dirPath: List<string>;
|
||||
isSharing: boolean;
|
||||
items: List<MetadataResp>;
|
||||
uploadings: List<UploadInfo>;
|
||||
sharings: List<string>;
|
||||
|
||||
uploadFiles: List<File>;
|
||||
uploadValue: string;
|
||||
|
@ -191,6 +191,12 @@ export class Browser extends React.Component<Props, State, {}> {
|
|||
|
||||
updater()
|
||||
.setItems(dirPath)
|
||||
.then(() => {
|
||||
updater().listSharings();
|
||||
})
|
||||
.then(() => {
|
||||
updater().setSharing(dirPath.join("/"));
|
||||
})
|
||||
.then(() => {
|
||||
this.update(updater().setBrowser);
|
||||
});
|
||||
|
@ -235,6 +241,40 @@ export class Browser extends React.Component<Props, State, {}> {
|
|||
});
|
||||
};
|
||||
|
||||
addSharing = () => {
|
||||
updater()
|
||||
.addSharing()
|
||||
.then((ok) => {
|
||||
if (!ok) {
|
||||
alert("failed to enable sharing");
|
||||
} else {
|
||||
this.listSharings();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
deleteSharing = (dirPath: string) => {
|
||||
updater()
|
||||
.deleteSharing(dirPath)
|
||||
.then((ok) => {
|
||||
if (!ok) {
|
||||
alert("failed to disable sharing");
|
||||
} else {
|
||||
this.listSharings();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
listSharings = () => {
|
||||
updater()
|
||||
.listSharings()
|
||||
.then((ok) => {
|
||||
if (ok) {
|
||||
this.update(updater().setBrowser);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const breadcrumb = this.props.dirPath.map(
|
||||
(pathPart: string, key: number) => {
|
||||
|
@ -308,10 +348,29 @@ export class Browser extends React.Component<Props, State, {}> {
|
|||
<button
|
||||
type="button"
|
||||
onClick={() => this.moveHere()}
|
||||
className="grey1-bg white-font margin-t-m margin-b-m"
|
||||
className="grey1-bg white-font margin-t-m margin-b-m margin-r-m"
|
||||
>
|
||||
Paste
|
||||
</button>
|
||||
{this.props.isSharing ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
this.deleteSharing(this.props.dirPath.join("/"));
|
||||
}}
|
||||
className="red0-bg white-font margin-t-m margin-b-m"
|
||||
>
|
||||
Stop Sharing
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={this.addSharing}
|
||||
className="green0-bg white-font margin-t-m margin-b-m"
|
||||
>
|
||||
Share Folder
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -418,6 +477,24 @@ export class Browser extends React.Component<Props, State, {}> {
|
|||
);
|
||||
});
|
||||
|
||||
const sharingList = this.props.sharings.map((dirPath: string) => {
|
||||
<div key={dirPath} className="flex-list-container">
|
||||
<span className="flex-list-item-l">{dirPath}</span>
|
||||
<span className="flex-list-item-r">
|
||||
<button
|
||||
onClick={() => {
|
||||
this.deleteSharing(dirPath);
|
||||
}}
|
||||
className="grey1-bg white-font"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</span>
|
||||
</div>;
|
||||
});
|
||||
|
||||
console.log("browser", this.props.sharings, this.props.isSharing);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div id="op-bar" className="op-bar">
|
||||
|
@ -432,7 +509,7 @@ export class Browser extends React.Component<Props, State, {}> {
|
|||
backgroundColor: "rgba(0, 0, 0, 0.7)",
|
||||
padding: "0.8rem 1rem",
|
||||
fontWeight: "bold",
|
||||
borderRadius: "0.5rem"
|
||||
borderRadius: "0.5rem",
|
||||
}}
|
||||
>
|
||||
Location:
|
||||
|
@ -453,6 +530,19 @@ export class Browser extends React.Component<Props, State, {}> {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{this.props.sharings.size === 0 ? null : (
|
||||
<div className="container">
|
||||
<div className="flex-list-container bold">
|
||||
<span className="flex-list-item-l">
|
||||
<span className="dot black-bg"></span>
|
||||
<span>Uploading Files</span>
|
||||
</span>
|
||||
<span className="flex-list-item-r padding-r-m"></span>
|
||||
</div>
|
||||
{sharingList}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="container">
|
||||
<div className="flex-list-container bold">
|
||||
<span className="flex-list-item-l">
|
||||
|
|
|
@ -25,21 +25,18 @@ export class Updater {
|
|||
}
|
||||
|
||||
initUploads = () => {
|
||||
this.props.uploadings.forEach(entry => {
|
||||
this.props.uploadings.forEach((entry) => {
|
||||
Up().addStopped(entry.realFilePath, entry.uploaded, entry.size);
|
||||
})
|
||||
});
|
||||
// this.setUploadings(Up().list());
|
||||
};
|
||||
|
||||
addUploads = (fileList: List<File>) => {
|
||||
fileList.forEach(file => {
|
||||
const filePath = getItemPath(
|
||||
this.props.dirPath.join("/"),
|
||||
file.name
|
||||
);
|
||||
fileList.forEach((file) => {
|
||||
const filePath = getItemPath(this.props.dirPath.join("/"), file.name);
|
||||
// do not wait for the promise
|
||||
Up().add(file, filePath);
|
||||
})
|
||||
});
|
||||
this.setUploadings(Up().list());
|
||||
};
|
||||
|
||||
|
@ -51,18 +48,42 @@ export class Updater {
|
|||
|
||||
setUploadings = (infos: Map<string, UploadEntry>) => {
|
||||
this.props.uploadings = List<UploadInfo>(
|
||||
infos.valueSeq().map(
|
||||
(v: UploadEntry): UploadInfo => {
|
||||
return {
|
||||
realFilePath: v.filePath,
|
||||
size: v.size,
|
||||
uploaded: v.uploaded,
|
||||
};
|
||||
}
|
||||
)
|
||||
infos.valueSeq().map((v: UploadEntry): UploadInfo => {
|
||||
return {
|
||||
realFilePath: v.filePath,
|
||||
size: v.size,
|
||||
uploaded: v.uploaded,
|
||||
};
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
addSharing = async (): Promise<boolean> => {
|
||||
const dirPath = this.props.dirPath.join("/");
|
||||
const resp = await this.filesClient.addSharing(dirPath);
|
||||
return resp.status === 200;
|
||||
};
|
||||
|
||||
deleteSharing = async (dirPath: string): Promise<boolean> => {
|
||||
const resp = await this.filesClient.addSharing(dirPath);
|
||||
return resp.status === 200;
|
||||
};
|
||||
|
||||
setSharing = async (dirPath: string): Promise<boolean> => {
|
||||
const resp = await this.filesClient.isSharing(dirPath);
|
||||
this.props.isSharing = resp.status === 200;
|
||||
return resp.status === 200; // TODO: differentiate 404 and error
|
||||
};
|
||||
|
||||
listSharings = async (): Promise<boolean> => {
|
||||
const resp = await this.filesClient.listSharings();
|
||||
this.props.sharings =
|
||||
resp.status === 200
|
||||
? List<string>(resp.data.sharingDirs)
|
||||
: this.props.sharings;
|
||||
return resp.status === 200;
|
||||
};
|
||||
|
||||
refreshUploadings = async (): Promise<boolean> => {
|
||||
const luResp = await this.filesClient.listUploadings();
|
||||
|
||||
|
@ -93,13 +114,11 @@ export class Updater {
|
|||
.filter((item) => {
|
||||
return selectedItems.has(item.name);
|
||||
})
|
||||
.map(
|
||||
async (selectedItem: MetadataResp): Promise<string> => {
|
||||
const itemPath = getItemPath(dirParts.join("/"), selectedItem.name);
|
||||
const resp = await this.filesClient.delete(itemPath);
|
||||
return resp.status === 200 ? "" : selectedItem.name;
|
||||
}
|
||||
);
|
||||
.map(async (selectedItem: MetadataResp): Promise<string> => {
|
||||
const itemPath = getItemPath(dirParts.join("/"), selectedItem.name);
|
||||
const resp = await this.filesClient.delete(itemPath);
|
||||
return resp.status === 200 ? "" : selectedItem.name;
|
||||
});
|
||||
|
||||
const failedFiles = await Promise.all(delRequests);
|
||||
failedFiles.forEach((failedFile) => {
|
||||
|
@ -156,8 +175,13 @@ export class Updater {
|
|||
};
|
||||
|
||||
setBrowser = (prevState: ICoreState): ICoreState => {
|
||||
prevState.panel.browser = { ...prevState.panel, ...this.props };
|
||||
return prevState;
|
||||
return {
|
||||
...prevState,
|
||||
panel: {
|
||||
...prevState.panel,
|
||||
browser: { ...this.props }, // TODO: use spread
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ export function initState(): ICoreState {
|
|||
isVertical: isVertical(),
|
||||
dirPath: List<string>(["."]),
|
||||
items: List<Item>([]),
|
||||
sharings: List<string>([]),
|
||||
isSharing: false,
|
||||
uploadings: List<UploadInfo>([]),
|
||||
uploadValue: "",
|
||||
uploadFiles: List<File>([]),
|
||||
|
@ -91,6 +93,8 @@ export function mockState(): ICoreState {
|
|||
isVertical: false,
|
||||
dirPath: List<string>(["."]),
|
||||
items: List<Item>([]),
|
||||
sharings: List<string>([]),
|
||||
isSharing: false,
|
||||
uploadings: List<UploadInfo>([]),
|
||||
uploadValue: "",
|
||||
uploadFiles: List<File>([]),
|
||||
|
|
|
@ -377,7 +377,7 @@ export class AdminPane extends React.Component<Props, State, {}> {
|
|||
render() {
|
||||
const userList = this.props.users.valueSeq().map((user: User) => {
|
||||
return (
|
||||
<div className="margin-t-m">
|
||||
<div key={user.id} className="margin-t-m">
|
||||
<UserForm
|
||||
key={user.id}
|
||||
id={user.id}
|
||||
|
|
|
@ -139,6 +139,14 @@ export class AuthPane extends React.Component<Props, State, {}> {
|
|||
.then(() => {
|
||||
return BrowserUpdater().refreshUploadings();
|
||||
})
|
||||
.then(() => {
|
||||
return BrowserUpdater().setSharing(
|
||||
BrowserUpdater().props.dirPath.join("/")
|
||||
);
|
||||
})
|
||||
.then(() => {
|
||||
return BrowserUpdater().listSharings();
|
||||
})
|
||||
.then((_: boolean) => {
|
||||
this.update(BrowserUpdater().setBrowser);
|
||||
});
|
||||
|
|
|
@ -117,7 +117,6 @@ export class Updater {
|
|||
};
|
||||
|
||||
static updateState = (prevState: ICoreState): ICoreState => {
|
||||
console.log(prevState, Updater.props);
|
||||
return {
|
||||
...prevState,
|
||||
panel: {
|
||||
|
|
|
@ -43,6 +43,8 @@ export class RootFrame extends React.Component<Props, State, {}> {
|
|||
|
||||
render() {
|
||||
const update = this.props.update;
|
||||
console.log("rootframe", this.props.browser.isSharing);
|
||||
|
||||
return (
|
||||
<div className="theme-white desktop">
|
||||
<div id="bg" className="bg bg-img font-m">
|
||||
|
@ -88,6 +90,8 @@ export class RootFrame extends React.Component<Props, State, {}> {
|
|||
dirPath={this.props.browser.dirPath}
|
||||
items={this.props.browser.items}
|
||||
uploadings={this.props.browser.uploadings}
|
||||
sharings={this.props.browser.sharings}
|
||||
isSharing={this.props.browser.isSharing}
|
||||
update={update}
|
||||
uploadFiles={this.props.browser.uploadFiles}
|
||||
uploadValue={this.props.browser.uploadValue}
|
||||
|
|
|
@ -24,15 +24,13 @@ export class StateMgr extends React.Component<Props, State, {}> {
|
|||
|
||||
LoginPaneUpdater.init(state.panel.authPane);
|
||||
LoginPaneUpdater.setClient(new UsersClient(""));
|
||||
LoginPaneUpdater.getCaptchaID()
|
||||
.then((ok: boolean) => {
|
||||
if (!ok) {
|
||||
alert("failed to get captcha id");
|
||||
} else {
|
||||
this.update(LoginPaneUpdater.setAuthPane);
|
||||
console.log(LoginPaneUpdater)
|
||||
}
|
||||
});
|
||||
LoginPaneUpdater.getCaptchaID().then((ok: boolean) => {
|
||||
if (!ok) {
|
||||
alert("failed to get captcha id");
|
||||
} else {
|
||||
this.update(LoginPaneUpdater.setAuthPane);
|
||||
}
|
||||
});
|
||||
|
||||
BrowserUpdater()
|
||||
.setHomeItems()
|
||||
|
@ -42,28 +40,42 @@ export class StateMgr extends React.Component<Props, State, {}> {
|
|||
.then((_: boolean) => {
|
||||
BrowserUpdater().initUploads();
|
||||
})
|
||||
.then(() => {
|
||||
BrowserUpdater().setSharing(BrowserUpdater().props.dirPath.join("/"));
|
||||
})
|
||||
.then(() => {
|
||||
BrowserUpdater().listSharings();
|
||||
})
|
||||
.then(() => {
|
||||
this.update(BrowserUpdater().setBrowser);
|
||||
console.log("0", this.state, BrowserUpdater().props);
|
||||
})
|
||||
.then(() => {
|
||||
return PanesUpdater.self();
|
||||
PanesUpdater.self();
|
||||
console.log("1", this.state);
|
||||
})
|
||||
.then(() => {
|
||||
return PanesUpdater.listRoles();
|
||||
PanesUpdater.listRoles();
|
||||
console.log("2", this.state);
|
||||
})
|
||||
.then((_: boolean) => {
|
||||
return PanesUpdater.listUsers();
|
||||
.then(() => {
|
||||
PanesUpdater.listUsers();
|
||||
console.log("3", this.state);
|
||||
})
|
||||
.then((_: boolean) => {
|
||||
.then(() => {
|
||||
this.update(PanesUpdater.updateState);
|
||||
console.log("final", this.state);
|
||||
});
|
||||
};
|
||||
|
||||
update = (apply: (prevState: ICoreState) => ICoreState): void => {
|
||||
this.setState(apply(this.state));
|
||||
console.log("core", this.state);
|
||||
};
|
||||
|
||||
render() {
|
||||
console.log("state_mgr", this.state.panel.browser.isSharing);
|
||||
|
||||
return (
|
||||
<RootFrame
|
||||
authPane={this.state.panel.authPane}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue