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:
Akmal Isomadinov 2022-12-16 17:31:44 +05:00
commit 3f19ea513a
49 changed files with 5553 additions and 581 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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");
}
}
}

View File

@ -2329,6 +2329,10 @@ namespace ASC.Migrations.MySql.Migrations
.HasColumnName("folder_type") .HasColumnName("folder_type")
.HasDefaultValueSql("'0'"); .HasDefaultValueSql("'0'");
b.Property<bool>("HasLogo")
.HasColumnType("tinyint(1)")
.HasColumnName("has_logo");
b.Property<string>("Password") b.Property<string>("Password")
.IsRequired() .IsRequired()
.HasColumnType("varchar(512)") .HasColumnType("varchar(512)")
@ -2502,6 +2506,10 @@ namespace ASC.Migrations.MySql.Migrations
.HasColumnName("foldersCount") .HasColumnName("foldersCount")
.HasDefaultValueSql("'0'"); .HasDefaultValueSql("'0'");
b.Property<bool>("HasLogo")
.HasColumnType("tinyint(1)")
.HasColumnName("has_logo");
b.Property<string>("ModifiedBy") b.Property<string>("ModifiedBy")
.IsRequired() .IsRequired()
.HasColumnType("char(38)") .HasColumnType("char(38)")

File diff suppressed because it is too large Load Diff

View File

@ -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");
}
}
}

View File

@ -2283,6 +2283,10 @@ namespace ASC.Migrations.PostgreSql.Migrations
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("folder_type"); .HasColumnName("folder_type");
b.Property<bool>("HasLogo")
.HasColumnType("boolean")
.HasColumnName("has_logo");
b.Property<string>("Password") b.Property<string>("Password")
.IsRequired() .IsRequired()
.HasMaxLength(100) .HasMaxLength(100)
@ -2430,6 +2434,10 @@ namespace ASC.Migrations.PostgreSql.Migrations
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("foldersCount"); .HasColumnName("foldersCount");
b.Property<bool>("HasLogo")
.HasColumnType("boolean")
.HasColumnName("has_logo");
b.Property<Guid>("ModifiedBy") b.Property<Guid>("ModifiedBy")
.HasMaxLength(38) .HasMaxLength(38)
.HasColumnType("uuid") .HasColumnType("uuid")

View File

