Merge branch 'develop' into bugfix/whitelabel
This commit is contained in:
commit
a54341871e
@ -12,6 +12,12 @@ import config from "PACKAGE_FILE";
|
||||
|
||||
export default function withBadges(WrappedComponent) {
|
||||
class WithBadges extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = { disableBadgeClick: false, disableUnpinClick: false };
|
||||
}
|
||||
|
||||
onShowVersionHistory = () => {
|
||||
const {
|
||||
homepage,
|
||||
@ -28,22 +34,42 @@ export default function withBadges(WrappedComponent) {
|
||||
};
|
||||
|
||||
onBadgeClick = () => {
|
||||
if (this.state.disableBadgeClick) return;
|
||||
|
||||
const { item, markAsRead, setNewFilesPanelVisible } = this.props;
|
||||
this.setState(() => ({
|
||||
disableBadgeClick: true,
|
||||
}));
|
||||
|
||||
const enableBadgeClick = () => {
|
||||
this.setState({ disableBadgeClick: false });
|
||||
};
|
||||
|
||||
if (item.fileExst) {
|
||||
markAsRead([], [item.id], item);
|
||||
markAsRead([], [item.id], item).then(() => {
|
||||
enableBadgeClick();
|
||||
});
|
||||
} else {
|
||||
setNewFilesPanelVisible(true, null, item);
|
||||
setNewFilesPanelVisible(true, null, item).then(() => {
|
||||
enableBadgeClick();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onUnpinClick = (e) => {
|
||||
if (this.state.disableUnpinClick) return;
|
||||
|
||||
this.setState({ disableUnpinClick: true });
|
||||
|
||||
const { t, setPinAction } = this.props;
|
||||
|
||||
const { action, id } = e.target.closest(".is-pinned").dataset;
|
||||
|
||||
if (!action && !id) return;
|
||||
|
||||
setPinAction(action, id, t);
|
||||
setPinAction(action, id, t).then(() => {
|
||||
this.setState({ disableUnpinClick: false });
|
||||
});
|
||||
};
|
||||
|
||||
setConvertDialogVisible = () => {
|
||||
|
@ -49,6 +49,8 @@ const ArticleBodyContent = (props) => {
|
||||
archiveFolderId,
|
||||
} = props;
|
||||
|
||||
const [disableBadgeClick, setDisableBadgeClick] = React.useState(false);
|
||||
|
||||
const campaigns = (localStorage.getItem("campaigns") || "")
|
||||
.split(",")
|
||||
.filter((campaign) => campaign.length > 0);
|
||||
@ -148,9 +150,18 @@ const ArticleBodyContent = (props) => {
|
||||
[categoryType, roomsFolderId, archiveFolderId]
|
||||
);
|
||||
|
||||
const onShowNewFilesPanel = React.useCallback((folderId) => {
|
||||
props.setNewFilesPanelVisible(true, [`${folderId}`]);
|
||||
}, []);
|
||||
const onShowNewFilesPanel = React.useCallback(
|
||||
async (folderId) => {
|
||||
if (disableBadgeClick) return;
|
||||
|
||||
setDisableBadgeClick(true);
|
||||
|
||||
await props.setNewFilesPanelVisible(true, [`${folderId}`]);
|
||||
|
||||
setDisableBadgeClick(false);
|
||||
},
|
||||
[disableBadgeClick]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -33,6 +33,7 @@ class NewFilesPanel extends React.Component {
|
||||
state = { readingFiles: [], inProgress: false };
|
||||
|
||||
onClose = () => {
|
||||
if (this.state.inProgress) return;
|
||||
this.props.setNewFilesPanelVisible(false);
|
||||
};
|
||||
|
||||
@ -52,16 +53,27 @@ class NewFilesPanel extends React.Component {
|
||||
};
|
||||
|
||||
onMarkAsRead = () => {
|
||||
const fileIds = [];
|
||||
const folderIds = [];
|
||||
|
||||
for (let item of this.props.newFiles) {
|
||||
if (item.fileExst) fileIds.push(item.id);
|
||||
else folderIds.push(item.id);
|
||||
}
|
||||
const { inProgress, readingFiles } = this.state;
|
||||
if (inProgress) return;
|
||||
|
||||
this.setState({ inProgress: true });
|
||||
|
||||
const files = [];
|
||||
const folders = [];
|
||||
|
||||
for (let item of this.props.newFiles) {
|
||||
if (item.fileExst) files.push(item);
|
||||
else folders.push(item);
|
||||
}
|
||||
|
||||
const fileIds = files
|
||||
.filter((f) => !readingFiles.includes(f.id.toString()))
|
||||
.map((f) => f.id);
|
||||
|
||||
const folderIds = folders
|
||||
.filter((f) => !readingFiles.includes(f.id.toString()))
|
||||
.map((f) => f.id);
|
||||
|
||||
this.props
|
||||
.markAsRead(folderIds, fileIds)
|
||||
.then(() => this.setNewBadgeCount())
|
||||
@ -78,6 +90,10 @@ class NewFilesPanel extends React.Component {
|
||||
};
|
||||
|
||||
onNewFileClick = (e) => {
|
||||
if (this.state.inProgress) return;
|
||||
|
||||
this.setState({ inProgress: true });
|
||||
|
||||
const { id, extension: fileExst } = e.target.dataset;
|
||||
|
||||
const {
|
||||
@ -92,16 +108,23 @@ class NewFilesPanel extends React.Component {
|
||||
|
||||
const item = newFiles.find((file) => file.id.toString() === id);
|
||||
|
||||
if (readingFiles.includes(id)) return this.onFileClick(item);
|
||||
if (readingFiles.includes(id)) {
|
||||
this.setState({ inProgress: false });
|
||||
return this.onFileClick(item);
|
||||
}
|
||||
|
||||
markAsRead(folderIds, fileIds, item)
|
||||
.then(() => {
|
||||
//updateFolderBadge(folderId, 1);
|
||||
|
||||
readingFiles.push(id);
|
||||
this.setState({ readingFiles });
|
||||
this.setState({ readingFiles, inProgress: false });
|
||||
|
||||
this.onFileClick(item);
|
||||
})
|
||||
.then(() => refreshFiles())
|
||||
.then(() => {
|
||||
refreshFiles();
|
||||
})
|
||||
.catch((err) => toastr.error(err));
|
||||
};
|
||||
|
||||
@ -159,7 +182,11 @@ class NewFilesPanel extends React.Component {
|
||||
newFiles,
|
||||
} = this.props;
|
||||
|
||||
const filesCount = newFiles.length;
|
||||
const { readingFiles } = this.state;
|
||||
|
||||
const filesCount = newFiles.filter(
|
||||
(f) => !readingFiles.includes(f.id.toString())
|
||||
).length;
|
||||
updateRootBadge(+newFilesIds[0], filesCount);
|
||||
|
||||
if (newFilesIds.length <= 1) {
|
||||
@ -175,6 +202,7 @@ class NewFilesPanel extends React.Component {
|
||||
render() {
|
||||
//console.log("NewFiles panel render");
|
||||
const { t, visible, isLoading, newFiles, theme } = this.props;
|
||||
const { inProgress } = this.state;
|
||||
const zIndex = 310;
|
||||
|
||||
return (
|
||||
@ -244,12 +272,13 @@ class NewFilesPanel extends React.Component {
|
||||
size="normal"
|
||||
primary
|
||||
onClick={this.onMarkAsRead}
|
||||
isLoading={this.state.inProgress}
|
||||
isLoading={inProgress}
|
||||
/>
|
||||
<Button
|
||||
className="new_files_panel-button"
|
||||
label={t("Common:CloseButton")}
|
||||
size="normal"
|
||||
isDisabled={inProgress}
|
||||
onClick={this.onClose}
|
||||
/>
|
||||
</StyledFooter>
|
||||
|
@ -13,7 +13,11 @@ const DialogAsideLoader = ({
|
||||
|
||||
const renderClearDialogAsideLoader = () => {
|
||||
return (
|
||||
<StyledDialogAsideLoader withFooterBorder={withFooterBorder} visible>
|
||||
<StyledDialogAsideLoader
|
||||
withFooterBorder={withFooterBorder}
|
||||
isPanel={isPanel}
|
||||
visible
|
||||
>
|
||||
<div className="dialog-loader-header">
|
||||
<Loaders.Rectangle height="29px" />
|
||||
</div>
|
||||
@ -23,6 +27,7 @@ const DialogAsideLoader = ({
|
||||
|
||||
<div className="dialog-loader-footer">
|
||||
<Loaders.Rectangle height="40px" />
|
||||
<Loaders.Rectangle height="40px" />
|
||||
</div>
|
||||
</StyledDialogAsideLoader>
|
||||
);
|
||||
@ -32,7 +37,7 @@ const DialogAsideLoader = ({
|
||||
renderClearDialogAsideLoader()
|
||||
) : (
|
||||
<>
|
||||
<Backdrop visible isAside />
|
||||
<Backdrop visible isAside zIndex={zIndex} />
|
||||
<StyledDialogAsideLoader visible isPanel={isPanel}>
|
||||
<Aside className="dialog-aside-loader" visible zIndex={zIndex}>
|
||||
{renderClearDialogAsideLoader()}
|
||||
|
@ -1,41 +1,43 @@
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
const StyledDialogAsideLoader = styled.div`
|
||||
${(props) =>
|
||||
props.isPanel &&
|
||||
css`
|
||||
.dialog-aside-loader {
|
||||
padding: 0;
|
||||
transform: translateX(${(props) => (props.visible ? "0" : "500px")});
|
||||
width: 500px;
|
||||
|
||||
@media (max-width: 550px) {
|
||||
width: 320px;
|
||||
transform: translateX(${(props) => (props.visible ? "0" : "320px")});
|
||||
}
|
||||
}
|
||||
`}
|
||||
|
||||
${(props) =>
|
||||
props.isPanel
|
||||
? css`
|
||||
.dialog-loader-header {
|
||||
padding: 12px 16px;
|
||||
|
||||
height: 53px;
|
||||
|
||||
border-bottom: ${(props) =>
|
||||
`1px solid ${props.theme.modalDialog.headerBorderColor}`};
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
margin-right: -16px;
|
||||
}
|
||||
|
||||
.dialog-loader-body {
|
||||
padding: 16px;
|
||||
margin-right: -16px;
|
||||
}
|
||||
|
||||
.dialog-loader-footer {
|
||||
padding: 12px 16px;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 468px;
|
||||
|
||||
@media (max-width: 550px) {
|
||||
width: 288px;
|
||||
}
|
||||
height: 71px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
border-top: ${(props) =>
|
||||
`1px solid ${props.theme.modalDialog.headerBorderColor}`};
|
||||
}
|
||||
`
|
||||
: css`
|
||||
|
@ -73,6 +73,8 @@ internal class FileMoveCopyOperationData<T> : FileOperationData<T>
|
||||
|
||||
class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
|
||||
{
|
||||
private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
|
||||
|
||||
private readonly int _daoFolderId;
|
||||
private readonly string _thirdpartyFolderId;
|
||||
private readonly bool _copy;
|
||||
@ -382,10 +384,15 @@ class FileMoveCopyOperation<T> : FileOperation<FileMoveCopyOperationData<T>, T>
|
||||
{
|
||||
if (isRoom && toFolder.FolderType == FolderType.VirtualRooms)
|
||||
{
|
||||
await _semaphore.WaitAsync();
|
||||
await countRoomChecker.CheckAppend();
|
||||
newFolderId = await FolderDao.MoveFolderAsync(folder.Id, toFolderId, CancellationToken);
|
||||
_semaphore.Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
newFolderId = await FolderDao.MoveFolderAsync(folder.Id, toFolderId, CancellationToken);
|
||||
}
|
||||
|
||||
newFolderId = await FolderDao.MoveFolderAsync(folder.Id, toFolderId, CancellationToken);
|
||||
}
|
||||
|
||||
newFolder = await folderDao.GetFolderAsync(newFolderId);
|
||||
|
@ -50,13 +50,12 @@ public abstract class FileOperation : DistributedTaskProgress
|
||||
_culture = Thread.CurrentThread.CurrentCulture.Name;
|
||||
|
||||
this[Owner] = ((IAccount)(_principal ?? Thread.CurrentPrincipal).Identity).ID.ToString();
|
||||
this[Src] = "";
|
||||
this[Src] = _props.ContainsValue(Src) ? this[Src] : "";
|
||||
this[Progress] = 0;
|
||||
this[Res] = "";
|
||||
this[Err] = "";
|
||||
this[Process] = 0;
|
||||
this[Finish] = false;
|
||||
this[Hold] = false;
|
||||
}
|
||||
|
||||
protected void IncrementProgress()
|
||||
@ -84,6 +83,7 @@ internal class ComposeFileOperation<T1, T2> : FileOperation
|
||||
{
|
||||
ThirdPartyOperation = thirdPartyOperation;
|
||||
DaoOperation = daoOperation;
|
||||
this[Hold] = ThirdPartyOperation[Hold] || DaoOperation[Hold];
|
||||
}
|
||||
|
||||
public override async Task RunJob(DistributedTask _, CancellationToken cancellationToken)
|
||||
|
Loading…
Reference in New Issue
Block a user