Merge branch 'release/rc-v1.2.0' of github.com:ONLYOFFICE/DocSpace into release/rc-v1.2.0
# Conflicts: # packages/client/src/store/FilesStore.js
This commit is contained in:
commit
3f19ea513a
2587
migrations/mysql/FilesDbContext/20221215125741_FilesDbContext_Upgrade1.Designer.cs
generated
Normal file
2587
migrations/mysql/FilesDbContext/20221215125741_FilesDbContext_Upgrade1.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,37 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Migrations.MySql.Migrations.FilesDb
|
||||
{
|
||||
public partial class FilesDbContext_Upgrade1 : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "has_logo",
|
||||
table: "files_thirdparty_account",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "has_logo",
|
||||
table: "files_folder",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "has_logo",
|
||||
table: "files_thirdparty_account");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "has_logo",
|
||||
table: "files_folder");
|
||||
}
|
||||
}
|
||||
}
|
@ -2329,6 +2329,10 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
.HasColumnName("folder_type")
|
||||
.HasDefaultValueSql("'0'");
|
||||
|
||||
b.Property<bool>("HasLogo")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("has_logo");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(512)")
|
||||
@ -2502,6 +2506,10 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
.HasColumnName("foldersCount")
|
||||
.HasDefaultValueSql("'0'");
|
||||
|
||||
b.Property<bool>("HasLogo")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("has_logo");
|
||||
|
||||
b.Property<string>("ModifiedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
|
2507
migrations/postgre/FilesDbContext/20221215125741_FilesDbContext_Upgrade1.Designer.cs
generated
Normal file
2507
migrations/postgre/FilesDbContext/20221215125741_FilesDbContext_Upgrade1.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Migrations.PostgreSql.Migrations.FilesDb
|
||||
{
|
||||
public partial class FilesDbContext_Upgrade1 : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "has_logo",
|
||||
schema: "onlyoffice",
|
||||
table: "files_thirdparty_account",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "has_logo",
|
||||
schema: "onlyoffice",
|
||||
table: "files_folder",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "has_logo",
|
||||
schema: "onlyoffice",
|
||||
table: "files_thirdparty_account");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "has_logo",
|
||||
schema: "onlyoffice",
|
||||
table: "files_folder");
|
||||
}
|
||||
}
|
||||
}
|
@ -2283,6 +2283,10 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("folder_type");
|
||||
|
||||
b.Property<bool>("HasLogo")
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("has_logo");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
@ -2430,6 +2434,10 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("foldersCount");
|
||||
|
||||
b.Property<bool>("HasLogo")
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("has_logo");
|
||||
|
||||
b.Property<Guid>("ModifiedBy")
|
||||
.HasMaxLength(38)
|
||||
.HasColumnType("uuid")
|
||||
|
@ -19,7 +19,6 @@ const PureSettingsItem = ({
|
||||
setExpandSettingsTree,
|
||||
setSelectedFolder,
|
||||
history,
|
||||
setIsLoading,
|
||||
t,
|
||||
showText,
|
||||
toggleArticleOpen,
|
||||
@ -27,10 +26,8 @@ const PureSettingsItem = ({
|
||||
const { setting } = match.params;
|
||||
|
||||
React.useEffect(() => {
|
||||
setIsLoading(true);
|
||||
setSelectedNode([setting]);
|
||||
setIsLoading(false);
|
||||
}, [setting, setIsLoading, setSelectedNode]);
|
||||
}, [setting, setSelectedNode]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (setting && !expandedSetting) setExpandSettingsTree(["settings"]);
|
||||
@ -73,20 +70,13 @@ const SettingsItem = withTranslation(["FilesSettings", "Common"])(
|
||||
);
|
||||
|
||||
export default inject(
|
||||
({
|
||||
auth,
|
||||
filesStore,
|
||||
settingsStore,
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
}) => {
|
||||
const { setIsLoading } = filesStore;
|
||||
({ auth, settingsStore, treeFoldersStore, selectedFolderStore }) => {
|
||||
const { setSelectedFolder } = selectedFolderStore;
|
||||
const { setSelectedNode } = treeFoldersStore;
|
||||
const { expandedSetting, setExpandSettingsTree } = settingsStore;
|
||||
return {
|
||||
expandedSetting,
|
||||
setIsLoading,
|
||||
|
||||
setSelectedFolder,
|
||||
setSelectedNode,
|
||||
setExpandSettingsTree,
|
||||
|
@ -101,13 +101,13 @@ const CreateEvent = ({
|
||||
setStartValue(newValue);
|
||||
}
|
||||
|
||||
// let tab =
|
||||
// !isDesktop && extension && open
|
||||
// ? window.open(
|
||||
// combineUrl(AppServerConfig.proxyURL, config.homepage, `/doceditor`),
|
||||
// "_blank"
|
||||
// )
|
||||
// : null;
|
||||
let tab =
|
||||
!isDesktop && extension && open
|
||||
? window.open(
|
||||
combineUrl(AppServerConfig.proxyURL, config.homepage, `/doceditor`),
|
||||
"_blank"
|
||||
)
|
||||
: null;
|
||||
|
||||
if (!extension) {
|
||||
createFolder(parentId, newValue)
|
||||
@ -135,7 +135,7 @@ const CreateEvent = ({
|
||||
createdFileId = file.id;
|
||||
addActiveItems([file.id]);
|
||||
|
||||
open && openDocEditor(file.id, file.providerKey, null);
|
||||
open && openDocEditor(file.id, file.providerKey, tab);
|
||||
})
|
||||
.then(() => editCompleteAction(item, type))
|
||||
.catch((err) => {
|
||||
@ -196,7 +196,7 @@ const CreateEvent = ({
|
||||
setCreatedItem({ id: createdFileId, type: "file" });
|
||||
addActiveItems([file.id]);
|
||||
|
||||
return open && openDocEditor(file.id, file.providerKey, null);
|
||||
return open && openDocEditor(file.id, file.providerKey, tab);
|
||||
})
|
||||
.then(() => editCompleteAction(item, type))
|
||||
.catch((e) => toastr.error(e))
|
||||
@ -227,12 +227,12 @@ const CreateEvent = ({
|
||||
true,
|
||||
false
|
||||
).then(
|
||||
() => open && openDocEditor(file.id, file.providerKey, null)
|
||||
() => open && openDocEditor(file.id, file.providerKey, tab)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return open && openDocEditor(file.id, file.providerKey, null);
|
||||
return open && openDocEditor(file.id, file.providerKey, tab);
|
||||
})
|
||||
.then(() => editCompleteAction(item, type))
|
||||
.catch((e) => toastr.error(e))
|
||||
|
@ -32,7 +32,6 @@ const EditRoomEvent = ({
|
||||
withPaging,
|
||||
|
||||
reloadSelection,
|
||||
getRoomLogo,
|
||||
}) => {
|
||||
const { t } = useTranslation(["CreateEditRoomDialog", "Common", "Files"]);
|
||||
|
||||
@ -107,12 +106,6 @@ const EditRoomEvent = ({
|
||||
});
|
||||
|
||||
if (!withPaging) {
|
||||
const newLogo = await getRoomLogo(room.logo);
|
||||
|
||||
room.logoHandlers = room.logo;
|
||||
room.logo = newLogo;
|
||||
room.isLogoLoading = false;
|
||||
|
||||
setFolder(room);
|
||||
}
|
||||
|
||||
@ -125,12 +118,6 @@ const EditRoomEvent = ({
|
||||
});
|
||||
} else {
|
||||
if (!withPaging) {
|
||||
const newLogo = await getRoomLogo(room.logo);
|
||||
|
||||
room.logoHandlers = room.logo;
|
||||
room.logo = newLogo;
|
||||
room.isLogoLoading = false;
|
||||
|
||||
setFolder(room);
|
||||
}
|
||||
// to update state info panel
|
||||
@ -149,9 +136,7 @@ const EditRoomEvent = ({
|
||||
};
|
||||
|
||||
useEffect(async () => {
|
||||
const logo = item?.logo?.original
|
||||
? item.logo.original
|
||||
: await api.rooms.getLogoIcon(item?.logoHandlers?.original);
|
||||
const logo = item?.logo?.original ? item.logo.original : "";
|
||||
|
||||
if (logo) {
|
||||
const imgExst = logo.slice(".")[1];
|
||||
@ -212,7 +197,6 @@ export default inject(
|
||||
setFolder,
|
||||
addLogoToRoom,
|
||||
removeLogoFromRoom,
|
||||
getRoomLogo,
|
||||
} = filesStore;
|
||||
|
||||
const { createTag, fetchTags } = tagsStore;
|
||||
@ -226,7 +210,6 @@ export default inject(
|
||||
editRoom,
|
||||
addTagsToRoom,
|
||||
removeTagsFromRoom,
|
||||
getRoomLogo,
|
||||
|
||||
createTag,
|
||||
fetchTags,
|
||||
|
@ -37,7 +37,10 @@ const InvitePanel = ({
|
||||
adminLink,
|
||||
defaultAccess,
|
||||
inviteUsers,
|
||||
setInfoPanelIsMobileHidden,
|
||||
reloadSelectionParentRoom,
|
||||
setUpdateRoomMembers,
|
||||
roomsView,
|
||||
}) => {
|
||||
const [selectedRoom, setSelectedRoom] = useState(null);
|
||||
const [hasErrors, setHasErrors] = useState(false);
|
||||
@ -118,6 +121,7 @@ const InvitePanel = ({
|
||||
}, [inviteItems]);
|
||||
|
||||
const onClose = () => {
|
||||
setInfoPanelIsMobileHidden(false);
|
||||
setInvitePanelOptions({
|
||||
visible: false,
|
||||
hideSelector: false,
|
||||
@ -160,6 +164,8 @@ const InvitePanel = ({
|
||||
roomId === -1
|
||||
? await inviteUsers(data)
|
||||
: await setRoomSecurity(roomId, data);
|
||||
|
||||
if (roomsView === "info_members") setUpdateRoomMembers(true);
|
||||
onClose();
|
||||
toastr.success(t("Common:UsersInvited"));
|
||||
reloadSelectionParentRoom();
|
||||
@ -244,7 +250,13 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
||||
const { theme } = auth.settingsStore;
|
||||
|
||||
const { getUsersByQuery, inviteUsers } = peopleStore.usersStore;
|
||||
const { reloadSelectionParentRoom } = auth.infoPanelStore;
|
||||
const {
|
||||
setIsMobileHidden: setInfoPanelIsMobileHidden,
|
||||
reloadSelectionParentRoom,
|
||||
setUpdateRoomMembers,
|
||||
roomsView,
|
||||
filesView,
|
||||
} = auth.infoPanelStore;
|
||||
|
||||
const {
|
||||
getPortalInviteLinks,
|
||||
@ -285,7 +297,10 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
||||
guestLink,
|
||||
adminLink,
|
||||
inviteUsers,
|
||||
setInfoPanelIsMobileHidden,
|
||||
reloadSelectionParentRoom,
|
||||
setUpdateRoomMembers,
|
||||
roomsView,
|
||||
};
|
||||
})(
|
||||
withTranslation([
|
||||
|
@ -30,10 +30,7 @@ const FilesItemTitle = ({
|
||||
</StyledTitle>
|
||||
);
|
||||
|
||||
const icon =
|
||||
selection?.isRoom && selection?.logo?.medium
|
||||
? selection.logo.medium
|
||||
: selection.icon;
|
||||
const icon = selection.icon;
|
||||
|
||||
return (
|
||||
<StyledTitle ref={itemTitleRef}>
|
||||
|
@ -22,7 +22,6 @@ const Details = ({
|
||||
isVisitor,
|
||||
}) => {
|
||||
const [itemProperties, setItemProperties] = useState([]);
|
||||
const [largeLogoIcon, setLargeLogoIcon] = useState("");
|
||||
|
||||
const [isThumbnailError, setIsThumbmailError] = useState(false);
|
||||
const onThumbnailError = () => setIsThumbmailError(true);
|
||||
@ -39,24 +38,9 @@ const Details = ({
|
||||
culture,
|
||||
});
|
||||
|
||||
const getLargeRoomLogo = React.useCallback(
|
||||
async (url) => {
|
||||
if (selection?.logo?.large) return setLargeLogoIcon(selection.logo.large);
|
||||
|
||||
const icon = await api.rooms.getLogoIcon(url);
|
||||
|
||||
setLargeLogoIcon(icon);
|
||||
},
|
||||
[selection?.logo?.large]
|
||||
);
|
||||
|
||||
useEffect(async () => {
|
||||
setItemProperties(detailsHelper.getPropertyList());
|
||||
|
||||
if ((selection?.isRoom || selection?.roomType) && !selection.isArchive) {
|
||||
getLargeRoomLogo(selection?.logoHandlers?.large);
|
||||
}
|
||||
|
||||
if (
|
||||
!selection.isFolder &&
|
||||
selection.thumbnailStatus === 0 &&
|
||||
@ -67,10 +51,11 @@ const Details = ({
|
||||
) {
|
||||
await createThumbnail(selection.id);
|
||||
}
|
||||
}, [selection, getLargeRoomLogo]);
|
||||
}, [selection]);
|
||||
|
||||
const currentIcon = largeLogoIcon
|
||||
? largeLogoIcon
|
||||
const currentIcon =
|
||||
!selection.isArchive && selection?.logo?.large
|
||||
? selection?.logo?.large
|
||||
: getInfoPanelItemIcon(selection, 96);
|
||||
|
||||
return (
|
||||
@ -89,7 +74,10 @@ const Details = ({
|
||||
<StyledNoThumbnail>
|
||||
<img
|
||||
className={`no-thumbnail-img ${selection.isRoom && "is-room"} ${
|
||||
selection.isRoom && selection.logo?.large && "custom-logo"
|
||||
selection.isRoom &&
|
||||
!selection.isArchive &&
|
||||
selection.logo?.large &&
|
||||
"custom-logo"
|
||||
}`}
|
||||
src={currentIcon}
|
||||
alt="thumbnail-icon-big"
|
||||
|
@ -21,6 +21,10 @@ const Members = ({
|
||||
isAdmin,
|
||||
selection,
|
||||
|
||||
setIsMobileHidden,
|
||||
updateRoomMembers,
|
||||
setUpdateRoomMembers,
|
||||
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
|
||||
@ -64,6 +68,7 @@ const Members = ({
|
||||
});
|
||||
|
||||
setShowLoader(false);
|
||||
setUpdateRoomMembers(false);
|
||||
return {
|
||||
inRoom: inRoomMembers,
|
||||
expected: expectedMembers,
|
||||
@ -95,7 +100,20 @@ const Members = ({
|
||||
});
|
||||
}, [selection]);
|
||||
|
||||
useEffect(async () => {
|
||||
if (!updateRoomMembers) return;
|
||||
|
||||
const fetchedMembers = await fetchMembers(selection.id);
|
||||
|
||||
setSelectionParentRoom({
|
||||
...selectionParentRoom,
|
||||
members: fetchedMembers,
|
||||
});
|
||||
setMembers(fetchedMembers);
|
||||
}, [selectionParentRoom, selection?.id, updateRoomMembers]);
|
||||
|
||||
const onClickInviteUsers = () => {
|
||||
setIsMobileHidden(true);
|
||||
const parentRoomId = selectionParentRoom.id;
|
||||
|
||||
setInvitePanelOptions({
|
||||
@ -205,7 +223,15 @@ const Members = ({
|
||||
|
||||
export default inject(
|
||||
({ auth, filesStore, peopleStore, dialogsStore, accessRightsStore }) => {
|
||||
const { selectionParentRoom, setSelectionParentRoom } = auth.infoPanelStore;
|
||||
const {
|
||||
setIsMobileHidden,
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
roomsView,
|
||||
|
||||
updateRoomMembers,
|
||||
setUpdateRoomMembers,
|
||||
} = auth.infoPanelStore;
|
||||
const {
|
||||
getRoomMembers,
|
||||
updateRoomMemberRole,
|
||||
@ -221,12 +247,16 @@ export default inject(
|
||||
} = accessRightsStore;
|
||||
|
||||
return {
|
||||
setIsMobileHidden,
|
||||
selectionParentRoom,
|
||||
setSelectionParentRoom,
|
||||
|
||||
getRoomMembers,
|
||||
updateRoomMemberRole,
|
||||
|
||||
updateRoomMembers,
|
||||
setUpdateRoomMembers,
|
||||
|
||||
isOwner,
|
||||
isAdmin,
|
||||
selfId,
|
||||
|
@ -231,7 +231,7 @@ const SimpleFilesRow = (props) => {
|
||||
const element = (
|
||||
<ItemIcon
|
||||
id={item.id}
|
||||
icon={item.isRoom && item.logo.medium ? item.logo.medium : item.icon}
|
||||
icon={item.icon}
|
||||
fileExst={item.fileExst}
|
||||
isRoom={item.isRoom}
|
||||
/>
|
||||
|
@ -324,7 +324,7 @@ const FilesTableRow = (props) => {
|
||||
const element = (
|
||||
<ItemIcon
|
||||
id={item.id}
|
||||
icon={item.isRoom && item.logo.medium ? item.logo.medium : item.icon}
|
||||
icon={item.icon}
|
||||
fileExst={item.fileExst}
|
||||
isRoom={item.isRoom}
|
||||
/>
|
||||
|
@ -68,7 +68,7 @@ const FileTile = (props) => {
|
||||
const element = (
|
||||
<ItemIcon
|
||||
id={item.id}
|
||||
icon={item.isRoom && item.logo.medium ? item.logo.medium : item.icon}
|
||||
icon={item.icon}
|
||||
fileExst={item.fileExst}
|
||||
isRoom={item.isRoom}
|
||||
/>
|
||||
|
@ -263,6 +263,8 @@ class ContextOptionsStore {
|
||||
};
|
||||
|
||||
gotoDocEditor = (preview = false, item) => {
|
||||
const { isDesktopClient } = this.authStore.settingsStore;
|
||||
|
||||
const { id, providerKey, fileExst } = item;
|
||||
|
||||
const urlFormation = preview
|
||||
@ -274,13 +276,9 @@ class ContextOptionsStore {
|
||||
: null;
|
||||
|
||||
let tab =
|
||||
!this.authStore.isDesktopClient && fileExst
|
||||
!isDesktopClient && fileExst
|
||||
? window.open(
|
||||
combineUrl(
|
||||
AppServerConfig.proxyURL,
|
||||
config.homepage,
|
||||
`/doceditor?fileId=${id}`
|
||||
),
|
||||
combineUrl(AppServerConfig.proxyURL, config.homepage, `/doceditor`),
|
||||
"_blank"
|
||||
)
|
||||
: null;
|
||||
|
@ -277,6 +277,7 @@ class FilesActionStore {
|
||||
this.isMediaOpen();
|
||||
|
||||
try {
|
||||
this.filesStore.setOperationAction(true);
|
||||
await removeFiles(folderIds, fileIds, deleteAfter, immediately)
|
||||
.then(async (res) => {
|
||||
if (res[0]?.error) return Promise.reject(res[0].error);
|
||||
@ -330,6 +331,8 @@ class FilesActionStore {
|
||||
});
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
return toastr.error(err.message ? err.message : err);
|
||||
} finally {
|
||||
this.filesStore.setOperationAction(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -675,10 +678,13 @@ class FilesActionStore {
|
||||
label: translations?.deleteOperation,
|
||||
};
|
||||
|
||||
this.filesStore.setOperationAction(true);
|
||||
|
||||
if (isFile) {
|
||||
addActiveItems([itemId]);
|
||||
this.isMediaOpen();
|
||||
return deleteFile(itemId).then(async (res) => {
|
||||
return deleteFile(itemId)
|
||||
.then(async (res) => {
|
||||
if (res[0]?.error) return Promise.reject(res[0].error);
|
||||
const data = res[0] ? res[0] : null;
|
||||
await this.uploadDataStore.loopFilesOperations(data, pbData);
|
||||
@ -692,7 +698,8 @@ class FilesActionStore {
|
||||
toastr.success(translations.successRemoveFile)
|
||||
);
|
||||
}
|
||||
});
|
||||
})
|
||||
.finally(() => this.filesStore.setOperationAction(false));
|
||||
} else if (isRoom) {
|
||||
const items = Array.isArray(itemId) ? itemId : [itemId];
|
||||
addActiveItems(null, items);
|
||||
@ -715,7 +722,8 @@ class FilesActionStore {
|
||||
);
|
||||
} else {
|
||||
addActiveItems(null, [itemId]);
|
||||
return deleteFolder(itemId).then(async (res) => {
|
||||
return deleteFolder(itemId)
|
||||
.then(async (res) => {
|
||||
if (res[0]?.error) return Promise.reject(res[0].error);
|
||||
const data = res[0] ? res[0] : null;
|
||||
await this.uploadDataStore.loopFilesOperations(data, pbData);
|
||||
@ -731,7 +739,8 @@ class FilesActionStore {
|
||||
}
|
||||
|
||||
getIsEmptyTrash();
|
||||
});
|
||||
})
|
||||
.finally(() => this.filesStore.setOperationAction(false));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -27,6 +27,7 @@ import { isDesktop } from "@docspace/components/utils/device";
|
||||
import { getContextMenuKeysByType } from "SRC_DIR/helpers/plugins";
|
||||
import { PluginContextMenuItemType } from "SRC_DIR/helpers/plugins/constants";
|
||||
import { getArchiveRoomRoleActions } from "@docspace/common/utils/actions";
|
||||
import debounce from "lodash.debounce";
|
||||
|
||||
const { FilesFilter, RoomsFilter } = api;
|
||||
const storageViewAs = localStorage.getItem("viewAs");
|
||||
@ -102,7 +103,12 @@ class FilesStore {
|
||||
|
||||
isEmptyPage = false;
|
||||
isLoadedFetchFiles = false;
|
||||
|
||||
tempActionFilesIds = [];
|
||||
operationAction = false;
|
||||
|
||||
isErrorRoomNotAvailable = false;
|
||||
|
||||
constructor(
|
||||
authStore,
|
||||
selectedFolderStore,
|
||||
@ -128,7 +134,7 @@ class FilesStore {
|
||||
socketHelper.on("s:modify-folder", async (opt) => {
|
||||
console.log("[WS] s:modify-folder", opt);
|
||||
|
||||
if (this.isLoading) return;
|
||||
if (this.isLoading || this.operationAction) return;
|
||||
|
||||
switch (opt?.cmd) {
|
||||
case "create":
|
||||
@ -203,15 +209,23 @@ class FilesStore {
|
||||
this.files[foundIndex].title
|
||||
);
|
||||
|
||||
this.setFiles(
|
||||
this.files.filter((_, index) => {
|
||||
return index !== foundIndex;
|
||||
})
|
||||
);
|
||||
// this.setFiles(
|
||||
// this.files.filter((_, index) => {
|
||||
// return index !== foundIndex;
|
||||
// })
|
||||
// );
|
||||
|
||||
const newFilter = this.filter.clone();
|
||||
newFilter.total -= 1;
|
||||
this.setFilter(newFilter);
|
||||
// const newFilter = this.filter.clone();
|
||||
// newFilter.total -= 1;
|
||||
// this.setFilter(newFilter);
|
||||
|
||||
const tempActionFilesIds = JSON.parse(
|
||||
JSON.stringify(this.tempActionFilesIds)
|
||||
);
|
||||
tempActionFilesIds.push(this.files[foundIndex].id);
|
||||
|
||||
this.setTempActionFilesIds(tempActionFilesIds);
|
||||
this.debounceRemoveFiles();
|
||||
|
||||
// Hide pagination when deleting files
|
||||
runInAction(() => {
|
||||
@ -239,7 +253,10 @@ class FilesStore {
|
||||
// `selected folder id ${this.selectedFolderStore.id} an changed folder id ${id}`
|
||||
//);
|
||||
|
||||
if (this.selectedFolderStore.id == id) {
|
||||
if (
|
||||
this.selectedFolderStore.id == id &&
|
||||
this.authStore.settingsStore.withPaging //TODO: no longer deletes the folder in other tabs
|
||||
) {
|
||||
console.log("[WS] refresh-folder", id);
|
||||
this.fetchFiles(id, this.filter);
|
||||
}
|
||||
@ -317,6 +334,18 @@ class FilesStore {
|
||||
});
|
||||
}
|
||||
|
||||
debounceRemoveFiles = debounce(() => {
|
||||
this.removeFiles(this.tempActionFilesIds);
|
||||
}, 1000);
|
||||
|
||||
setTempActionFilesIds = (tempActionFilesIds) => {
|
||||
this.tempActionFilesIds = tempActionFilesIds;
|
||||
};
|
||||
|
||||
setOperationAction = (operationAction) => {
|
||||
this.operationAction = operationAction;
|
||||
};
|
||||
|
||||
updateSelectionStatus = (id, status, isEditing) => {
|
||||
const index = this.selection.findIndex((x) => x.id === id);
|
||||
|
||||
@ -1050,8 +1079,6 @@ class FilesStore {
|
||||
|
||||
this.setCreatedItem(null);
|
||||
}
|
||||
|
||||
this.updateRoomLoadingLogo();
|
||||
this.isErrorRoomNotAvailable = false;
|
||||
return Promise.resolve(selectedFolder);
|
||||
})
|
||||
@ -1832,9 +1859,13 @@ class FilesStore {
|
||||
|
||||
showToast && showToast();
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((err) => {
|
||||
toastr.error(err);
|
||||
console.log("Need page reload");
|
||||
})
|
||||
.finally(() => {
|
||||
this.setOperationAction(false);
|
||||
this.setTempActionFilesIds([]);
|
||||
});
|
||||
};
|
||||
|
||||
@ -2027,48 +2058,6 @@ class FilesStore {
|
||||
return folderUrl;
|
||||
};
|
||||
|
||||
getRoomLogo = async (logoHandlers) => {
|
||||
const newLogos = {};
|
||||
|
||||
for (let key in logoHandlers) {
|
||||
let icon = "";
|
||||
|
||||
if (key === "medium") {
|
||||
icon = await api.rooms.getLogoIcon(logoHandlers[key]);
|
||||
|
||||
// check for null
|
||||
icon = icon ? icon : "";
|
||||
}
|
||||
|
||||
newLogos[key] = icon;
|
||||
}
|
||||
|
||||
return newLogos;
|
||||
};
|
||||
|
||||
updateRoomLoadingLogo = async () => {
|
||||
const newRooms = await Promise.all(
|
||||
this.folders.map(async (f) => {
|
||||
const newRoom = JSON.parse(JSON.stringify(f));
|
||||
|
||||
if (!newRoom.isLogoLoading) return newRoom;
|
||||
|
||||
newRoom.isLogoLoading = false;
|
||||
newRoom.logo = await this.getRoomLogo(newRoom.logoHandlers);
|
||||
|
||||
return newRoom;
|
||||
})
|
||||
);
|
||||
|
||||
if (
|
||||
(this.treeFoldersStore.isRoomsFolder ||
|
||||
this.treeFoldersStore.isArchiveFolder) &&
|
||||
this.selectedFolderStore.navigationPath.length === 0
|
||||
) {
|
||||
this.setFolders(newRooms);
|
||||
}
|
||||
};
|
||||
|
||||
get filesList() {
|
||||
const { getIcon } = this.filesSettingsStore;
|
||||
//return [...this.folders, ...this.files];
|
||||
@ -2099,8 +2088,6 @@ class FilesStore {
|
||||
foldersCount,
|
||||
id,
|
||||
logo,
|
||||
logoHandlers,
|
||||
isLogoLoading,
|
||||
locked,
|
||||
parentId,
|
||||
pureContentLength,
|
||||
@ -2150,14 +2137,6 @@ class FilesStore {
|
||||
const isThirdPartyFolder = providerKey && id === rootFolderId;
|
||||
|
||||
const iconSize = this.viewAs === "table" ? 24 : 32;
|
||||
const icon = getIcon(
|
||||
iconSize,
|
||||
fileExst,
|
||||
providerKey,
|
||||
contentLength,
|
||||
roomType,
|
||||
isArchive
|
||||
);
|
||||
|
||||
let isFolder = false;
|
||||
this.folders.map((x) => {
|
||||
@ -2188,6 +2167,18 @@ class FilesStore {
|
||||
|
||||
const isRoom = !!roomType;
|
||||
|
||||
const icon =
|
||||
isRoom && !isArchive && logo?.medium
|
||||
? logo?.medium
|
||||
: getIcon(
|
||||
iconSize,
|
||||
fileExst,
|
||||
providerKey,
|
||||
contentLength,
|
||||
roomType,
|
||||
isArchive
|
||||
);
|
||||
|
||||
return {
|
||||
access,
|
||||
//checked,
|
||||
@ -2206,9 +2197,8 @@ class FilesStore {
|
||||
icon,
|
||||
id,
|
||||
isFolder,
|
||||
isLogoLoading,
|
||||
logo,
|
||||
logoHandlers,
|
||||
|
||||
locked,
|
||||
new: item.new,
|
||||
parentId,
|
||||
@ -2846,8 +2836,6 @@ class FilesStore {
|
||||
this.setFolders([...this.folders, ...newFiles.folders]);
|
||||
this.setFilesIsLoading(false);
|
||||
});
|
||||
|
||||
if (isRooms) this.updateRoomLoadingLogo();
|
||||
};
|
||||
|
||||
//Duplicate of countTilesInRow, used to update the number of tiles in a row after the window is resized.
|
||||
|
@ -24,8 +24,8 @@ class SelectedFolderStore {
|
||||
roomType = null;
|
||||
pinned = null;
|
||||
isRoom = null;
|
||||
isArchive = null;
|
||||
logo = null;
|
||||
logoHandlers = null;
|
||||
tags = null;
|
||||
rootFolderId = null;
|
||||
settingsStore = null;
|
||||
|
@ -431,7 +431,7 @@ class UploadDataStore {
|
||||
}
|
||||
});
|
||||
|
||||
// storeOriginalFiles && this.refreshFiles(file);
|
||||
storeOriginalFiles && this.refreshFiles(file);
|
||||
|
||||
if (fileInfo && fileInfo !== "password") {
|
||||
file.fileInfo = fileInfo;
|
||||
@ -653,6 +653,8 @@ class UploadDataStore {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.filesStore.setOperationAction(false);
|
||||
};
|
||||
|
||||
const isFiltered =
|
||||
@ -694,6 +696,7 @@ class UploadDataStore {
|
||||
file,
|
||||
path
|
||||
) => {
|
||||
this.filesStore.setOperationAction(true);
|
||||
const length = requestsDataArray.length;
|
||||
for (let index = 0; index < length; index++) {
|
||||
if (
|
||||
@ -769,10 +772,8 @@ class UploadDataStore {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
if (currentFile.action === "uploaded") {
|
||||
if (currentFile?.path?.length > 1) {
|
||||
this.refreshFiles(currentFile);
|
||||
}
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ import { FolderType, RoomSearchArea } from "../../constants";
|
||||
import find from "lodash/find";
|
||||
import { getFolderOptions, decodeDisplayName } from "../../utils";
|
||||
import { Encoder } from "../../utils/encoder";
|
||||
import { getLogoIcon, getRooms } from "../rooms";
|
||||
import { getRooms } from "../rooms";
|
||||
import RoomsFilter from "../rooms/filter";
|
||||
|
||||
export function openEdit(fileId, version, doc, view) {
|
||||
@ -39,45 +39,7 @@ export function getFolderInfo(folderId) {
|
||||
url: `/files/folder/${folderId}`,
|
||||
};
|
||||
|
||||
return request(options).then((res) => {
|
||||
if (res.roomType) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (res.rootFolderType === FolderType.Archive) {
|
||||
res.isLogoLoading = false;
|
||||
for (let key in room.logo) {
|
||||
room.logo[key] = "";
|
||||
}
|
||||
|
||||
return resolve(res);
|
||||
}
|
||||
|
||||
res.isLogoLoading = false;
|
||||
res.logoHandlers = res.logo;
|
||||
|
||||
const newLogos = {};
|
||||
|
||||
const actions = [];
|
||||
|
||||
const getLogo = async (key) => {
|
||||
const logo = await getLogoIcon(res.logo[key]);
|
||||
|
||||
newLogos[key] = logo;
|
||||
};
|
||||
|
||||
for (let key in res.logo) {
|
||||
actions.push(getLogo(key));
|
||||
}
|
||||
|
||||
return Promise.all(actions).then(() => {
|
||||
res.logo = newLogos;
|
||||
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return res;
|
||||
});
|
||||
return request(options);
|
||||
}
|
||||
|
||||
export function getFolderPath(folderId) {
|
||||
@ -95,40 +57,9 @@ export function getFolder(folderId, filter) {
|
||||
res.files = decodeDisplayName(res.files);
|
||||
res.folders = decodeDisplayName(res.folders);
|
||||
|
||||
const { current } = res;
|
||||
|
||||
if (current.roomType) {
|
||||
res.current.isLogoLoading = false;
|
||||
res.current.logoHandlers = current.logo;
|
||||
|
||||
if (current.rootFolderType === FolderType.Rooms) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const actions = [];
|
||||
|
||||
const newLogos = {};
|
||||
|
||||
const getLogo = async (key) => {
|
||||
const logo = await getLogoIcon(current.logo[key]);
|
||||
|
||||
newLogos[key] = logo;
|
||||
};
|
||||
|
||||
for (let key in current.logo) {
|
||||
actions.push(getLogo(key));
|
||||
}
|
||||
|
||||
return Promise.all(actions).then(() => {
|
||||
res.current.logo = newLogos;
|
||||
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
for (let key in res.current.logo) {
|
||||
res.current.logo[key] = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
res.current.isArchive =
|
||||
!!res.current.roomType &&
|
||||
res.current.rootFolderType === FolderType.Archive;
|
||||
|
||||
return res;
|
||||
});
|
||||
|
@ -15,23 +15,6 @@ export function getRooms(filter) {
|
||||
if (res.current.rootFolderType === FolderType.Archive) {
|
||||
res.folders.forEach((room) => {
|
||||
room.isArchive = true;
|
||||
room.isLogoLoading = false;
|
||||
for (let key in room.logo) {
|
||||
room.logo[key] = "";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.folders.forEach((f, index) => {
|
||||
res.folders[index].isLogoLoading = true;
|
||||
res.folders[index].logoHandlers = f.logo;
|
||||
|
||||
const newLogos = {};
|
||||
|
||||
for (let key in f.logo) {
|
||||
newLogos[key] = "";
|
||||
}
|
||||
|
||||
res.folders[index].logo = newLogos;
|
||||
});
|
||||
}
|
||||
|
||||
@ -39,60 +22,16 @@ export function getRooms(filter) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getLogoIcon(url) {
|
||||
if (!url) return "";
|
||||
|
||||
const options = {
|
||||
// baseURL: combineUrl(AppServerConfig.proxyURL, config.homepage),
|
||||
method: "get",
|
||||
url: `/products/files/httphandlers${url}`,
|
||||
responseType: "text",
|
||||
};
|
||||
|
||||
return request(options);
|
||||
}
|
||||
|
||||
export function getRoomInfo(id) {
|
||||
const options = {
|
||||
method: "get",
|
||||
url: `/files/rooms/${id}`,
|
||||
};
|
||||
|
||||
return request(options).then(async (res) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (res.rootFolderType === FolderType.Archive) {
|
||||
res.isLogoLoading = false;
|
||||
res.isArchive = true;
|
||||
for (let key in res.logo) {
|
||||
res.logo[key] = "";
|
||||
}
|
||||
return request(options).then((res) => {
|
||||
if (res.rootFolderType === FolderType.Archive) res.isArchive = true;
|
||||
|
||||
return resolve(res);
|
||||
}
|
||||
|
||||
res.isLogoLoading = false;
|
||||
res.logoHandlers = res.logo;
|
||||
|
||||
const newLogos = {};
|
||||
|
||||
const actions = [];
|
||||
|
||||
const getLogo = async (key) => {
|
||||
const logo = await getLogoIcon(res.logo[key]);
|
||||
|
||||
newLogos[key] = logo;
|
||||
};
|
||||
|
||||
for (let key in res.logo) {
|
||||
actions.push(getLogo(key));
|
||||
}
|
||||
|
||||
return Promise.all(actions).then(() => {
|
||||
res.logo = newLogos;
|
||||
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -77,13 +77,11 @@ const FilterBlockItem = ({
|
||||
return !item.isSelected ||
|
||||
item.selectedKey === "me" ||
|
||||
item.selectedKey === "other" ? (
|
||||
<StyledFilterBlockItemSelector key={item.key}>
|
||||
<SelectorAddButton
|
||||
onClick={(event) =>
|
||||
showSelectorAction(event, isAuthor, item.group, [])
|
||||
}
|
||||
id="filter_add-author"
|
||||
/>
|
||||
<StyledFilterBlockItemSelector
|
||||
key={item.key}
|
||||
onClick={(event) => showSelectorAction(event, isAuthor, item.group, [])}
|
||||
>
|
||||
<SelectorAddButton id="filter_add-author" />
|
||||
<StyledFilterBlockItemSelectorText noSelect={true}>
|
||||
{item.label}
|
||||
</StyledFilterBlockItemSelectorText>
|
||||
|
@ -151,8 +151,8 @@ const StyledFilterBlockItemSelectorText = styled(Text)`
|
||||
font-size: 13px;
|
||||
line-height: 15px;
|
||||
color: ${(props) => props.theme.filterInput.filter.color};
|
||||
|
||||
margin-left: 8px;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
StyledFilterBlockItemSelectorText.defaultProps = { theme: Base };
|
||||
|
@ -83,11 +83,10 @@ const StyledInfoPanel = styled.div`
|
||||
const StyledControlContainer = styled.div`
|
||||
display: none;
|
||||
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
position: absolute;
|
||||
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
|
||||
align-items: center;
|
||||
@ -97,22 +96,22 @@ const StyledControlContainer = styled.div`
|
||||
@media ${tablet} {
|
||||
display: flex;
|
||||
|
||||
top: 16px;
|
||||
left: -34px;
|
||||
top: 18px;
|
||||
left: -27px;
|
||||
}
|
||||
|
||||
${isMobile &&
|
||||
css`
|
||||
display: flex;
|
||||
|
||||
top: 16px;
|
||||
left: -34px;
|
||||
top: 18px;
|
||||
left: -27px;
|
||||
`}
|
||||
|
||||
@media (max-width: 428px) {
|
||||
display: flex;
|
||||
|
||||
top: -34px;
|
||||
top: -27px;
|
||||
right: 10px;
|
||||
left: unset;
|
||||
}
|
||||
@ -134,11 +133,14 @@ StyledCrossIcon.defaultProps = { theme: Base };
|
||||
const InfoPanel = ({
|
||||
children,
|
||||
isVisible,
|
||||
isMobileHidden,
|
||||
setIsVisible,
|
||||
canDisplay,
|
||||
viewAs,
|
||||
}) => {
|
||||
if (!isVisible || !canDisplay) return null;
|
||||
if ((isTablet() || isMobile || isMobileUtils()) && isMobileHidden)
|
||||
return null;
|
||||
|
||||
const closeInfoPanel = () => setIsVisible(false);
|
||||
|
||||
@ -180,13 +182,14 @@ const InfoPanel = ({
|
||||
);
|
||||
|
||||
const renderPortalInfoPanel = () => {
|
||||
console.log(isMobileHidden);
|
||||
const rootElement = document.getElementById("root");
|
||||
|
||||
return (
|
||||
<Portal
|
||||
element={infoPanelComponent}
|
||||
appendTo={rootElement}
|
||||
visible={isVisible}
|
||||
visible={isVisible && !isMobileHidden}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -208,12 +211,18 @@ StyledInfoPanel.defaultProps = { theme: Base };
|
||||
InfoPanel.defaultProps = { theme: Base };
|
||||
|
||||
export default inject(({ auth }) => {
|
||||
const { isVisible, setIsVisible, getCanDisplay } = auth.infoPanelStore;
|
||||
const {
|
||||
isVisible,
|
||||
isMobileHidden,
|
||||
setIsVisible,
|
||||
getCanDisplay,
|
||||
} = auth.infoPanelStore;
|
||||
|
||||
const canDisplay = getCanDisplay();
|
||||
|
||||
return {
|
||||
isVisible,
|
||||
isMobileHidden,
|
||||
setIsVisible,
|
||||
canDisplay,
|
||||
};
|
||||
|
@ -19,6 +19,7 @@ const observedKeys = [
|
||||
|
||||
class InfoPanelStore {
|
||||
isVisible = false;
|
||||
isMobileHidden = false;
|
||||
|
||||
selection = null;
|
||||
selectionParentRoom = null;
|
||||
@ -26,6 +27,8 @@ class InfoPanelStore {
|
||||
roomsView = "info_details";
|
||||
fileView = "info_history";
|
||||
|
||||
updateRoomMembers = null;
|
||||
|
||||
authStore = null;
|
||||
settingsStore = null;
|
||||
peopleStore = null;
|
||||
@ -40,6 +43,7 @@ class InfoPanelStore {
|
||||
// Setters
|
||||
|
||||
setIsVisible = (bool) => (this.isVisible = bool);
|
||||
setIsMobileHidden = (bool) => (this.isMobileHidden = bool);
|
||||
|
||||
setSelection = (selection) => {
|
||||
if (this.getIsAccounts() && (!selection.email || !selection.displayName)) {
|
||||
@ -57,6 +61,10 @@ class InfoPanelStore {
|
||||
this.fileView = view === "info_members" ? "info_history" : view;
|
||||
};
|
||||
|
||||
setUpdateRoomMembers = (updateRoomMembers) => {
|
||||
this.updateRoomMembers = updateRoomMembers;
|
||||
};
|
||||
|
||||
// Selection helpers //
|
||||
|
||||
getSelectedItems = () => {
|
||||
|
@ -78,29 +78,37 @@ const StyledAside = styled(Container)`
|
||||
StyledAside.defaultProps = { theme: Base };
|
||||
|
||||
const StyledControlContainer = styled.div`
|
||||
display: flex;
|
||||
display: none;
|
||||
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
position: absolute;
|
||||
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 450;
|
||||
|
||||
top: 14px;
|
||||
left: -34px;
|
||||
@media ${tablet} {
|
||||
display: flex;
|
||||
|
||||
top: 18px;
|
||||
left: -27px;
|
||||
}
|
||||
|
||||
${isMobile &&
|
||||
css`
|
||||
top: 14px;
|
||||
display: flex;
|
||||
|
||||
top: 18px;
|
||||
left: -27px;
|
||||
`}
|
||||
|
||||
@media (max-width: 428px) {
|
||||
top: -34px;
|
||||
display: flex;
|
||||
|
||||
top: -27px;
|
||||
right: 10px;
|
||||
left: unset;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class FolderDtoHelper : FileEntryDtoHelper
|
||||
result.Tags = folder.Tags.Select(t => t.Name);
|
||||
}
|
||||
|
||||
result.Logo = _roomLogoManager.GetLogo(folder);
|
||||
result.Logo = await _roomLogoManager.GetLogoAsync(folder);
|
||||
result.RoomType = folder.FolderType switch
|
||||
{
|
||||
FolderType.FillingFormsRoom => RoomType.FillingFormsRoom,
|
||||
|
@ -35,6 +35,7 @@ public interface IProviderDao
|
||||
IAsyncEnumerable<IProviderInfo> GetProvidersInfoAsync(Guid userId);
|
||||
Task<int> SaveProviderInfoAsync(string providerKey, string customerTitle, AuthData authData, FolderType folderType);
|
||||
Task<bool> UpdateProviderInfoAsync(int linkId, FolderType rootFolderType);
|
||||
Task<bool> UpdateProviderInfoAsync(int linkId, bool hasLogo);
|
||||
Task<bool> UpdateProviderInfoAsync(int linkId, string folderId, FolderType folderType, bool @private);
|
||||
Task<int> UpdateProviderInfoAsync(int linkId, string customerTitle, AuthData authData, FolderType folderType, Guid? userId = null);
|
||||
Task<int> UpdateBackupProviderInfoAsync(string providerKey, string customerTitle, AuthData authData);
|
||||
|
@ -446,6 +446,7 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
toUpdate.CreateBy = folder.CreateBy;
|
||||
toUpdate.ModifiedOn = _tenantUtil.DateTimeToUtc(folder.ModifiedOn);
|
||||
toUpdate.ModifiedBy = folder.ModifiedBy;
|
||||
toUpdate.HasLogo = folder.HasLogo;
|
||||
|
||||
await filesDbContext.SaveChangesAsync();
|
||||
|
||||
|
@ -42,6 +42,7 @@ public class DbFilesThirdpartyAccount : BaseEntity, IDbFile, IDbSearch
|
||||
public int TenantId { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public bool Private { get; set; }
|
||||
public bool HasLogo { get; set; }
|
||||
|
||||
public override object[] GetKeys()
|
||||
{
|
||||
@ -137,6 +138,8 @@ public static class DbFilesThirdpartyAccountExtension
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Private).HasColumnName("private");
|
||||
|
||||
entity.Property(e => e.HasLogo).HasColumnName("has_logo");
|
||||
});
|
||||
}
|
||||
public static void PgSqlAddDbFilesThirdpartyAccount(this ModelBuilder modelBuilder)
|
||||
@ -189,6 +192,8 @@ public static class DbFilesThirdpartyAccountExtension
|
||||
entity.Property(e => e.FolderId).HasColumnName("folder_id");
|
||||
|
||||
entity.Property(e => e.Private).HasColumnName("private");
|
||||
|
||||
entity.Property(e => e.HasLogo).HasColumnName("has_logo");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ public class DbFolder : IDbFile, IDbSearch, ISearchItem
|
||||
public int FoldersCount { get; set; }
|
||||
public int FilesCount { get; set; }
|
||||
public bool Private { get; set; }
|
||||
public bool HasLogo { get; set; }
|
||||
|
||||
[Ignore]
|
||||
public string IndexName => Tables.Folder;
|
||||
@ -130,6 +131,8 @@ public static class DbFolderExtension
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Private).HasColumnName("private");
|
||||
|
||||
entity.Property(e => e.HasLogo).HasColumnName("has_logo");
|
||||
});
|
||||
}
|
||||
public static void PgSqlAddDbFolder(this ModelBuilder modelBuilder)
|
||||
@ -178,6 +181,8 @@ public static class DbFolderExtension
|
||||
.HasMaxLength(400);
|
||||
|
||||
entity.Property(e => e.Private).HasColumnName("private");
|
||||
|
||||
entity.Property(e => e.HasLogo).HasColumnName("has_logo");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ public class Folder<T> : FileEntry<T>, IFolder
|
||||
public string FolderUrl { get; set; }
|
||||
public bool Pinned { get; set; }
|
||||
public bool Private { get; set; }
|
||||
public bool HasLogo { get; set; }
|
||||
public override bool IsNew
|
||||
{
|
||||
get => Convert.ToBoolean(NewForMe);
|
||||
|
@ -124,6 +124,7 @@ internal abstract class BoxDaoBase : ThirdPartyProviderDao<BoxProviderInfo>
|
||||
folder.FilesCount = boxFolder.ItemCollection != null ? boxFolder.ItemCollection.Entries.Count(item => item is BoxFile) : 0;
|
||||
folder.FoldersCount = boxFolder.ItemCollection != null ? boxFolder.ItemCollection.Entries.Count(item => item is BoxFolder) : 0;
|
||||
folder.Private = ProviderInfo.Private;
|
||||
folder.HasLogo = ProviderInfo.HasLogo;
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)
|
||||
|
@ -57,6 +57,7 @@ internal class BoxProviderInfo : IProviderInfo
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public bool Private { get; set; }
|
||||
public bool HasLogo { get; set; }
|
||||
|
||||
public string BoxRootId
|
||||
{
|
||||
|
@ -128,6 +128,7 @@ internal abstract class DropboxDaoBase : ThirdPartyProviderDao<DropboxProviderIn
|
||||
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : default;
|
||||
folder.Title = MakeFolderTitle(dropboxFolder);
|
||||
folder.Private = ProviderInfo.Private;
|
||||
folder.HasLogo = ProviderInfo.HasLogo;
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)
|
||||
|
@ -56,6 +56,7 @@ internal class DropboxProviderInfo : IProviderInfo
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public bool Private { get; set; }
|
||||
public bool HasLogo { get; set; }
|
||||
|
||||
private readonly DropboxStorageDisposableWrapper _wrapper;
|
||||
private readonly DropboxProviderInfoHelper _dropboxProviderInfoHelper;
|
||||
|
@ -140,6 +140,7 @@ internal abstract class GoogleDriveDaoBase : ThirdPartyProviderDao<GoogleDrivePr
|
||||
folder.CreateOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.CreatedTime ?? default);
|
||||
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.ModifiedTime ?? default);
|
||||
folder.Private = ProviderInfo.Private;
|
||||
folder.HasLogo = ProviderInfo.HasLogo;
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
folder.Title = MakeFolderTitle(driveEntry);
|
||||
|
@ -60,6 +60,7 @@ internal class GoogleDriveProviderInfo : IProviderInfo
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public bool Private { get; set; }
|
||||
public bool HasLogo { get; set; }
|
||||
public string DriveRootId
|
||||
{
|
||||
get
|
||||
|
@ -127,6 +127,7 @@ internal abstract class OneDriveDaoBase : ThirdPartyProviderDao<OneDriveProvider
|
||||
folder.CreateOn = isRoot ? ProviderInfo.CreateOn : (onedriveFolder.CreatedDateTime.HasValue ? _tenantUtil.DateTimeFromUtc(onedriveFolder.CreatedDateTime.Value.DateTime) : default);
|
||||
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : (onedriveFolder.LastModifiedDateTime.HasValue ? _tenantUtil.DateTimeFromUtc(onedriveFolder.LastModifiedDateTime.Value.DateTime) : default);
|
||||
folder.Private = ProviderInfo.Private;
|
||||
folder.HasLogo = ProviderInfo.HasLogo;
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
folder.Title = MakeItemTitle(onedriveFolder);
|
||||
|
@ -57,6 +57,7 @@ internal class OneDriveProviderInfo : IProviderInfo
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public bool Private { get; set; }
|
||||
public bool HasLogo { get; set; }
|
||||
|
||||
private readonly OneDriveStorageDisposableWrapper _wrapper;
|
||||
private readonly OneDriveProviderInfoHelper _oneDriveProviderInfoHelper;
|
||||
|
@ -229,6 +229,26 @@ internal class ProviderAccountDao : IProviderDao
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateProviderInfoAsync(int linkId, bool hasLogo)
|
||||
{
|
||||
using var filesDbContext = _dbContextFactory.CreateDbContext();
|
||||
var forUpdate = await filesDbContext.ThirdpartyAccount
|
||||
.Where(r => r.Id == linkId)
|
||||
.Where(r => r.TenantId == TenantID)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (forUpdate == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
forUpdate.HasLogo = hasLogo;
|
||||
|
||||
await filesDbContext.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateProviderInfoAsync(int linkId, string folderId, FolderType roomType, bool @private)
|
||||
{
|
||||
using var filesDbContext = _dbContextFactory.CreateDbContext();
|
||||
@ -496,6 +516,7 @@ internal class ProviderAccountDao : IProviderDao
|
||||
var folderId = input.FolderId;
|
||||
var createOn = _tenantUtil.DateTimeFromUtc(input.CreateOn);
|
||||
var authData = new AuthData(input.Url, input.UserName, DecryptPassword(input.Password, id), token);
|
||||
var hasLogo = input.HasLogo;
|
||||
|
||||
if (key == ProviderTypes.Box)
|
||||
{
|
||||
@ -515,6 +536,7 @@ internal class ProviderAccountDao : IProviderDao
|
||||
box.FolderType = folderType;
|
||||
box.FolderId = folderId;
|
||||
box.Private = privateRoom;
|
||||
box.HasLogo = hasLogo;
|
||||
|
||||
return box;
|
||||
}
|
||||
@ -537,6 +559,7 @@ internal class ProviderAccountDao : IProviderDao
|
||||
drop.FolderType = folderType;
|
||||
drop.FolderId = folderId;
|
||||
drop.Private = privateRoom;
|
||||
drop.HasLogo = hasLogo;
|
||||
|
||||
return drop;
|
||||
}
|
||||
@ -559,6 +582,7 @@ internal class ProviderAccountDao : IProviderDao
|
||||
sh.FolderType = folderType;
|
||||
sh.FolderId = folderId;
|
||||
sh.Private = privateRoom;
|
||||
sh.HasLogo = hasLogo;
|
||||
|
||||
return sh;
|
||||
}
|
||||
@ -581,6 +605,7 @@ internal class ProviderAccountDao : IProviderDao
|
||||
gd.FolderType = folderType;
|
||||
gd.FolderId = folderId;
|
||||
gd.Private = privateRoom;
|
||||
gd.HasLogo = hasLogo;
|
||||
|
||||
return gd;
|
||||
}
|
||||
@ -603,6 +628,7 @@ internal class ProviderAccountDao : IProviderDao
|
||||
od.FolderType = folderType;
|
||||
od.FolderId = folderId;
|
||||
od.Private = privateRoom;
|
||||
od.HasLogo = hasLogo;
|
||||
|
||||
return od;
|
||||
}
|
||||
@ -633,6 +659,7 @@ internal class ProviderAccountDao : IProviderDao
|
||||
sharpBoxProviderInfo.FolderType = folderType;
|
||||
sharpBoxProviderInfo.FolderId = folderId;
|
||||
sharpBoxProviderInfo.Private = privateRoom;
|
||||
sharpBoxProviderInfo.HasLogo = hasLogo;
|
||||
|
||||
return sharpBoxProviderInfo;
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ public class SharePointProviderInfo : IProviderInfo
|
||||
public string SpRootFolderId { get; set; } = "/Shared Documents";
|
||||
public string FolderId { get; set; }
|
||||
public bool Private { get; set; }
|
||||
public bool HasLogo { get; set; }
|
||||
|
||||
public SharePointProviderInfo(
|
||||
ILogger<SharePointProviderInfo> logger,
|
||||
@ -576,6 +577,7 @@ public class SharePointProviderInfo : IProviderInfo
|
||||
result.FoldersCount = 0;
|
||||
result.Error = errorFolder.Error;
|
||||
result.Private = Private;
|
||||
result.HasLogo = HasLogo;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -599,6 +601,7 @@ public class SharePointProviderInfo : IProviderInfo
|
||||
result.FilesCount = 0;
|
||||
result.FoldersCount = 0;
|
||||
result.Private = Private;
|
||||
result.HasLogo = HasLogo;
|
||||
|
||||
SetFolderType(result, isRoot);
|
||||
|
||||
|
@ -310,6 +310,7 @@ internal abstract class SharpBoxDaoBase : ThirdPartyProviderDao<SharpBoxProvider
|
||||
folder.FilesCount = 0; /*fsEntry.Count - childFoldersCount NOTE: Removed due to performance isssues*/
|
||||
folder.FoldersCount = 0; /*childFoldersCount NOTE: Removed due to performance isssues*/
|
||||
folder.Private = ProviderInfo.Private;
|
||||
folder.HasLogo = ProviderInfo.HasLogo;
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)
|
||||
|
@ -112,6 +112,7 @@ internal class SharpBoxProviderInfo : IProviderInfo
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public bool Private { get; set; }
|
||||
public bool HasLogo { get; set; }
|
||||
private readonly SharpBoxStorageDisposableWrapper _wrapper;
|
||||
}
|
||||
|
||||
|
@ -31,16 +31,14 @@ namespace ASC.Files.Core.VirtualRooms;
|
||||
[Scope]
|
||||
public class RoomLogoManager
|
||||
{
|
||||
private const string LogosPath = "{0}_size_{1}-{2}.{3}";
|
||||
private const string LogosPath = "{0}_{1}.png";
|
||||
private const string ModuleName = "room_logos";
|
||||
private const string TempDomainPath = "logos_temp";
|
||||
private const string ActionName = "logo";
|
||||
private const string Default = "default";
|
||||
|
||||
private static Size _originalLogoSize = new Size(1280, 1280);
|
||||
private static Size _largeLogoSize = new Size(96, 96);
|
||||
private static Size _mediumLogoSize = new Size(32, 32);
|
||||
private static Size _smallLogoSize = new Size(16, 16);
|
||||
private static (SizeName, Size) _originalLogoSize = (SizeName.Original, new Size(1280, 1280));
|
||||
private static (SizeName, Size) _largeLogoSize = (SizeName.Large, new Size(96, 96));
|
||||
private static (SizeName, Size) _mediumLogoSize = (SizeName.Medium, new Size(32, 32));
|
||||
private static (SizeName, Size) _smallLogoSize = (SizeName.Small, new Size(16, 16));
|
||||
|
||||
private readonly IDaoFactory _daoFactory;
|
||||
private readonly FileSecurity _fileSecurity;
|
||||
@ -48,13 +46,8 @@ public class RoomLogoManager
|
||||
private readonly StorageFactory _storageFactory;
|
||||
private readonly TenantManager _tenantManager;
|
||||
private IDataStore _dataStore;
|
||||
private readonly ICache _cache;
|
||||
private readonly FilesMessageService _filesMessageService;
|
||||
private static readonly Regex _pattern = new Regex(@"\d+-\d+", RegexOptions.Compiled);
|
||||
private static readonly Regex _cachePattern = new Regex(@"\d+\/\S+\/\d+\/\d+", RegexOptions.Compiled);
|
||||
private static readonly TimeSpan _cacheLifeTime = TimeSpan.FromMinutes(30);
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly FilesLinkUtility _filesLinkUtility;
|
||||
|
||||
public RoomLogoManager(
|
||||
StorageFactory storageFactory,
|
||||
@ -62,20 +55,16 @@ public class RoomLogoManager
|
||||
IDaoFactory daoFactory,
|
||||
FileSecurity fileSecurity,
|
||||
ILogger<RoomLogoManager> logger,
|
||||
AscCache cache,
|
||||
FilesMessageService filesMessageService,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
FilesLinkUtility filesLinkUtility)
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_storageFactory = storageFactory;
|
||||
_tenantManager = tenantManager;
|
||||
_daoFactory = daoFactory;
|
||||
_fileSecurity = fileSecurity;
|
||||
_logger = logger;
|
||||
_cache = cache;
|
||||
_filesMessageService = filesMessageService;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_filesLinkUtility = filesLinkUtility;
|
||||
}
|
||||
|
||||
public bool EnableAudit { get; set; } = true;
|
||||
@ -108,8 +97,19 @@ public class RoomLogoManager
|
||||
|
||||
id = GetId(room);
|
||||
|
||||
await DeleteLogo(id);
|
||||
await SaveWithProcessAsync(id, data, -1, new Point(x, y), new Size(width, height));
|
||||
await RemoveTempAsync(fileName);
|
||||
|
||||
room.HasLogo = true;
|
||||
|
||||
if (room.ProviderEntry)
|
||||
{
|
||||
await _daoFactory.ProviderDao.UpdateProviderInfoAsync(room.ProviderId, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
await folderDao.SaveFolderAsync(room);
|
||||
}
|
||||
|
||||
if (EnableAudit)
|
||||
{
|
||||
@ -133,14 +133,24 @@ public class RoomLogoManager
|
||||
|
||||
try
|
||||
{
|
||||
await DeleteLogo(id);
|
||||
await DataStore.DeleteFilesAsync(string.Empty, $"{ProcessFolderId(id)}*.*", false);
|
||||
room.HasLogo = false;
|
||||
|
||||
if (room.ProviderEntry)
|
||||
{
|
||||
await _daoFactory.ProviderDao.UpdateProviderInfoAsync(room.ProviderId, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await folderDao.SaveFolderAsync(room);
|
||||
}
|
||||
|
||||
if (EnableAudit)
|
||||
{
|
||||
_filesMessageService.Send(room, Headers, MessageAction.RoomLogoDeleted);
|
||||
}
|
||||
}
|
||||
catch (DirectoryNotFoundException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.ErrorRemoveRoomLogo(e);
|
||||
}
|
||||
@ -148,24 +158,35 @@ public class RoomLogoManager
|
||||
return room;
|
||||
}
|
||||
|
||||
public Logo GetLogo<T>(Folder<T> room)
|
||||
public async ValueTask<Logo> GetLogoAsync<T>(Folder<T> room)
|
||||
{
|
||||
if (!room.HasLogo)
|
||||
{
|
||||
var id = room.Id;
|
||||
|
||||
return new Logo
|
||||
{
|
||||
Original = GetOriginalLogoUrl(id),
|
||||
Large = GetLargeLogoUrl(id),
|
||||
Medium = GetMediumLogoUrl(id),
|
||||
Small = GetSmallLogoUrl(id)
|
||||
Original = string.Empty,
|
||||
Large = string.Empty,
|
||||
Medium = string.Empty,
|
||||
Small = string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
var id = GetId(room);
|
||||
|
||||
return new Logo()
|
||||
{
|
||||
Original = await GetLogoPathAsync(id, SizeName.Original),
|
||||
Large = await GetLogoPathAsync(id, SizeName.Large),
|
||||
Medium = await GetLogoPathAsync(id, SizeName.Medium),
|
||||
Small = await GetLogoPathAsync(id, SizeName.Small),
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<string> SaveTempAsync(byte[] data, long maxFileSize)
|
||||
{
|
||||
data = UserPhotoThumbnailManager.TryParseImage(data, maxFileSize, _originalLogoSize, out var imgFormat, out _, out _);
|
||||
data = UserPhotoThumbnailManager.TryParseImage(data, maxFileSize, _originalLogoSize.Item2, out _, out _, out _);
|
||||
|
||||
var fileName = Guid.NewGuid() + "." + CommonPhotoManager.GetImgFormatName(imgFormat);
|
||||
var fileName = $"{Guid.NewGuid()}.png";
|
||||
|
||||
using var stream = new MemoryStream(data);
|
||||
var path = await DataStore.SaveAsync(TempDomainPath, fileName, stream);
|
||||
@ -182,84 +203,26 @@ public class RoomLogoManager
|
||||
return pathWithoutQuery;
|
||||
}
|
||||
|
||||
public string GetOriginalLogoUrl<T>(T id)
|
||||
public async Task RemoveTempAsync(string fileName)
|
||||
{
|
||||
return GetLogoUrl(id, RoomLogoSize.Original);
|
||||
var index = fileName.LastIndexOf('.');
|
||||
var fileNameWithoutExt = (index != -1) ? fileName.Substring(0, index) : fileName;
|
||||
|
||||
try
|
||||
{
|
||||
await DataStore.DeleteFilesAsync(TempDomainPath, "", fileNameWithoutExt + "*.*", false);
|
||||
}
|
||||
|
||||
public string GetLargeLogoUrl<T>(T id)
|
||||
catch(Exception e)
|
||||
{
|
||||
return GetLogoUrl(id, RoomLogoSize.Large);
|
||||
_logger.ErrorRemoveTempPhoto(e);
|
||||
}
|
||||
|
||||
public string GetMediumLogoUrl<T>(T id)
|
||||
{
|
||||
return GetLogoUrl(id, RoomLogoSize.Medium);
|
||||
}
|
||||
|
||||
public string GetSmallLogoUrl<T>(T id)
|
||||
{
|
||||
return GetLogoUrl(id, RoomLogoSize.Small);
|
||||
}
|
||||
|
||||
public async ValueTask<string> GetMediumLogoPathAsync<T>(T id)
|
||||
{
|
||||
return await GetLogoPathAsync(id, _mediumLogoSize);
|
||||
}
|
||||
|
||||
public async ValueTask<string> GetSmallLogoPathAsync<T>(T id)
|
||||
{
|
||||
return await GetLogoPathAsync(id, _smallLogoSize);
|
||||
}
|
||||
|
||||
public async ValueTask<string> GetLargeLogoPathAsync<T>(T id)
|
||||
{
|
||||
return await GetLogoPathAsync(id, _largeLogoSize);
|
||||
}
|
||||
|
||||
public async ValueTask<string> GetOriginalLogoPathAsync<T>(T id)
|
||||
{
|
||||
return await GetLogoPathAsync(id, null, true);
|
||||
}
|
||||
|
||||
public async Task<string> GetLogoPathAsync<T>(T id, string size)
|
||||
{
|
||||
var room = await _daoFactory.GetFolderDao<T>().GetFolderAsync(id);
|
||||
|
||||
if (room == null)
|
||||
{
|
||||
throw new ItemNotFoundException("Room not found");
|
||||
}
|
||||
|
||||
if (!await _fileSecurity.CanReadAsync(room))
|
||||
{
|
||||
throw new SecurityException("You don't have permission to read the room");
|
||||
}
|
||||
|
||||
if (!RoomLogoSizeExtensions.TryParse(size, true, out var result))
|
||||
{
|
||||
throw new ArgumentException("Size not valid", nameof(size));
|
||||
}
|
||||
|
||||
id = GetId(room);
|
||||
|
||||
return result switch
|
||||
{
|
||||
RoomLogoSize.Original => await GetOriginalLogoPathAsync(id),
|
||||
RoomLogoSize.Large => await GetLargeLogoPathAsync(id),
|
||||
RoomLogoSize.Medium => await GetMediumLogoPathAsync(id),
|
||||
RoomLogoSize.Small => await GetSmallLogoPathAsync(id),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<string> SaveWithProcessAsync<T>(T id, byte[] imageData, long maxFileSize, Point position, Size cropSize)
|
||||
{
|
||||
imageData = UserPhotoThumbnailManager.TryParseImage(imageData, maxFileSize, _originalLogoSize, out var imageFormat, out var width, out var height);
|
||||
imageData = UserPhotoThumbnailManager.TryParseImage(imageData, maxFileSize, _originalLogoSize.Item2, out var _, out var _, out var _);
|
||||
|
||||
var imageExtension = CommonPhotoManager.GetImgFormatName(imageFormat);
|
||||
|
||||
var fileName = $"{ProcessFolderId(id)}_orig_{width}-{height}.{imageExtension}";
|
||||
var fileName = string.Format(LogosPath, ProcessFolderId(id), SizeName.Original.ToStringLowerFast());
|
||||
|
||||
if (imageData == null || imageData.Length == 0)
|
||||
{
|
||||
@ -276,7 +239,7 @@ public class RoomLogoManager
|
||||
return path.ToString();
|
||||
}
|
||||
|
||||
private async Task ResizeAndSaveAsync<T>(T id, byte[] data, long maxFileSize, Size size, Point position, Size cropSize)
|
||||
private async Task ResizeAndSaveAsync<T>(T id, byte[] data, long maxFileSize, (SizeName, Size) size, Point position, Size cropSize)
|
||||
{
|
||||
if (data == null || data.Length <= 0)
|
||||
{
|
||||
@ -293,9 +256,9 @@ public class RoomLogoManager
|
||||
using var img = Image.Load(stream, out var format);
|
||||
var imgFormat = format;
|
||||
|
||||
if (size != img.Size())
|
||||
if (size.Item2 != img.Size())
|
||||
{
|
||||
using var img2 = UserPhotoThumbnailManager.GetImage(img, size, new UserPhotoThumbnailSettings(position, cropSize));
|
||||
using var img2 = UserPhotoThumbnailManager.GetImage(img, size.Item2, new UserPhotoThumbnailSettings(position, cropSize));
|
||||
data = CommonPhotoManager.SaveToBytes(img2);
|
||||
}
|
||||
else
|
||||
@ -304,7 +267,7 @@ public class RoomLogoManager
|
||||
}
|
||||
|
||||
var extension = CommonPhotoManager.GetImgFormatName(imgFormat);
|
||||
var fileName = string.Format(LogosPath, ProcessFolderId(id), size.Width, size.Height, extension);
|
||||
var fileName = string.Format(LogosPath, ProcessFolderId(id), size.Item1.ToStringLowerFast());
|
||||
|
||||
using var stream2 = new MemoryStream(data);
|
||||
await DataStore.SaveAsync(fileName, stream2);
|
||||
@ -315,33 +278,12 @@ public class RoomLogoManager
|
||||
}
|
||||
}
|
||||
|
||||
private string GetLogoUrl<T>(T id, RoomLogoSize size)
|
||||
private async ValueTask<string> GetLogoPathAsync<T>(T id, SizeName size)
|
||||
{
|
||||
return $"{_filesLinkUtility.FileHandlerPath}?{FilesLinkUtility.Action}={ActionName}" +
|
||||
$"&{FilesLinkUtility.FolderId}={Uri.EscapeDataString(id.ToString())}" +
|
||||
$"&{FilesLinkUtility.Size}={size.ToStringLowerFast()}";
|
||||
}
|
||||
var fileName = string.Format(LogosPath, ProcessFolderId(id), size.ToStringLowerFast());
|
||||
var uri = await DataStore.GetUriAsync(fileName);
|
||||
|
||||
private async ValueTask<string> GetLogoPathAsync<T>(T id, Size? size, bool original = false)
|
||||
{
|
||||
var key = original ? GetKey(id) : GetKey(id, size.Value);
|
||||
|
||||
var path = _cache.Get<string>(key);
|
||||
if (path == Default)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
return await ValueTask.FromResult(path);
|
||||
}
|
||||
|
||||
await LoadPathToCacheAsync(id);
|
||||
|
||||
path = _cache.Get<string>(key);
|
||||
|
||||
return path == null || path == Default ? string.Empty : path;
|
||||
return uri.ToString();
|
||||
}
|
||||
|
||||
private async Task<byte[]> GetTempAsync(string fileName)
|
||||
@ -364,37 +306,6 @@ public class RoomLogoManager
|
||||
return data.ToArray();
|
||||
}
|
||||
|
||||
private async Task LoadPathToCacheAsync<T>(T id)
|
||||
{
|
||||
var logoPath = await DataStore.ListFilesAsync(string.Empty, $"{ProcessFolderId(id)}*", false)
|
||||
.Select(u => u.ToString()).ToListAsync();
|
||||
|
||||
if (logoPath.Count == 0)
|
||||
{
|
||||
SetDefaultCache(id);
|
||||
return;
|
||||
}
|
||||
|
||||
var original = logoPath.Where(u => u.Contains("orig")).FirstOrDefault();
|
||||
|
||||
_cache.Insert(GetKey(id), original, _cacheLifeTime);
|
||||
|
||||
logoPath.Remove(original);
|
||||
|
||||
foreach (var (k, v) in logoPath.ToDictionary(p => _pattern.Match(p).Value.Split('-')))
|
||||
{
|
||||
_cache.Insert(GetKey(id, new Size(int.Parse(k[0]), int.Parse(k[1]))), v, _cacheLifeTime);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteLogo<T>(T id)
|
||||
{
|
||||
await DataStore.DeleteFilesAsync(string.Empty, $"{ProcessFolderId(id)}*.*", false);
|
||||
|
||||
_cache.Remove(_cachePattern);
|
||||
_cache.Remove(GetKey(id));
|
||||
}
|
||||
|
||||
private string ProcessFolderId<T>(T id)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(id, nameof(id));
|
||||
@ -404,24 +315,6 @@ public class RoomLogoManager
|
||||
: id.ToString()?.Replace("-", "").Replace("|", "");
|
||||
}
|
||||
|
||||
private string GetKey<T>(T id, Size size)
|
||||
{
|
||||
return $"{TenantId}/{id}/{size.Width}/{size.Height}";
|
||||
}
|
||||
|
||||
private string GetKey<T>(T id)
|
||||
{
|
||||
return $"{TenantId}/{id}/orig";
|
||||
}
|
||||
|
||||
private void SetDefaultCache<T>(T id)
|
||||
{
|
||||
_cache.Insert(GetKey(id), Default, _cacheLifeTime);
|
||||
_cache.Insert(GetKey(id, _largeLogoSize), Default, _cacheLifeTime);
|
||||
_cache.Insert(GetKey(id, _mediumLogoSize), Default, _cacheLifeTime);
|
||||
_cache.Insert(GetKey(id, _smallLogoSize), Default, _cacheLifeTime);
|
||||
}
|
||||
|
||||
private T GetId<T>(Folder<T> room)
|
||||
{
|
||||
return room.ProviderEntry && (room.RootId.ToString().Contains("sbox")
|
||||
@ -430,7 +323,7 @@ public class RoomLogoManager
|
||||
}
|
||||
|
||||
[EnumExtensions]
|
||||
public enum RoomLogoSize
|
||||
public enum SizeName
|
||||
{
|
||||
Original = 0,
|
||||
Large = 1,
|
||||
|
@ -196,9 +196,6 @@ public class FileHandlerService
|
||||
case "track":
|
||||
await TrackFile(context);
|
||||
break;
|
||||
case "logo":
|
||||
await GetRoomLogoPathAsync(context);
|
||||
break;
|
||||
default:
|
||||
throw new HttpException((int)HttpStatusCode.BadRequest, FilesCommonResource.ErrorMassage_BadRequest);
|
||||
}
|
||||
@ -1569,60 +1566,6 @@ public class FileHandlerService
|
||||
|
||||
await context.Response.WriteAsync(TrackResponse.Serialize(result));
|
||||
}
|
||||
|
||||
private async Task GetRoomLogoPathAsync(HttpContext context)
|
||||
{
|
||||
if (!_securityContext.IsAuthenticated)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return;
|
||||
}
|
||||
|
||||
var folderId = context.Request.Query[FilesLinkUtility.FolderId].FirstOrDefault();
|
||||
var size = context.Request.Query[FilesLinkUtility.Size].FirstOrDefault();
|
||||
|
||||
string result;
|
||||
|
||||
try
|
||||
{
|
||||
if (int.TryParse(folderId, out var id))
|
||||
{
|
||||
result = await _roomLogoManager.GetLogoPathAsync(id, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await _roomLogoManager.GetLogoPathAsync(folderId, size);
|
||||
}
|
||||
}
|
||||
catch(ItemNotFoundException)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
return;
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
return;
|
||||
}
|
||||
|
||||
context.Response.Clear();
|
||||
await context.Response.WriteAsync(result);
|
||||
|
||||
try
|
||||
{
|
||||
await context.Response.Body.FlushAsync();
|
||||
await context.Response.CompleteAsync();
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
_logger.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FileHandlerExtensions
|
||||
|
@ -30,4 +30,7 @@ public static partial class RoomLogoManagerLogger
|
||||
{
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "RemoveRoomLogo")]
|
||||
public static partial void ErrorRemoveRoomLogo(this ILogger<RoomLogoManager> logger, Exception exception);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "RemoveTempPhoto")]
|
||||
public static partial void ErrorRemoveTempPhoto(this ILogger<RoomLogoManager> logger, Exception exception);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user