@ -19,7 +19,6 @@ const PureSettingsItem = ({
setExpandSettingsTree, setExpandSettingsTree,
setSelectedFolder, setSelectedFolder,
history, history,
setIsLoading,
t, t,
showText, showText,
toggleArticleOpen, toggleArticleOpen,
@ -27,10 +26,8 @@ const PureSettingsItem = ({
const { setting } = match.params; const { setting } = match.params;
React.useEffect(() => { React.useEffect(() => {
setIsLoading(true);
setSelectedNode([setting]); setSelectedNode([setting]);
setIsLoading(false); }, [setting, setSelectedNode]);
}, [setting, setIsLoading, setSelectedNode]);
React.useEffect(() => { React.useEffect(() => {
if (setting && !expandedSetting) setExpandSettingsTree(["settings"]); if (setting && !expandedSetting) setExpandSettingsTree(["settings"]);
@ -73,20 +70,13 @@ const SettingsItem = withTranslation(["FilesSettings", "Common"])(
); );
export default inject( export default inject(
({ ({ auth, settingsStore, treeFoldersStore, selectedFolderStore }) => {
auth,
filesStore,
settingsStore,
treeFoldersStore,
selectedFolderStore,
}) => {
const { setIsLoading } = filesStore;
const { setSelectedFolder } = selectedFolderStore; const { setSelectedFolder } = selectedFolderStore;
const { setSelectedNode } = treeFoldersStore; const { setSelectedNode } = treeFoldersStore;
const { expandedSetting, setExpandSettingsTree } = settingsStore; const { expandedSetting, setExpandSettingsTree } = settingsStore;
return { return {
expandedSetting, expandedSetting,
setIsLoading,
setSelectedFolder, setSelectedFolder,
setSelectedNode, setSelectedNode,
setExpandSettingsTree, setExpandSettingsTree,

View File

@ -101,13 +101,13 @@ const CreateEvent = ({
setStartValue(newValue); setStartValue(newValue);
} }
// let tab = let tab =
// !isDesktop && extension && open !isDesktop && extension && open
// ? window.open( ? window.open(
// combineUrl(AppServerConfig.proxyURL, config.homepage, `/doceditor`), combineUrl(AppServerConfig.proxyURL, config.homepage, `/doceditor`),
// "_blank" "_blank"
// ) )
// : null; : null;
if (!extension) { if (!extension) {
createFolder(parentId, newValue) createFolder(parentId, newValue)
@ -135,7 +135,7 @@ const CreateEvent = ({
createdFileId = file.id; createdFileId = file.id;
addActiveItems([file.id]); addActiveItems([file.id]);
open && openDocEditor(file.id, file.providerKey, null); open && openDocEditor(file.id, file.providerKey, tab);
}) })
.then(() => editCompleteAction(item, type)) .then(() => editCompleteAction(item, type))
.catch((err) => { .catch((err) => {
@ -196,7 +196,7 @@ const CreateEvent = ({
setCreatedItem({ id: createdFileId, type: "file" }); setCreatedItem({ id: createdFileId, type: "file" });
addActiveItems([file.id]); addActiveItems([file.id]);
return open && openDocEditor(file.id, file.providerKey, null); return open && openDocEditor(file.id, file.providerKey, tab);
}) })
.then(() => editCompleteAction(item, type)) .then(() => editCompleteAction(item, type))
.catch((e) => toastr.error(e)) .catch((e) => toastr.error(e))
@ -227,12 +227,12 @@ const CreateEvent = ({
true, true,
false false
).then( ).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)) .then(() => editCompleteAction(item, type))
.catch((e) => toastr.error(e)) .catch((e) => toastr.error(e))

View File

@ -32,7 +32,6 @@ const EditRoomEvent = ({
withPaging, withPaging,
reloadSelection, reloadSelection,
getRoomLogo,
}) => { }) => {
const { t } = useTranslation(["CreateEditRoomDialog", "Common", "Files"]); const { t } = useTranslation(["CreateEditRoomDialog", "Common", "Files"]);
@ -107,12 +106,6 @@ const EditRoomEvent = ({
}); });
if (!withPaging) { if (!withPaging) {
const newLogo = await getRoomLogo(room.logo);
room.logoHandlers = room.logo;
room.logo = newLogo;
room.isLogoLoading = false;
setFolder(room); setFolder(room);
} }
@ -125,12 +118,6 @@ const EditRoomEvent = ({
}); });
} else { } else {
if (!withPaging) { if (!withPaging) {
const newLogo = await getRoomLogo(room.logo);
room.logoHandlers = room.logo;
room.logo = newLogo;
room.isLogoLoading = false;
setFolder(room); setFolder(room);
} }
// to update state info panel // to update state info panel
@ -149,9 +136,7 @@ const EditRoomEvent = ({
}; };
useEffect(async () => { useEffect(async () => {
const logo = item?.logo?.original const logo = item?.logo?.original ? item.logo.original : "";
? item.logo.original
: await api.rooms.getLogoIcon(item?.logoHandlers?.original);
if (logo) { if (logo) {
const imgExst = logo.slice(".")[1]; const imgExst = logo.slice(".")[1];
@ -212,7 +197,6 @@ export default inject(
setFolder, setFolder,
addLogoToRoom, addLogoToRoom,
removeLogoFromRoom, removeLogoFromRoom,
getRoomLogo,
} = filesStore; } = filesStore;
const { createTag, fetchTags } = tagsStore; const { createTag, fetchTags } = tagsStore;
@ -226,7 +210,6 @@ export default inject(
editRoom, editRoom,
addTagsToRoom, addTagsToRoom,
removeTagsFromRoom, removeTagsFromRoom,
getRoomLogo,
createTag, createTag,
fetchTags, fetchTags,

View File

@ -37,7 +37,10 @@ const InvitePanel = ({
adminLink, adminLink,
defaultAccess, defaultAccess,
inviteUsers, inviteUsers,
setInfoPanelIsMobileHidden,
reloadSelectionParentRoom, reloadSelectionParentRoom,
setUpdateRoomMembers,
roomsView,
}) => { }) => {
const [selectedRoom, setSelectedRoom] = useState(null); const [selectedRoom, setSelectedRoom] = useState(null);
const [hasErrors, setHasErrors] = useState(false); const [hasErrors, setHasErrors] = useState(false);
@ -118,6 +121,7 @@ const InvitePanel = ({
}, [inviteItems]); }, [inviteItems]);
const onClose = () => { const onClose = () => {
setInfoPanelIsMobileHidden(false);
setInvitePanelOptions({ setInvitePanelOptions({
visible: false, visible: false,
hideSelector: false, hideSelector: false,
@ -160,6 +164,8 @@ const InvitePanel = ({
roomId === -1 roomId === -1
? await inviteUsers(data) ? await inviteUsers(data)
: await setRoomSecurity(roomId, data); : await setRoomSecurity(roomId, data);
if (roomsView === "info_members") setUpdateRoomMembers(true);
onClose(); onClose();
toastr.success(t("Common:UsersInvited")); toastr.success(t("Common:UsersInvited"));
reloadSelectionParentRoom(); reloadSelectionParentRoom();
@ -244,7 +250,13 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
const { theme } = auth.settingsStore; const { theme } = auth.settingsStore;
const { getUsersByQuery, inviteUsers } = peopleStore.usersStore; const { getUsersByQuery, inviteUsers } = peopleStore.usersStore;
const { reloadSelectionParentRoom } = auth.infoPanelStore; const {
setIsMobileHidden: setInfoPanelIsMobileHidden,
reloadSelectionParentRoom,
setUpdateRoomMembers,
roomsView,
filesView,
} = auth.infoPanelStore;
const { const {
getPortalInviteLinks, getPortalInviteLinks,
@ -285,7 +297,10 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
guestLink, guestLink,
adminLink, adminLink,
inviteUsers, inviteUsers,
setInfoPanelIsMobileHidden,
reloadSelectionParentRoom, reloadSelectionParentRoom,
setUpdateRoomMembers,
roomsView,
}; };
})( })(
withTranslation([ withTranslation([

View File

@ -30,10 +30,7 @@ const FilesItemTitle = ({
</StyledTitle> </StyledTitle>
); );
const icon = const icon = selection.icon;
selection?.isRoom && selection?.logo?.medium
? selection.logo.medium
: selection.icon;
return ( return (
<StyledTitle ref={itemTitleRef}> <StyledTitle ref={itemTitleRef}>

View File

@ -22,7 +22,6 @@ const Details = ({
isVisitor, isVisitor,
}) => { }) => {
const [itemProperties, setItemProperties] = useState([]); const [itemProperties, setItemProperties] = useState([]);
const [largeLogoIcon, setLargeLogoIcon] = useState("");
const [isThumbnailError, setIsThumbmailError] = useState(false); const [isThumbnailError, setIsThumbmailError] = useState(false);
const onThumbnailError = () => setIsThumbmailError(true); const onThumbnailError = () => setIsThumbmailError(true);
@ -39,24 +38,9 @@ const Details = ({
culture, 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 () => { useEffect(async () => {
setItemProperties(detailsHelper.getPropertyList()); setItemProperties(detailsHelper.getPropertyList());
if ((selection?.isRoom || selection?.roomType) && !selection.isArchive) {
getLargeRoomLogo(selection?.logoHandlers?.large);
}
if ( if (
!selection.isFolder && !selection.isFolder &&
selection.thumbnailStatus === 0 && selection.thumbnailStatus === 0 &&
@ -67,10 +51,11 @@ const Details = ({
) { ) {
await createThumbnail(selection.id); await createThumbnail(selection.id);
} }
}, [selection, getLargeRoomLogo]); }, [selection]);
const currentIcon = largeLogoIcon const currentIcon =
? largeLogoIcon !selection.isArchive && selection?.logo?.large
? selection?.logo?.large
: getInfoPanelItemIcon(selection, 96); : getInfoPanelItemIcon(selection, 96);
return ( return (
@ -89,7 +74,10 @@ const Details = ({
<StyledNoThumbnail> <StyledNoThumbnail>
<img <img
className={`no-thumbnail-img ${selection.isRoom && "is-room"} ${ 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} src={currentIcon}
alt="thumbnail-icon-big" alt="thumbnail-icon-big"

View File

@ -21,6 +21,10 @@ const Members = ({
isAdmin, isAdmin,
selection, selection,
setIsMobileHidden,
updateRoomMembers,
setUpdateRoomMembers,
selectionParentRoom, selectionParentRoom,
setSelectionParentRoom, setSelectionParentRoom,
@ -64,6 +68,7 @@ const Members = ({
}); });
setShowLoader(false); setShowLoader(false);
setUpdateRoomMembers(false);
return { return {
inRoom: inRoomMembers, inRoom: inRoomMembers,
expected: expectedMembers, expected: expectedMembers,
@ -95,7 +100,20 @@ const Members = ({
}); });
}, [selection]); }, [selection]);
useEffect(async () => {
if (!updateRoomMembers) return;
const fetchedMembers = await fetchMembers(selection.id);
setSelectionParentRoom({
...selectionParentRoom,
members: fetchedMembers,
});
setMembers(fetchedMembers);
}, [selectionParentRoom, selection?.id, updateRoomMembers]);
const onClickInviteUsers = () => { const onClickInviteUsers = () => {
setIsMobileHidden(true);
const parentRoomId = selectionParentRoom.id; const parentRoomId = selectionParentRoom.id;
setInvitePanelOptions({ setInvitePanelOptions({
@ -205,7 +223,15 @@ const Members = ({
export default inject( export default inject(
({ auth, filesStore, peopleStore, dialogsStore, accessRightsStore }) => { ({ auth, filesStore, peopleStore, dialogsStore, accessRightsStore }) => {
const { selectionParentRoom, setSelectionParentRoom } = auth.infoPanelStore; const {
setIsMobileHidden,
selectionParentRoom,
setSelectionParentRoom,
roomsView,
updateRoomMembers,
setUpdateRoomMembers,
} = auth.infoPanelStore;
const { const {
getRoomMembers, getRoomMembers,
updateRoomMemberRole, updateRoomMemberRole,
@ -221,12 +247,16 @@ export default inject(
} = accessRightsStore; } = accessRightsStore;
return { return {
setIsMobileHidden,
selectionParentRoom, selectionParentRoom,
setSelectionParentRoom, setSelectionParentRoom,
getRoomMembers, getRoomMembers,
updateRoomMemberRole, updateRoomMemberRole,
updateRoomMembers,
setUpdateRoomMembers,
isOwner, isOwner,
isAdmin, isAdmin,
selfId, selfId,

View File

@ -231,7 +231,7 @@ const SimpleFilesRow = (props) => {
const element = ( const element = (
<ItemIcon <ItemIcon
id={item.id} id={item.id}
icon={item.isRoom && item.logo.medium ? item.logo.medium : item.icon} icon={item.icon}
fileExst={item.fileExst} fileExst={item.fileExst}
isRoom={item.isRoom} isRoom={item.isRoom}
/> />

View File

@ -324,7 +324,7 @@ const FilesTableRow = (props) => {
const element = ( const element = (
<ItemIcon <ItemIcon
id={item.id} id={item.id}
icon={item.isRoom && item.logo.medium ? item.logo.medium : item.icon} icon={item.icon}
fileExst={item.fileExst} fileExst={item.fileExst}
isRoom={item.isRoom} isRoom={item.isRoom}
/> />

View File

@ -68,7 +68,7 @@ const FileTile = (props) => {
const element = ( const element = (
<ItemIcon <ItemIcon
id={item.id} id={item.id}
icon={item.isRoom && item.logo.medium ? item.logo.medium : item.icon} icon={item.icon}
fileExst={item.fileExst} fileExst={item.fileExst}
isRoom={item.isRoom} isRoom={item.isRoom}
/> />

View File

@ -263,6 +263,8 @@ class ContextOptionsStore {
}; };
gotoDocEditor = (preview = false, item) => { gotoDocEditor = (preview = false, item) => {
const { isDesktopClient } = this.authStore.settingsStore;
const { id, providerKey, fileExst } = item; const { id, providerKey, fileExst } = item;
const urlFormation = preview const urlFormation = preview
@ -274,13 +276,9 @@ class ContextOptionsStore {
: null; : null;
let tab = let tab =
!this.authStore.isDesktopClient && fileExst !isDesktopClient && fileExst
? window.open( ? window.open(
combineUrl( combineUrl(AppServerConfig.proxyURL, config.homepage, `/doceditor`),
AppServerConfig.proxyURL,
config.homepage,
`/doceditor?fileId=${id}`
),
"_blank" "_blank"
) )
: null; : null;

View File

@ -277,6 +277,7 @@ class FilesActionStore {
this.isMediaOpen(); this.isMediaOpen();
try { try {
this.filesStore.setOperationAction(true);
await removeFiles(folderIds, fileIds, deleteAfter, immediately) await removeFiles(folderIds, fileIds, deleteAfter, immediately)
.then(async (res) => { .then(async (res) => {
if (res[0]?.error) return Promise.reject(res[0].error); if (res[0]?.error) return Promise.reject(res[0].error);
@ -330,6 +331,8 @@ class FilesActionStore {
}); });
setTimeout(() => clearSecondaryProgressData(), TIMEOUT); setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
return toastr.error(err.message ? err.message : err); return toastr.error(err.message ? err.message : err);
} finally {
this.filesStore.setOperationAction(false);
} }
} }
}; };
@ -675,10 +678,13 @@ class FilesActionStore {
label: translations?.deleteOperation, label: translations?.deleteOperation,
}; };
this.filesStore.setOperationAction(true);
if (isFile) { if (isFile) {
addActiveItems([itemId]); addActiveItems([itemId]);
this.isMediaOpen(); this.isMediaOpen();
return deleteFile(itemId).then(async (res) => { return deleteFile(itemId)
.then(async (res) => {
if (res[0]?.error) return Promise.reject(res[0].error); if (res[0]?.error) return Promise.reject(res[0].error);
const data = res[0] ? res[0] : null; const data = res[0] ? res[0] : null;
await this.uploadDataStore.loopFilesOperations(data, pbData); await this.uploadDataStore.loopFilesOperations(data, pbData);
@ -692,7 +698,8 @@ class FilesActionStore {
toastr.success(translations.successRemoveFile) toastr.success(translations.successRemoveFile)
); );
} }
}); })
.finally(() => this.filesStore.setOperationAction(false));
} else if (isRoom) { } else if (isRoom) {
const items = Array.isArray(itemId) ? itemId : [itemId]; const items = Array.isArray(itemId) ? itemId : [itemId];
addActiveItems(null, items); addActiveItems(null, items);
@ -715,7 +722,8 @@ class FilesActionStore {
); );
} else { } else {
addActiveItems(null, [itemId]); 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); if (res[0]?.error) return Promise.reject(res[0].error);
const data = res[0] ? res[0] : null; const data = res[0] ? res[0] : null;
await this.uploadDataStore.loopFilesOperations(data, pbData); await this.uploadDataStore.loopFilesOperations(data, pbData);
@ -731,7 +739,8 @@ class FilesActionStore {
} }
getIsEmptyTrash(); getIsEmptyTrash();
}); })
.finally(() => this.filesStore.setOperationAction(false));
} }
}; };

View File

@ -27,6 +27,7 @@ import { isDesktop } from "@docspace/components/utils/device";
import { getContextMenuKeysByType } from "SRC_DIR/helpers/plugins"; import { getContextMenuKeysByType } from "SRC_DIR/helpers/plugins";
import { PluginContextMenuItemType } from "SRC_DIR/helpers/plugins/constants"; import { PluginContextMenuItemType } from "SRC_DIR/helpers/plugins/constants";
import { getArchiveRoomRoleActions } from "@docspace/common/utils/actions"; import { getArchiveRoomRoleActions } from "@docspace/common/utils/actions";
import debounce from "lodash.debounce";
const { FilesFilter, RoomsFilter } = api; const { FilesFilter, RoomsFilter } = api;
const storageViewAs = localStorage.getItem("viewAs"); const storageViewAs = localStorage.getItem("viewAs");
@ -102,7 +103,12 @@ class FilesStore {
isEmptyPage = false; isEmptyPage = false;
isLoadedFetchFiles = false; isLoadedFetchFiles = false;
tempActionFilesIds = [];
operationAction = false;
isErrorRoomNotAvailable = false; isErrorRoomNotAvailable = false;
constructor( constructor(
authStore, authStore,
selectedFolderStore, selectedFolderStore,
@ -128,7 +134,7 @@ class FilesStore {
socketHelper.on("s:modify-folder", async (opt) => { socketHelper.on("s:modify-folder", async (opt) => {
console.log("[WS] s:modify-folder", opt); console.log("[WS] s:modify-folder", opt);
if (this.isLoading) return; if (this.isLoading || this.operationAction) return;
switch (opt?.cmd) { switch (opt?.cmd) {
case "create": case "create":
@ -203,15 +209,23 @@ class FilesStore {
this.files[foundIndex].title this.files[foundIndex].title
); );
this.setFiles( // this.setFiles(
this.files.filter((_, index) => { // this.files.filter((_, index) => {
return index !== foundIndex; // return index !== foundIndex;
}) // })
); // );
const newFilter = this.filter.clone(); // const newFilter = this.filter.clone();
newFilter.total -= 1; // newFilter.total -= 1;
this.setFilter(newFilter); // 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 // Hide pagination when deleting files
runInAction(() => { runInAction(() => {
@ -239,7 +253,10 @@ class FilesStore {
// `selected folder id ${this.selectedFolderStore.id} an changed folder id ${id}` // `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); console.log("[WS] refresh-folder", id);
this.fetchFiles(id, this.filter); 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) => { updateSelectionStatus = (id, status, isEditing) => {
const index = this.selection.findIndex((x) => x.id === id); const index = this.selection.findIndex((x) => x.id === id);
@ -1050,8 +1079,6 @@ class FilesStore {
this.setCreatedItem(null); this.setCreatedItem(null);
} }
this.updateRoomLoadingLogo();
this.isErrorRoomNotAvailable = false; this.isErrorRoomNotAvailable = false;
return Promise.resolve(selectedFolder); return Promise.resolve(selectedFolder);
}) })
@ -1832,9 +1859,13 @@ class FilesStore {
showToast && showToast(); showToast && showToast();
}) })
.catch(() => { .catch((err) => {
toastr.error(err); toastr.error(err);
console.log("Need page reload"); console.log("Need page reload");
})
.finally(() => {
this.setOperationAction(false);
this.setTempActionFilesIds([]);
}); });
}; };
@ -2027,48 +2058,6 @@ class FilesStore {
return folderUrl; 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() { get filesList() {
const { getIcon } = this.filesSettingsStore; const { getIcon } = this.filesSettingsStore;
//return [...this.folders, ...this.files]; //return [...this.folders, ...this.files];
@ -2099,8 +2088,6 @@ class FilesStore {
foldersCount, foldersCount,
id, id,
logo, logo,
logoHandlers,
isLogoLoading,
locked, locked,
parentId, parentId,
pureContentLength, pureContentLength,
@ -2150,14 +2137,6 @@ class FilesStore {
const isThirdPartyFolder = providerKey && id === rootFolderId; const isThirdPartyFolder = providerKey && id === rootFolderId;
const iconSize = this.viewAs === "table" ? 24 : 32; const iconSize = this.viewAs === "table" ? 24 : 32;
const icon = getIcon(
iconSize,
fileExst,
providerKey,
contentLength,
roomType,
isArchive
);
let isFolder = false; let isFolder = false;
this.folders.map((x) => { this.folders.map((x) => {
@ -2188,6 +2167,18 @@ class FilesStore {
const isRoom = !!roomType; const isRoom = !!roomType;
const icon =
isRoom && !isArchive && logo?.medium
? logo?.medium
: getIcon(
iconSize,
fileExst,
providerKey,
contentLength,
roomType,
isArchive
);
return { return {
access, access,
//checked, //checked,
@ -2206,9 +2197,8 @@ class FilesStore {
icon, icon,
id, id,
isFolder, isFolder,
isLogoLoading,
logo, logo,
logoHandlers,
locked, locked,
new: item.new, new: item.new,
parentId, parentId,
@ -2846,8 +2836,6 @@ class FilesStore {
this.setFolders([...this.folders, ...newFiles.folders]); this.setFolders([...this.folders, ...newFiles.folders]);
this.setFilesIsLoading(false); 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. //Duplicate of countTilesInRow, used to update the number of tiles in a row after the window is resized.

View File

@ -24,8 +24,8 @@ class SelectedFolderStore {
roomType = null; roomType = null;
pinned = null; pinned = null;
isRoom = null; isRoom = null;
isArchive = null;
logo = null; logo = null;
logoHandlers = null;
tags = null; tags = null;
rootFolderId = null; rootFolderId = null;
settingsStore = null; settingsStore = null;

View File

@ -431,7 +431,7 @@ class UploadDataStore {
} }
}); });
// storeOriginalFiles && this.refreshFiles(file); storeOriginalFiles && this.refreshFiles(file);
if (fileInfo && fileInfo !== "password") { if (fileInfo && fileInfo !== "password") {
file.fileInfo = fileInfo; file.fileInfo = fileInfo;
@ -653,6 +653,8 @@ class UploadDataStore {
} }
} }
} }
this.filesStore.setOperationAction(false);
}; };
const isFiltered = const isFiltered =
@ -694,6 +696,7 @@ class UploadDataStore {
file, file,
path path
) => { ) => {
this.filesStore.setOperationAction(true);
const length = requestsDataArray.length; const length = requestsDataArray.length;
for (let index = 0; index < length; index++) { for (let index = 0; index < length; index++) {
if ( if (
@ -769,10 +772,8 @@ class UploadDataStore {
return Promise.resolve(); return Promise.resolve();
} else { } else {
if (currentFile.action === "uploaded") { if (currentFile.action === "uploaded") {
if (currentFile?.path?.length > 1) {
this.refreshFiles(currentFile); this.refreshFiles(currentFile);
} }
}
return Promise.resolve(); return Promise.resolve();
} }
}; };

View File

@ -5,7 +5,7 @@ import { FolderType, RoomSearchArea } from "../../constants";
import find from "lodash/find"; import find from "lodash/find";
import { getFolderOptions, decodeDisplayName } from "../../utils"; import { getFolderOptions, decodeDisplayName } from "../../utils";
import { Encoder } from "../../utils/encoder"; import { Encoder } from "../../utils/encoder";
import { getLogoIcon, getRooms } from "../rooms"; import { getRooms } from "../rooms";
import RoomsFilter from "../rooms/filter"; import RoomsFilter from "../rooms/filter";
export function openEdit(fileId, version, doc, view) { export function openEdit(fileId, version, doc, view) {
@ -39,45 +39,7 @@ export function getFolderInfo(folderId) {
url: `/files/folder/${folderId}`, url: `/files/folder/${folderId}`,
}; };
return request(options).then((res) => { return request(options);
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;
});
} }
export function getFolderPath(folderId) { export function getFolderPath(folderId) {
@ -95,40 +57,9 @@ export function getFolder(folderId, filter) {
res.files = decodeDisplayName(res.files); res.files = decodeDisplayName(res.files);
res.folders = decodeDisplayName(res.folders); res.folders = decodeDisplayName(res.folders);
const { current } = res; res.current.isArchive =
!!res.current.roomType &&
if (current.roomType) { res.current.rootFolderType === FolderType.Archive;
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] = "";
}
}
}
return res; return res;
}); });

View File

@ -15,23 +15,6 @@ export function getRooms(filter) {
if (res.current.rootFolderType === FolderType.Archive) { if (res.current.rootFolderType === FolderType.Archive) {
res.folders.forEach((room) => { res.folders.forEach((room) => {
room.isArchive = true; 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) { export function getRoomInfo(id) {
const options = { const options = {
method: "get", method: "get",
url: `/files/rooms/${id}`, url: `/files/rooms/${id}`,
}; };
return request(options).then(async (res) => { return request(options).then((res) => {
return new Promise((resolve, reject) => { if (res.rootFolderType === FolderType.Archive) res.isArchive = true;
if (res.rootFolderType === FolderType.Archive) {
res.isLogoLoading = false;
res.isArchive = true;
for (let key in res.logo) {
res.logo[key] = "";
}
return resolve(res); return 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);
});
});
}); });
} }

View File

@ -77,13 +77,11 @@ const FilterBlockItem = ({
return !item.isSelected || return !item.isSelected ||
item.selectedKey === "me" || item.selectedKey === "me" ||
item.selectedKey === "other" ? ( item.selectedKey === "other" ? (
<StyledFilterBlockItemSelector key={item.key}> <StyledFilterBlockItemSelector
<SelectorAddButton key={item.key}
onClick={(event) => onClick={(event) => showSelectorAction(event, isAuthor, item.group, [])}
showSelectorAction(event, isAuthor, item.group, []) >
} <SelectorAddButton id="filter_add-author" />
id="filter_add-author"
/>
<StyledFilterBlockItemSelectorText noSelect={true}> <StyledFilterBlockItemSelectorText noSelect={true}>
{item.label} {item.label}
</StyledFilterBlockItemSelectorText> </StyledFilterBlockItemSelectorText>

View File

@ -151,8 +151,8 @@ const StyledFilterBlockItemSelectorText = styled(Text)`
font-size: 13px; font-size: 13px;
line-height: 15px; line-height: 15px;
color: ${(props) => props.theme.filterInput.filter.color}; color: ${(props) => props.theme.filterInput.filter.color};
margin-left: 8px; margin-left: 8px;
cursor: pointer;
`; `;
StyledFilterBlockItemSelectorText.defaultProps = { theme: Base }; StyledFilterBlockItemSelectorText.defaultProps = { theme: Base };

View File

@ -83,11 +83,10 @@ const StyledInfoPanel = styled.div`
const StyledControlContainer = styled.div` const StyledControlContainer = styled.div`
display: none; display: none;
width: 24px; width: 17px;
height: 24px; height: 17px;
position: absolute; position: absolute;
border-radius: 100px;
cursor: pointer; cursor: pointer;
align-items: center; align-items: center;
@ -97,22 +96,22 @@ const StyledControlContainer = styled.div`
@media ${tablet} { @media ${tablet} {
display: flex; display: flex;
top: 16px; top: 18px;
left: -34px; left: -27px;
} }
${isMobile && ${isMobile &&
css` css`
display: flex; display: flex;
top: 16px; top: 18px;
left: -34px; left: -27px;
`} `}
@media (max-width: 428px) { @media (max-width: 428px) {
display: flex; display: flex;
top: -34px; top: -27px;
right: 10px; right: 10px;
left: unset; left: unset;
} }
@ -134,11 +133,14 @@ StyledCrossIcon.defaultProps = { theme: Base };
const InfoPanel = ({ const InfoPanel = ({
children, children,
isVisible, isVisible,
isMobileHidden,
setIsVisible, setIsVisible,
canDisplay, canDisplay,
viewAs, viewAs,
}) => { }) => {
if (!isVisible || !canDisplay) return null; if (!isVisible || !canDisplay) return null;
if ((isTablet() || isMobile || isMobileUtils()) && isMobileHidden)
return null;
const closeInfoPanel = () => setIsVisible(false); const closeInfoPanel = () => setIsVisible(false);
@ -180,13 +182,14 @@ const InfoPanel = ({
); );
const renderPortalInfoPanel = () => { const renderPortalInfoPanel = () => {
console.log(isMobileHidden);
const rootElement = document.getElementById("root"); const rootElement = document.getElementById("root");
return ( return (
<Portal <Portal
element={infoPanelComponent} element={infoPanelComponent}
appendTo={rootElement} appendTo={rootElement}
visible={isVisible} visible={isVisible && !isMobileHidden}
/> />
); );
}; };
@ -208,12 +211,18 @@ StyledInfoPanel.defaultProps = { theme: Base };
InfoPanel.defaultProps = { theme: Base }; InfoPanel.defaultProps = { theme: Base };
export default inject(({ auth }) => { export default inject(({ auth }) => {
const { isVisible, setIsVisible, getCanDisplay } = auth.infoPanelStore; const {
isVisible,
isMobileHidden,
setIsVisible,
getCanDisplay,
} = auth.infoPanelStore;
const canDisplay = getCanDisplay(); const canDisplay = getCanDisplay();
return { return {
isVisible, isVisible,
isMobileHidden,
setIsVisible, setIsVisible,
canDisplay, canDisplay,
}; };

View File

@ -19,6 +19,7 @@ const observedKeys = [
class InfoPanelStore { class InfoPanelStore {
isVisible = false; isVisible = false;
isMobileHidden = false;
selection = null; selection = null;
selectionParentRoom = null; selectionParentRoom = null;
@ -26,6 +27,8 @@ class InfoPanelStore {
roomsView = "info_details"; roomsView = "info_details";
fileView = "info_history"; fileView = "info_history";
updateRoomMembers = null;
authStore = null; authStore = null;
settingsStore = null; settingsStore = null;
peopleStore = null; peopleStore = null;
@ -40,6 +43,7 @@ class InfoPanelStore {
// Setters // Setters
setIsVisible = (bool) => (this.isVisible = bool); setIsVisible = (bool) => (this.isVisible = bool);
setIsMobileHidden = (bool) => (this.isMobileHidden = bool);
setSelection = (selection) => { setSelection = (selection) => {
if (this.getIsAccounts() && (!selection.email || !selection.displayName)) { if (this.getIsAccounts() && (!selection.email || !selection.displayName)) {
@ -57,6 +61,10 @@ class InfoPanelStore {
this.fileView = view === "info_members" ? "info_history" : view; this.fileView = view === "info_members" ? "info_history" : view;
}; };
setUpdateRoomMembers = (updateRoomMembers) => {
this.updateRoomMembers = updateRoomMembers;
};
// Selection helpers // // Selection helpers //
getSelectedItems = () => { getSelectedItems = () => {

View File

@ -78,29 +78,37 @@ const StyledAside = styled(Container)`
StyledAside.defaultProps = { theme: Base }; StyledAside.defaultProps = { theme: Base };
const StyledControlContainer = styled.div` const StyledControlContainer = styled.div`
display: flex; display: none;
width: 24px; width: 17px;
height: 24px; height: 17px;
position: absolute; position: absolute;
border-radius: 100px;
cursor: pointer; cursor: pointer;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 450; z-index: 450;
top: 14px; @media ${tablet} {
left: -34px; display: flex;
top: 18px;
left: -27px;
}
${isMobile && ${isMobile &&
css` css`
top: 14px; display: flex;
top: 18px;
left: -27px;
`} `}
@media (max-width: 428px) { @media (max-width: 428px) {
top: -34px; display: flex;
top: -27px;
right: 10px; right: 10px;
left: unset; left: unset;
} }

View File

@ -110,7 +110,7 @@ public class FolderDtoHelper : FileEntryDtoHelper
result.Tags = folder.Tags.Select(t => t.Name); result.Tags = folder.Tags.Select(t => t.Name);
} }
result.Logo = _roomLogoManager.GetLogo(folder); result.Logo = await _roomLogoManager.GetLogoAsync(folder);
result.RoomType = folder.FolderType switch result.RoomType = folder.FolderType switch
{ {
FolderType.FillingFormsRoom => RoomType.FillingFormsRoom, FolderType.FillingFormsRoom => RoomType.FillingFormsRoom,

View File

@ -35,6 +35,7 @@ public interface IProviderDao
IAsyncEnumerable<IProviderInfo> GetProvidersInfoAsync(Guid userId); IAsyncEnumerable<IProviderInfo> GetProvidersInfoAsync(Guid userId);
Task<int> SaveProviderInfoAsync(string providerKey, string customerTitle, AuthData authData, FolderType folderType); Task<int> SaveProviderInfoAsync(string providerKey, string customerTitle, AuthData authData, FolderType folderType);
Task<bool> UpdateProviderInfoAsync(int linkId, FolderType rootFolderType); 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<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> UpdateProviderInfoAsync(int linkId, string customerTitle, AuthData authData, FolderType folderType, Guid? userId = null);
Task<int> UpdateBackupProviderInfoAsync(string providerKey, string customerTitle, AuthData authData); Task<int> UpdateBackupProviderInfoAsync(string providerKey, string customerTitle, AuthData authData);

View File

@ -446,6 +446,7 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
toUpdate.CreateBy = folder.CreateBy; toUpdate.CreateBy = folder.CreateBy;
toUpdate.ModifiedOn = _tenantUtil.DateTimeToUtc(folder.ModifiedOn); toUpdate.ModifiedOn = _tenantUtil.DateTimeToUtc(folder.ModifiedOn);
toUpdate.ModifiedBy = folder.ModifiedBy; toUpdate.ModifiedBy = folder.ModifiedBy;
toUpdate.HasLogo = folder.HasLogo;
await filesDbContext.SaveChangesAsync(); await filesDbContext.SaveChangesAsync();

View File

@ -42,6 +42,7 @@ public class DbFilesThirdpartyAccount : BaseEntity, IDbFile, IDbSearch
public int TenantId { get; set; } public int TenantId { get; set; }
public string FolderId { get; set; } public string FolderId { get; set; }
public bool Private { get; set; } public bool Private { get; set; }
public bool HasLogo { get; set; }
public override object[] GetKeys() public override object[] GetKeys()
{ {
@ -137,6 +138,8 @@ public static class DbFilesThirdpartyAccountExtension
.UseCollation("utf8_general_ci"); .UseCollation("utf8_general_ci");
entity.Property(e => e.Private).HasColumnName("private"); entity.Property(e => e.Private).HasColumnName("private");
entity.Property(e => e.HasLogo).HasColumnName("has_logo");
}); });
} }
public static void PgSqlAddDbFilesThirdpartyAccount(this ModelBuilder modelBuilder) 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.FolderId).HasColumnName("folder_id");
entity.Property(e => e.Private).HasColumnName("private"); entity.Property(e => e.Private).HasColumnName("private");
entity.Property(e => e.HasLogo).HasColumnName("has_logo");
}); });
} }
} }

View File

@ -44,6 +44,7 @@ public class DbFolder : IDbFile, IDbSearch, ISearchItem
public int FoldersCount { get; set; } public int FoldersCount { get; set; }
public int FilesCount { get; set; } public int FilesCount { get; set; }
public bool Private { get; set; } public bool Private { get; set; }
public bool HasLogo { get; set; }
[Ignore] [Ignore]
public string IndexName => Tables.Folder; public string IndexName => Tables.Folder;
@ -130,6 +131,8 @@ public static class DbFolderExtension
.UseCollation("utf8_general_ci"); .UseCollation("utf8_general_ci");
entity.Property(e => e.Private).HasColumnName("private"); entity.Property(e => e.Private).HasColumnName("private");
entity.Property(e => e.HasLogo).HasColumnName("has_logo");
}); });
} }
public static void PgSqlAddDbFolder(this ModelBuilder modelBuilder) public static void PgSqlAddDbFolder(this ModelBuilder modelBuilder)
@ -178,6 +181,8 @@ public static class DbFolderExtension
.HasMaxLength(400); .HasMaxLength(400);
entity.Property(e => e.Private).HasColumnName("private"); entity.Property(e => e.Private).HasColumnName("private");
entity.Property(e => e.HasLogo).HasColumnName("has_logo");
}); });
} }
} }

View File

@ -73,6 +73,7 @@ public class Folder<T> : FileEntry<T>, IFolder
public string FolderUrl { get; set; } public string FolderUrl { get; set; }
public bool Pinned { get; set; } public bool Pinned { get; set; }
public bool Private { get; set; } public bool Private { get; set; }
public bool HasLogo { get; set; }
public override bool IsNew public override bool IsNew
{ {
get => Convert.ToBoolean(NewForMe); get => Convert.ToBoolean(NewForMe);

View File

@ -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.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.FoldersCount = boxFolder.ItemCollection != null ? boxFolder.ItemCollection.Entries.Count(item => item is BoxFolder) : 0;
folder.Private = ProviderInfo.Private; folder.Private = ProviderInfo.Private;
folder.HasLogo = ProviderInfo.HasLogo;
SetFolderType(folder, isRoot); SetFolderType(folder, isRoot);
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc) if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)

View File

@ -57,6 +57,7 @@ internal class BoxProviderInfo : IProviderInfo
public FolderType FolderType { get; set; } public FolderType FolderType { get; set; }
public string FolderId { get; set; } public string FolderId { get; set; }
public bool Private { get; set; } public bool Private { get; set; }
public bool HasLogo { get; set; }
public string BoxRootId public string BoxRootId
{ {

View File

@ -128,6 +128,7 @@ internal abstract class DropboxDaoBase : ThirdPartyProviderDao<DropboxProviderIn
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : default; folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : default;
folder.Title = MakeFolderTitle(dropboxFolder); folder.Title = MakeFolderTitle(dropboxFolder);
folder.Private = ProviderInfo.Private; folder.Private = ProviderInfo.Private;
folder.HasLogo = ProviderInfo.HasLogo;
SetFolderType(folder, isRoot); SetFolderType(folder, isRoot);
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc) if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)

View File

@ -56,6 +56,7 @@ internal class DropboxProviderInfo : IProviderInfo
public FolderType FolderType { get; set; } public FolderType FolderType { get; set; }
public string FolderId { get; set; } public string FolderId { get; set; }
public bool Private { get; set; } public bool Private { get; set; }
public bool HasLogo { get; set; }
private readonly DropboxStorageDisposableWrapper _wrapper; private readonly DropboxStorageDisposableWrapper _wrapper;
private readonly DropboxProviderInfoHelper _dropboxProviderInfoHelper; private readonly DropboxProviderInfoHelper _dropboxProviderInfoHelper;

View File

@ -140,6 +140,7 @@ internal abstract class GoogleDriveDaoBase : ThirdPartyProviderDao<GoogleDrivePr
folder.CreateOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.CreatedTime ?? default); folder.CreateOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.CreatedTime ?? default);
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.ModifiedTime ?? default); folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.ModifiedTime ?? default);
folder.Private = ProviderInfo.Private; folder.Private = ProviderInfo.Private;
folder.HasLogo = ProviderInfo.HasLogo;
SetFolderType(folder, isRoot); SetFolderType(folder, isRoot);
folder.Title = MakeFolderTitle(driveEntry); folder.Title = MakeFolderTitle(driveEntry);

View File

@ -60,6 +60,7 @@ internal class GoogleDriveProviderInfo : IProviderInfo
public FolderType FolderType { get; set; } public FolderType FolderType { get; set; }
public string FolderId { get; set; } public string FolderId { get; set; }
public bool Private { get; set; } public bool Private { get; set; }
public bool HasLogo { get; set; }
public string DriveRootId public string DriveRootId
{ {
get get

View File

@ -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.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.ModifiedOn = isRoot ? ProviderInfo.CreateOn : (onedriveFolder.LastModifiedDateTime.HasValue ? _tenantUtil.DateTimeFromUtc(onedriveFolder.LastModifiedDateTime.Value.DateTime) : default);
folder.Private = ProviderInfo.Private; folder.Private = ProviderInfo.Private;
folder.HasLogo = ProviderInfo.HasLogo;
SetFolderType(folder, isRoot); SetFolderType(folder, isRoot);
folder.Title = MakeItemTitle(onedriveFolder); folder.Title = MakeItemTitle(onedriveFolder);

View File

@ -57,6 +57,7 @@ internal class OneDriveProviderInfo : IProviderInfo
public FolderType FolderType { get; set; } public FolderType FolderType { get; set; }
public string FolderId { get; set; } public string FolderId { get; set; }
public bool Private { get; set; } public bool Private { get; set; }
public bool HasLogo { get; set; }
private readonly OneDriveStorageDisposableWrapper _wrapper; private readonly OneDriveStorageDisposableWrapper _wrapper;
private readonly OneDriveProviderInfoHelper _oneDriveProviderInfoHelper; private readonly OneDriveProviderInfoHelper _oneDriveProviderInfoHelper;

View File

@ -229,6 +229,26 @@ internal class ProviderAccountDao : IProviderDao
return true; 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) public async Task<bool> UpdateProviderInfoAsync(int linkId, string folderId, FolderType roomType, bool @private)
{ {
using var filesDbContext = _dbContextFactory.CreateDbContext(); using var filesDbContext = _dbContextFactory.CreateDbContext();
@ -496,6 +516,7 @@ internal class ProviderAccountDao : IProviderDao
var folderId = input.FolderId; var folderId = input.FolderId;
var createOn = _tenantUtil.DateTimeFromUtc(input.CreateOn); var createOn = _tenantUtil.DateTimeFromUtc(input.CreateOn);
var authData = new AuthData(input.Url, input.UserName, DecryptPassword(input.Password, id), token); var authData = new AuthData(input.Url, input.UserName, DecryptPassword(input.Password, id), token);
var hasLogo = input.HasLogo;
if (key == ProviderTypes.Box) if (key == ProviderTypes.Box)
{ {
@ -515,6 +536,7 @@ internal class ProviderAccountDao : IProviderDao
box.FolderType = folderType; box.FolderType = folderType;
box.FolderId = folderId; box.FolderId = folderId;
box.Private = privateRoom; box.Private = privateRoom;
box.HasLogo = hasLogo;
return box; return box;
} }
@ -537,6 +559,7 @@ internal class ProviderAccountDao : IProviderDao
drop.FolderType = folderType; drop.FolderType = folderType;
drop.FolderId = folderId; drop.FolderId = folderId;
drop.Private = privateRoom; drop.Private = privateRoom;
drop.HasLogo = hasLogo;
return drop; return drop;
} }
@ -559,6 +582,7 @@ internal class ProviderAccountDao : IProviderDao
sh.FolderType = folderType; sh.FolderType = folderType;
sh.FolderId = folderId; sh.FolderId = folderId;
sh.Private = privateRoom; sh.Private = privateRoom;
sh.HasLogo = hasLogo;
return sh; return sh;
} }
@ -581,6 +605,7 @@ internal class ProviderAccountDao : IProviderDao
gd.FolderType = folderType; gd.FolderType = folderType;
gd.FolderId = folderId; gd.FolderId = folderId;
gd.Private = privateRoom; gd.Private = privateRoom;
gd.HasLogo = hasLogo;
return gd; return gd;
} }
@ -603,6 +628,7 @@ internal class ProviderAccountDao : IProviderDao
od.FolderType = folderType; od.FolderType = folderType;
od.FolderId = folderId; od.FolderId = folderId;
od.Private = privateRoom; od.Private = privateRoom;
od.HasLogo = hasLogo;
return od; return od;
} }
@ -633,6 +659,7 @@ internal class ProviderAccountDao : IProviderDao
sharpBoxProviderInfo.FolderType = folderType; sharpBoxProviderInfo.FolderType = folderType;
sharpBoxProviderInfo.FolderId = folderId; sharpBoxProviderInfo.FolderId = folderId;
sharpBoxProviderInfo.Private = privateRoom; sharpBoxProviderInfo.Private = privateRoom;
sharpBoxProviderInfo.HasLogo = hasLogo;
return sharpBoxProviderInfo; return sharpBoxProviderInfo;
} }

View File

@ -45,6 +45,7 @@ public class SharePointProviderInfo : IProviderInfo
public string SpRootFolderId { get; set; } = "/Shared Documents"; public string SpRootFolderId { get; set; } = "/Shared Documents";
public string FolderId { get; set; } public string FolderId { get; set; }
public bool Private { get; set; } public bool Private { get; set; }
public bool HasLogo { get; set; }
public SharePointProviderInfo( public SharePointProviderInfo(
ILogger<SharePointProviderInfo> logger, ILogger<SharePointProviderInfo> logger,
@ -576,6 +577,7 @@ public class SharePointProviderInfo : IProviderInfo
result.FoldersCount = 0; result.FoldersCount = 0;
result.Error = errorFolder.Error; result.Error = errorFolder.Error;
result.Private = Private; result.Private = Private;
result.HasLogo = HasLogo;
return result; return result;
} }
@ -599,6 +601,7 @@ public class SharePointProviderInfo : IProviderInfo
result.FilesCount = 0; result.FilesCount = 0;
result.FoldersCount = 0; result.FoldersCount = 0;
result.Private = Private; result.Private = Private;
result.HasLogo = HasLogo;
SetFolderType(result, isRoot); SetFolderType(result, isRoot);

View File

@ -310,6 +310,7 @@ internal abstract class SharpBoxDaoBase : ThirdPartyProviderDao<SharpBoxProvider
folder.FilesCount = 0; /*fsEntry.Count - childFoldersCount NOTE: Removed due to performance isssues*/ folder.FilesCount = 0; /*fsEntry.Count - childFoldersCount NOTE: Removed due to performance isssues*/
folder.FoldersCount = 0; /*childFoldersCount NOTE: Removed due to performance isssues*/ folder.FoldersCount = 0; /*childFoldersCount NOTE: Removed due to performance isssues*/
folder.Private = ProviderInfo.Private; folder.Private = ProviderInfo.Private;
folder.HasLogo = ProviderInfo.HasLogo;
SetFolderType(folder, isRoot); SetFolderType(folder, isRoot);
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc) if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)

View File

@ -112,6 +112,7 @@ internal class SharpBoxProviderInfo : IProviderInfo
public FolderType FolderType { get; set; } public FolderType FolderType { get; set; }
public string FolderId { get; set; } public string FolderId { get; set; }
public bool Private { get; set; } public bool Private { get; set; }
public bool HasLogo { get; set; }
private readonly SharpBoxStorageDisposableWrapper _wrapper; private readonly SharpBoxStorageDisposableWrapper _wrapper;
} }

View File

@ -31,16 +31,14 @@ namespace ASC.Files.Core.VirtualRooms;
[Scope] [Scope]
public class RoomLogoManager 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 ModuleName = "room_logos";
private const string TempDomainPath = "logos_temp"; 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 (SizeName, Size) _originalLogoSize = (SizeName.Original, new Size(1280, 1280));
private static Size _largeLogoSize = new Size(96, 96); private static (SizeName, Size) _largeLogoSize = (SizeName.Large, new Size(96, 96));
private static Size _mediumLogoSize = new Size(32, 32); private static (SizeName, Size) _mediumLogoSize = (SizeName.Medium, new Size(32, 32));
private static Size _smallLogoSize = new Size(16, 16); private static (SizeName, Size) _smallLogoSize = (SizeName.Small, new Size(16, 16));
private readonly IDaoFactory _daoFactory; private readonly IDaoFactory _daoFactory;
private readonly FileSecurity _fileSecurity; private readonly FileSecurity _fileSecurity;
@ -48,13 +46,8 @@ public class RoomLogoManager
private readonly StorageFactory _storageFactory; private readonly StorageFactory _storageFactory;
private readonly TenantManager _tenantManager; private readonly TenantManager _tenantManager;
private IDataStore _dataStore; private IDataStore _dataStore;
private readonly ICache _cache;
private readonly FilesMessageService _filesMessageService; 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 IHttpContextAccessor _httpContextAccessor;
private readonly FilesLinkUtility _filesLinkUtility;
public RoomLogoManager( public RoomLogoManager(
StorageFactory storageFactory, StorageFactory storageFactory,
@ -62,20 +55,16 @@ public class RoomLogoManager
IDaoFactory daoFactory, IDaoFactory daoFactory,
FileSecurity fileSecurity, FileSecurity fileSecurity,
ILogger<RoomLogoManager> logger, ILogger<RoomLogoManager> logger,
AscCache cache,
FilesMessageService filesMessageService, FilesMessageService filesMessageService,
IHttpContextAccessor httpContextAccessor, IHttpContextAccessor httpContextAccessor)
FilesLinkUtility filesLinkUtility)
{ {
_storageFactory = storageFactory; _storageFactory = storageFactory;
_tenantManager = tenantManager; _tenantManager = tenantManager;
_daoFactory = daoFactory; _daoFactory = daoFactory;
_fileSecurity = fileSecurity; _fileSecurity = fileSecurity;
_logger = logger; _logger = logger;
_cache = cache;
_filesMessageService = filesMessageService; _filesMessageService = filesMessageService;
_httpContextAccessor = httpContextAccessor; _httpContextAccessor = httpContextAccessor;
_filesLinkUtility = filesLinkUtility;
} }
public bool EnableAudit { get; set; } = true; public bool EnableAudit { get; set; } = true;
@ -108,8 +97,19 @@ public class RoomLogoManager
id = GetId(room); id = GetId(room);
await DeleteLogo(id);
await SaveWithProcessAsync(id, data, -1, new Point(x, y), new Size(width, height)); 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) if (EnableAudit)
{ {
@ -133,14 +133,24 @@ public class RoomLogoManager
try 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) if (EnableAudit)
{ {
_filesMessageService.Send(room, Headers, MessageAction.RoomLogoDeleted); _filesMessageService.Send(room, Headers, MessageAction.RoomLogoDeleted);
} }
} }
catch (DirectoryNotFoundException e) catch (Exception e)
{ {
_logger.ErrorRemoveRoomLogo(e); _logger.ErrorRemoveRoomLogo(e);
} }
@ -148,24 +158,35 @@ public class RoomLogoManager
return room; 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 return new Logo
{ {
Original = GetOriginalLogoUrl(id), Original = string.Empty,
Large = GetLargeLogoUrl(id), Large = string.Empty,
Medium = GetMediumLogoUrl(id), Medium = string.Empty,
Small = GetSmallLogoUrl(id) 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) 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); using var stream = new MemoryStream(data);
var path = await DataStore.SaveAsync(TempDomainPath, fileName, stream); var path = await DataStore.SaveAsync(TempDomainPath, fileName, stream);
@ -182,84 +203,26 @@ public class RoomLogoManager
return pathWithoutQuery; 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);
} }
catch(Exception e)
public string GetLargeLogoUrl<T>(T id)
{ {
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) 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 = string.Format(LogosPath, ProcessFolderId(id), SizeName.Original.ToStringLowerFast());
var fileName = $"{ProcessFolderId(id)}_orig_{width}-{height}.{imageExtension}";
if (imageData == null || imageData.Length == 0) if (imageData == null || imageData.Length == 0)
{ {
@ -276,7 +239,7 @@ public class RoomLogoManager
return path.ToString(); 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) if (data == null || data.Length <= 0)
{ {
@ -293,9 +256,9 @@ public class RoomLogoManager
using var img = Image.Load(stream, out var format); using var img = Image.Load(stream, out var format);
var imgFormat = 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); data = CommonPhotoManager.SaveToBytes(img2);
} }
else else
@ -304,7 +267,7 @@ public class RoomLogoManager
} }
var extension = CommonPhotoManager.GetImgFormatName(imgFormat); 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); using var stream2 = new MemoryStream(data);
await DataStore.SaveAsync(fileName, stream2); 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}" + var fileName = string.Format(LogosPath, ProcessFolderId(id), size.ToStringLowerFast());
$"&{FilesLinkUtility.FolderId}={Uri.EscapeDataString(id.ToString())}" + var uri = await DataStore.GetUriAsync(fileName);
$"&{FilesLinkUtility.Size}={size.ToStringLowerFast()}";
}
private async ValueTask<string> GetLogoPathAsync<T>(T id, Size? size, bool original = false) return uri.ToString();
{
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;
} }
private async Task<byte[]> GetTempAsync(string fileName) private async Task<byte[]> GetTempAsync(string fileName)
@ -364,37 +306,6 @@ public class RoomLogoManager
return data.ToArray(); 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) private string ProcessFolderId<T>(T id)
{ {
ArgumentNullException.ThrowIfNull(id, nameof(id)); ArgumentNullException.ThrowIfNull(id, nameof(id));
@ -404,24 +315,6 @@ public class RoomLogoManager
: id.ToString()?.Replace("-", "").Replace("|", ""); : 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) private T GetId<T>(Folder<T> room)
{ {
return room.ProviderEntry && (room.RootId.ToString().Contains("sbox") return room.ProviderEntry && (room.RootId.ToString().Contains("sbox")
@ -430,7 +323,7 @@ public class RoomLogoManager
} }
[EnumExtensions] [EnumExtensions]
public enum RoomLogoSize public enum SizeName
{ {
Original = 0, Original = 0,
Large = 1, Large = 1,

View File

@ -196,9 +196,6 @@ public class FileHandlerService
case "track": case "track":
await TrackFile(context); await TrackFile(context);
break; break;
case "logo":
await GetRoomLogoPathAsync(context);
break;
default: default:
throw new HttpException((int)HttpStatusCode.BadRequest, FilesCommonResource.ErrorMassage_BadRequest); throw new HttpException((int)HttpStatusCode.BadRequest, FilesCommonResource.ErrorMassage_BadRequest);
} }
@ -1569,60 +1566,6 @@ public class FileHandlerService
await context.Response.WriteAsync(TrackResponse.Serialize(result)); 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 public static class FileHandlerExtensions

View File

@ -30,4 +30,7 @@ public static partial class RoomLogoManagerLogger
{ {
[LoggerMessage(Level = LogLevel.Error, Message = "RemoveRoomLogo")] [LoggerMessage(Level = LogLevel.Error, Message = "RemoveRoomLogo")]
public static partial void ErrorRemoveRoomLogo(this ILogger<RoomLogoManager> logger, Exception exception); 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);
} }