Merge branch 'develop' into feature/fix-hide/show-header
This commit is contained in:
commit
0a64ce38a4
@ -67,7 +67,7 @@ namespace ASC.FederatedLogin.Helpers
|
||||
if (!string.IsNullOrEmpty(redirectUri)) query += "&redirect_uri=" + HttpUtility.UrlEncode(redirectUri);
|
||||
if (!string.IsNullOrEmpty(scope)) query += "&scope=" + HttpUtility.UrlEncode(scope);
|
||||
|
||||
query += "&state=" + HttpUtility.UrlEncode(HttpContextAccessor.HttpContext.Request.GetUrlRewriter().AbsoluteUri) + "/code";
|
||||
query += "&state=" + HttpUtility.UrlEncode(HttpContextAccessor.HttpContext.Request.GetUrlRewriter().AbsoluteUri.TrimEnd('/')) + "/code";
|
||||
|
||||
if (additionalArgs != null)
|
||||
{
|
||||
|
@ -50,7 +50,7 @@ using IsolationLevel = System.Data.IsolationLevel;
|
||||
namespace ASC.MessagingSystem.DbSender
|
||||
{
|
||||
[Singletone(Additional = typeof(MessagesRepositoryExtension))]
|
||||
public class MessagesRepository
|
||||
public class MessagesRepository: IDisposable
|
||||
{
|
||||
private static DateTime lastSave = DateTime.UtcNow;
|
||||
private readonly TimeSpan CacheTime;
|
||||
@ -315,6 +315,19 @@ namespace ASC.MessagingSystem.DbSender
|
||||
|
||||
} while (ids.Any());
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Timer != null)
|
||||
{
|
||||
Timer.Dispose();
|
||||
}
|
||||
|
||||
if (ClearTimer != null)
|
||||
{
|
||||
ClearTimer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MessagesRepositoryExtension
|
||||
|
@ -50,7 +50,7 @@ using Microsoft.Extensions.Options;
|
||||
namespace ASC.Feed.Aggregator
|
||||
{
|
||||
[Singletone(Additional = typeof(FeedAggregatorServiceExtension))]
|
||||
public class FeedAggregatorService : IHostedService
|
||||
public class FeedAggregatorService : IHostedService, IDisposable
|
||||
{
|
||||
private ILog Log { get; set; }
|
||||
private SignalrServiceClient SignalrServiceClient { get; }
|
||||
@ -285,6 +285,19 @@ namespace ASC.Feed.Aggregator
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (aggregateTimer != null)
|
||||
{
|
||||
aggregateTimer.Dispose();
|
||||
}
|
||||
|
||||
if (removeTimer != null)
|
||||
{
|
||||
removeTimer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Scope]
|
||||
|
@ -41,7 +41,7 @@ using Microsoft.Extensions.Options;
|
||||
namespace ASC.Notify
|
||||
{
|
||||
[Singletone]
|
||||
public class NotifyCleaner
|
||||
public class NotifyCleaner : IDisposable
|
||||
{
|
||||
private readonly ILog log;
|
||||
private readonly ManualResetEvent stop = new ManualResetEvent(false);
|
||||
@ -106,6 +106,14 @@ namespace ASC.Notify
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (CancellationTokenSource != null)
|
||||
{
|
||||
CancellationTokenSource.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ using Microsoft.Extensions.Options;
|
||||
namespace ASC.Notify
|
||||
{
|
||||
[Singletone]
|
||||
public class NotifySender
|
||||
public class NotifySender : IDisposable
|
||||
{
|
||||
private readonly ILog log;
|
||||
|
||||
@ -146,6 +146,14 @@ namespace ASC.Notify
|
||||
{
|
||||
log.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (cancellationToken != null)
|
||||
{
|
||||
cancellationToken.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,9 +47,24 @@ namespace ASC.Files.Core
|
||||
Privacy = 13,
|
||||
}
|
||||
|
||||
public interface IFolder
|
||||
{
|
||||
public FolderType FolderType { get; set; }
|
||||
|
||||
public int TotalFiles { get; set; }
|
||||
|
||||
public int TotalSubFolders { get; set; }
|
||||
|
||||
public bool Shareable { get; set; }
|
||||
|
||||
public int NewForMe { get; set; }
|
||||
|
||||
public string FolderUrl { get; set; }
|
||||
}
|
||||
|
||||
[Transient]
|
||||
[DebuggerDisplay("{Title} ({ID})")]
|
||||
public class Folder<T> : FileEntry<T>
|
||||
public class Folder<T> : FileEntry<T>, IFolder
|
||||
{
|
||||
public FolderType FolderType { get; set; }
|
||||
|
||||
|
@ -414,31 +414,31 @@ namespace ASC.Files.Core.Security
|
||||
continue;
|
||||
}
|
||||
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder<T>)e).FolderType == FolderType.Projects)
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((IFolder)e).FolderType == FolderType.Projects)
|
||||
{
|
||||
// Root Projects folder read-only
|
||||
continue;
|
||||
}
|
||||
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder<T>)e).FolderType == FolderType.SHARE)
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((IFolder)e).FolderType == FolderType.SHARE)
|
||||
{
|
||||
// Root Share folder read-only
|
||||
continue;
|
||||
}
|
||||
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder<T>)e).FolderType == FolderType.Recent)
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((IFolder)e).FolderType == FolderType.Recent)
|
||||
{
|
||||
// Recent folder read-only
|
||||
continue;
|
||||
}
|
||||
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder<T>)e).FolderType == FolderType.Favorites)
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((IFolder)e).FolderType == FolderType.Favorites)
|
||||
{
|
||||
// Favorites folder read-only
|
||||
continue;
|
||||
}
|
||||
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((Folder<T>)e).FolderType == FolderType.Templates)
|
||||
if (action != FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder && ((IFolder)e).FolderType == FolderType.Templates)
|
||||
{
|
||||
// Templates folder read-only
|
||||
continue;
|
||||
@ -464,7 +464,7 @@ namespace ASC.Files.Core.Security
|
||||
}
|
||||
|
||||
if (DefaultCommonShare == FileShare.Read && action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder &&
|
||||
((Folder<T>)e).FolderType == FolderType.COMMON)
|
||||
((IFolder)e).FolderType == FolderType.COMMON)
|
||||
{
|
||||
// all can read Common folder
|
||||
result.Add(e);
|
||||
@ -472,7 +472,7 @@ namespace ASC.Files.Core.Security
|
||||
}
|
||||
|
||||
if (action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder &&
|
||||
((Folder<T>)e).FolderType == FolderType.SHARE)
|
||||
((IFolder)e).FolderType == FolderType.SHARE)
|
||||
{
|
||||
// all can read Share folder
|
||||
result.Add(e);
|
||||
@ -480,7 +480,7 @@ namespace ASC.Files.Core.Security
|
||||
}
|
||||
|
||||
if (action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder &&
|
||||
((Folder<T>)e).FolderType == FolderType.Recent)
|
||||
((IFolder)e).FolderType == FolderType.Recent)
|
||||
{
|
||||
// all can read recent folder
|
||||
result.Add(e);
|
||||
@ -488,7 +488,7 @@ namespace ASC.Files.Core.Security
|
||||
}
|
||||
|
||||
if (action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder &&
|
||||
((Folder<T>)e).FolderType == FolderType.Favorites)
|
||||
((IFolder)e).FolderType == FolderType.Favorites)
|
||||
{
|
||||
// all can read favorites folder
|
||||
result.Add(e);
|
||||
@ -496,7 +496,7 @@ namespace ASC.Files.Core.Security
|
||||
}
|
||||
|
||||
if (action == FilesSecurityActions.Read && e.FileEntryType == FileEntryType.Folder &&
|
||||
((Folder<T>)e).FolderType == FolderType.Templates)
|
||||
((IFolder)e).FolderType == FolderType.Templates)
|
||||
{
|
||||
// all can read templates folder
|
||||
result.Add(e);
|
||||
@ -561,7 +561,7 @@ namespace ASC.Files.Core.Security
|
||||
else if (action == FilesSecurityActions.CustomFilter && (e.Access == FileShare.CustomFilter || e.Access == FileShare.ReadWrite)) result.Add(e);
|
||||
else if (action == FilesSecurityActions.Edit && e.Access == FileShare.ReadWrite) result.Add(e);
|
||||
else if (action == FilesSecurityActions.Create && e.Access == FileShare.ReadWrite) result.Add(e);
|
||||
else if (e.Access != FileShare.Restrict && e.CreateBy == userId && (e.FileEntryType == FileEntryType.File || ((Folder<T>)e).FolderType != FolderType.COMMON)) result.Add(e);
|
||||
else if (e.Access != FileShare.Restrict && e.CreateBy == userId && (e.FileEntryType == FileEntryType.File || ((IFolder)e).FolderType != FolderType.COMMON)) result.Add(e);
|
||||
|
||||
if (e.CreateBy == userId) e.Access = FileShare.None; //HACK: for client
|
||||
}
|
||||
@ -740,7 +740,7 @@ namespace ASC.Files.Core.Security
|
||||
|
||||
if (filterType != FilterType.FoldersOnly)
|
||||
{
|
||||
var files = fileDao.GetFilesFiltered(fileIds.Keys.Select(r => r).ToArray(), filterType, subjectGroup, subjectID, searchText, searchInContent);
|
||||
var files = fileDao.GetFilesFiltered(fileIds.Keys.ToArray(), filterType, subjectGroup, subjectID, searchText, searchInContent);
|
||||
|
||||
files.ForEach(x =>
|
||||
{
|
||||
@ -756,7 +756,7 @@ namespace ASC.Files.Core.Security
|
||||
|
||||
if (filterType == FilterType.None || filterType == FilterType.FoldersOnly)
|
||||
{
|
||||
var folders = folderDao.GetFolders(folderIds.Keys.Select(r => r).ToArray(), filterType, subjectGroup, subjectID, searchText, withSubfolders, false);
|
||||
var folders = folderDao.GetFolders(folderIds.Keys.ToArray(), filterType, subjectGroup, subjectID, searchText, withSubfolders, false);
|
||||
|
||||
if (withSubfolders)
|
||||
{
|
||||
@ -776,7 +776,7 @@ namespace ASC.Files.Core.Security
|
||||
|
||||
if (filterType != FilterType.FoldersOnly && withSubfolders)
|
||||
{
|
||||
var filesInSharedFolders = fileDao.GetFiles(folderIds.Keys.Select(r => r).ToArray(), filterType, subjectGroup, subjectID, searchText, searchInContent);
|
||||
var filesInSharedFolders = fileDao.GetFiles(folderIds.Keys.ToArray(), filterType, subjectGroup, subjectID, searchText, searchInContent);
|
||||
filesInSharedFolders = FilterRead(filesInSharedFolders).ToList();
|
||||
entries.AddRange(filesInSharedFolders);
|
||||
entries = entries.Distinct().ToList();
|
||||
@ -814,17 +814,25 @@ namespace ASC.Files.Core.Security
|
||||
return entries.Where(x => string.IsNullOrEmpty(x.Error)).Cast<FileEntry>().ToList();
|
||||
}
|
||||
|
||||
public List<FileEntry<T>> GetPrivacyForMe<T>(FilterType filterType, bool subjectGroup, Guid subjectID, string searchText = "", bool searchInContent = false, bool withSubfolders = false)
|
||||
public List<FileEntry> GetPrivacyForMe(FilterType filterType, bool subjectGroup, Guid subjectID, string searchText = "", bool searchInContent = false, bool withSubfolders = false)
|
||||
{
|
||||
var securityDao = daoFactory.GetSecurityDao<int>();
|
||||
var subjects = GetUserSubjects(AuthContext.CurrentAccount.ID);
|
||||
var records = securityDao.GetShares(subjects);
|
||||
|
||||
var result = new List<FileEntry>();
|
||||
result.AddRange(GetPrivacyForMe<int>(records.Where(r => r.EntryId.GetType() == typeof(int)), subjects, filterType, subjectGroup, subjectID, searchText, searchInContent, withSubfolders));
|
||||
result.AddRange(GetPrivacyForMe<string>(records.Where(r => r.EntryId.GetType() == typeof(string)), subjects, filterType, subjectGroup, subjectID, searchText, searchInContent, withSubfolders));
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<FileEntry<T>> GetPrivacyForMe<T>(IEnumerable<FileShareRecord> records, List<Guid> subjects, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText = "", bool searchInContent = false, bool withSubfolders = false)
|
||||
{
|
||||
var folderDao = daoFactory.GetFolderDao<T>();
|
||||
var fileDao = daoFactory.GetFileDao<T>();
|
||||
var securityDao = daoFactory.GetSecurityDao<T>();
|
||||
var subjects = new List<Guid> { AuthContext.CurrentAccount.ID };
|
||||
|
||||
var records = securityDao.GetShares(subjects);
|
||||
|
||||
var fileIds = new Dictionary<object, FileShare>();
|
||||
var folderIds = new Dictionary<object, FileShare>();
|
||||
var fileIds = new Dictionary<T, FileShare>();
|
||||
var folderIds = new Dictionary<T, FileShare>();
|
||||
|
||||
var recordGroup = records.GroupBy(r => new { r.EntryId, r.EntryType }, (key, group) => new
|
||||
{
|
||||
@ -837,13 +845,13 @@ namespace ASC.Files.Core.Security
|
||||
{
|
||||
if (r.firstRecord.EntryType == FileEntryType.Folder)
|
||||
{
|
||||
if (!folderIds.ContainsKey(r.firstRecord.EntryId))
|
||||
folderIds.Add(r.firstRecord.EntryId, r.firstRecord.Share);
|
||||
if (!folderIds.ContainsKey((T)r.firstRecord.EntryId))
|
||||
folderIds.Add((T)r.firstRecord.EntryId, r.firstRecord.Share);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fileIds.ContainsKey(r.firstRecord.EntryId))
|
||||
fileIds.Add(r.firstRecord.EntryId, r.firstRecord.Share);
|
||||
if (!fileIds.ContainsKey((T)r.firstRecord.EntryId))
|
||||
fileIds.Add((T)r.firstRecord.EntryId, r.firstRecord.Share);
|
||||
}
|
||||
}
|
||||
|
||||
@ -851,7 +859,7 @@ namespace ASC.Files.Core.Security
|
||||
|
||||
if (filterType != FilterType.FoldersOnly)
|
||||
{
|
||||
var files = fileDao.GetFilesFiltered(fileIds.Keys.Select(r => (T)r).ToArray(), filterType, subjectGroup, subjectID, searchText, searchInContent);
|
||||
var files = fileDao.GetFilesFiltered(fileIds.Keys.ToArray(), filterType, subjectGroup, subjectID, searchText, searchInContent);
|
||||
|
||||
files.ForEach(x =>
|
||||
{
|
||||
@ -867,7 +875,7 @@ namespace ASC.Files.Core.Security
|
||||
|
||||
if (filterType == FilterType.None || filterType == FilterType.FoldersOnly)
|
||||
{
|
||||
var folders = folderDao.GetFolders(folderIds.Keys.Select(r => (T)r).ToArray(), filterType, subjectGroup, subjectID, searchText, withSubfolders, false);
|
||||
var folders = folderDao.GetFolders(folderIds.Keys.ToArray(), filterType, subjectGroup, subjectID, searchText, withSubfolders, false);
|
||||
|
||||
if (withSubfolders)
|
||||
{
|
||||
@ -887,7 +895,7 @@ namespace ASC.Files.Core.Security
|
||||
|
||||
if (filterType != FilterType.FoldersOnly && withSubfolders)
|
||||
{
|
||||
var filesInSharedFolders = fileDao.GetFiles(folderIds.Keys.Select(r => (T)r).ToArray(), filterType, subjectGroup, subjectID, searchText, searchInContent);
|
||||
var filesInSharedFolders = fileDao.GetFiles(folderIds.Keys.ToArray(), filterType, subjectGroup, subjectID, searchText, searchInContent);
|
||||
filesInSharedFolders = FilterRead(filesInSharedFolders).ToList();
|
||||
entries.AddRange(filesInSharedFolders);
|
||||
entries = entries.Distinct().ToList();
|
||||
|
@ -131,7 +131,6 @@ namespace ASC.Files.Thirdparty.Box
|
||||
if (Wrapper != null)
|
||||
{
|
||||
Wrapper.Dispose();
|
||||
Wrapper = null;
|
||||
}
|
||||
|
||||
CacheReset();
|
||||
|
@ -35,11 +35,11 @@ using Dropbox.Api.Files;
|
||||
|
||||
namespace ASC.Files.Thirdparty.Dropbox
|
||||
{
|
||||
internal class DropboxStorage
|
||||
internal class DropboxStorage : IDisposable
|
||||
{
|
||||
private OAuth20Token _token;
|
||||
|
||||
private DropboxClient _dropboxClient;
|
||||
private DropboxClient dropboxClient;
|
||||
|
||||
public bool IsOpened { get; private set; }
|
||||
|
||||
@ -52,14 +52,14 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
|
||||
_token = token;
|
||||
|
||||
_dropboxClient = new DropboxClient(_token.AccessToken);
|
||||
dropboxClient = new DropboxClient(_token.AccessToken);
|
||||
|
||||
IsOpened = true;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
_dropboxClient.Dispose();
|
||||
dropboxClient.Dispose();
|
||||
|
||||
IsOpened = false;
|
||||
}
|
||||
@ -73,7 +73,7 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
|
||||
public long GetUsedSpace()
|
||||
{
|
||||
return (long)_dropboxClient.Users.GetSpaceUsageAsync().Result.Used;
|
||||
return (long)dropboxClient.Users.GetSpaceUsageAsync().Result.Used;
|
||||
}
|
||||
|
||||
public FolderMetadata GetFolder(string folderPath)
|
||||
@ -84,7 +84,7 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
}
|
||||
try
|
||||
{
|
||||
return _dropboxClient.Files.GetMetadataAsync(folderPath).Result.AsFolder;
|
||||
return dropboxClient.Files.GetMetadataAsync(folderPath).Result.AsFolder;
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
@ -105,7 +105,7 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
}
|
||||
try
|
||||
{
|
||||
return _dropboxClient.Files.GetMetadataAsync(filePath).Result.AsFile;
|
||||
return dropboxClient.Files.GetMetadataAsync(filePath).Result.AsFile;
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
@ -120,14 +120,14 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
|
||||
public List<Metadata> GetItems(string folderPath)
|
||||
{
|
||||
return new List<Metadata>(_dropboxClient.Files.ListFolderAsync(folderPath).Result.Entries);
|
||||
return new List<Metadata>(dropboxClient.Files.ListFolderAsync(folderPath).Result.Entries);
|
||||
}
|
||||
|
||||
public Stream DownloadStream(string filePath, int offset = 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("file");
|
||||
|
||||
using var response = _dropboxClient.Files.DownloadAsync(filePath).Result;
|
||||
using var response = dropboxClient.Files.DownloadAsync(filePath).Result;
|
||||
var tempBuffer = new FileStream(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read, 8096, FileOptions.DeleteOnClose);
|
||||
using (var str = response.GetContentAsStreamAsync().Result)
|
||||
{
|
||||
@ -144,62 +144,62 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
public FolderMetadata CreateFolder(string title, string parentPath)
|
||||
{
|
||||
var path = MakeDropboxPath(parentPath, title);
|
||||
var result = _dropboxClient.Files.CreateFolderV2Async(path, true).Result;
|
||||
var result = dropboxClient.Files.CreateFolderV2Async(path, true).Result;
|
||||
return result.Metadata;
|
||||
}
|
||||
|
||||
public FileMetadata CreateFile(Stream fileStream, string title, string parentPath)
|
||||
{
|
||||
var path = MakeDropboxPath(parentPath, title);
|
||||
return _dropboxClient.Files.UploadAsync(path, WriteMode.Add.Instance, true, body: fileStream).Result;
|
||||
return dropboxClient.Files.UploadAsync(path, WriteMode.Add.Instance, true, body: fileStream).Result;
|
||||
}
|
||||
|
||||
public void DeleteItem(Metadata dropboxItem)
|
||||
{
|
||||
_dropboxClient.Files.DeleteV2Async(dropboxItem.PathDisplay).Wait();
|
||||
dropboxClient.Files.DeleteV2Async(dropboxItem.PathDisplay).Wait();
|
||||
}
|
||||
|
||||
public FolderMetadata MoveFolder(string dropboxFolderPath, string dropboxFolderPathTo, string folderName)
|
||||
{
|
||||
var pathTo = MakeDropboxPath(dropboxFolderPathTo, folderName);
|
||||
var result = _dropboxClient.Files.MoveV2Async(dropboxFolderPath, pathTo, autorename: true).Result;
|
||||
var result = dropboxClient.Files.MoveV2Async(dropboxFolderPath, pathTo, autorename: true).Result;
|
||||
return (FolderMetadata)result.Metadata;
|
||||
}
|
||||
|
||||
public FileMetadata MoveFile(string dropboxFilePath, string dropboxFolderPathTo, string fileName)
|
||||
{
|
||||
var pathTo = MakeDropboxPath(dropboxFolderPathTo, fileName);
|
||||
var result = _dropboxClient.Files.MoveV2Async(dropboxFilePath, pathTo, autorename: true).Result;
|
||||
var result = dropboxClient.Files.MoveV2Async(dropboxFilePath, pathTo, autorename: true).Result;
|
||||
return (FileMetadata)result.Metadata;
|
||||
}
|
||||
|
||||
public FolderMetadata CopyFolder(string dropboxFolderPath, string dropboxFolderPathTo, string folderName)
|
||||
{
|
||||
var pathTo = MakeDropboxPath(dropboxFolderPathTo, folderName);
|
||||
var result = _dropboxClient.Files.CopyV2Async(dropboxFolderPath, pathTo, autorename: true).Result;
|
||||
var result = dropboxClient.Files.CopyV2Async(dropboxFolderPath, pathTo, autorename: true).Result;
|
||||
return (FolderMetadata)result.Metadata;
|
||||
}
|
||||
|
||||
public FileMetadata CopyFile(string dropboxFilePath, string dropboxFolderPathTo, string fileName)
|
||||
{
|
||||
var pathTo = MakeDropboxPath(dropboxFolderPathTo, fileName);
|
||||
var result = _dropboxClient.Files.CopyV2Async(dropboxFilePath, pathTo, autorename: true).Result;
|
||||
var result = dropboxClient.Files.CopyV2Async(dropboxFilePath, pathTo, autorename: true).Result;
|
||||
return (FileMetadata)result.Metadata;
|
||||
}
|
||||
|
||||
public FileMetadata SaveStream(string filePath, Stream fileStream)
|
||||
{
|
||||
return _dropboxClient.Files.UploadAsync(filePath, WriteMode.Overwrite.Instance, body: fileStream).Result.AsFile;
|
||||
return dropboxClient.Files.UploadAsync(filePath, WriteMode.Overwrite.Instance, body: fileStream).Result.AsFile;
|
||||
}
|
||||
|
||||
public string CreateResumableSession()
|
||||
{
|
||||
return _dropboxClient.Files.UploadSessionStartAsync(body: new MemoryStream()).Result.SessionId;
|
||||
return dropboxClient.Files.UploadSessionStartAsync(body: new MemoryStream()).Result.SessionId;
|
||||
}
|
||||
|
||||
public void Transfer(string dropboxSession, long offset, Stream stream)
|
||||
{
|
||||
_dropboxClient.Files.UploadSessionAppendV2Async(new UploadSessionCursor(dropboxSession, (ulong)offset), body: stream).Wait();
|
||||
dropboxClient.Files.UploadSessionAppendV2Async(new UploadSessionCursor(dropboxSession, (ulong)offset), body: stream).Wait();
|
||||
}
|
||||
|
||||
public Metadata FinishResumableSession(string dropboxSession, string dropboxFolderPath, string fileName, long offset)
|
||||
@ -210,10 +210,18 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
|
||||
public Metadata FinishResumableSession(string dropboxSession, string dropboxFilePath, long offset)
|
||||
{
|
||||
return _dropboxClient.Files.UploadSessionFinishAsync(
|
||||
return dropboxClient.Files.UploadSessionFinishAsync(
|
||||
new UploadSessionCursor(dropboxSession, (ulong)offset),
|
||||
new CommitInfo(dropboxFilePath, WriteMode.Overwrite.Instance),
|
||||
new MemoryStream()).Result;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (dropboxClient != null)
|
||||
{
|
||||
dropboxClient.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -144,7 +144,6 @@ namespace ASC.Files.Thirdparty.GoogleDrive
|
||||
if (Wrapper != null)
|
||||
{
|
||||
Wrapper.Dispose();
|
||||
Wrapper = null;
|
||||
}
|
||||
|
||||
CacheReset();
|
||||
|
@ -60,7 +60,7 @@ using MimeMapping = ASC.Common.Web.MimeMapping;
|
||||
namespace ASC.Files.Thirdparty.GoogleDrive
|
||||
{
|
||||
[Scope]
|
||||
internal class GoogleDriveStorage
|
||||
internal class GoogleDriveStorage : IDisposable
|
||||
{
|
||||
public GoogleDriveStorage(
|
||||
ConsumerFactory consumerFactory,
|
||||
@ -475,7 +475,15 @@ namespace ASC.Files.Thirdparty.GoogleDrive
|
||||
var about = request.Execute();
|
||||
|
||||
return about.MaxUploadSize ?? MaxChunkedUploadFileSize;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_driveService != null)
|
||||
{
|
||||
_driveService.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ResumableUploadSessionStatus
|
||||
|
@ -115,7 +115,6 @@ namespace ASC.Files.Thirdparty.OneDrive
|
||||
if (Wrapper != null)
|
||||
{
|
||||
Wrapper.Dispose();
|
||||
Wrapper = null;
|
||||
}
|
||||
|
||||
CacheReset();
|
||||
|
@ -217,7 +217,9 @@ namespace ASC.Files.Thirdparty
|
||||
Url = authData.Url ?? ""
|
||||
};
|
||||
|
||||
return FilesDbContext.AddOrUpdate(r => r.ThirdpartyAccount, dbFilesThirdpartyAccount).Id;
|
||||
var res = FilesDbContext.AddOrUpdate(r => r.ThirdpartyAccount, dbFilesThirdpartyAccount);
|
||||
FilesDbContext.SaveChanges();
|
||||
return res.Id;
|
||||
}
|
||||
|
||||
public bool CheckProviderInfo(IProviderInfo providerInfo)
|
||||
|
@ -52,7 +52,9 @@ namespace ASC.Files.Thirdparty.ProviderDao
|
||||
|
||||
public Folder<string> GetFolder(string folderId)
|
||||
{
|
||||
var selector = GetSelector(folderId);
|
||||
var selector = GetSelector(folderId);
|
||||
if (selector == null) return null;
|
||||
|
||||
var folderDao = selector.GetFolderDao(folderId);
|
||||
var result = folderDao.GetFolder(selector.ConvertId(folderId));
|
||||
|
||||
|
@ -95,7 +95,6 @@ namespace ASC.Files.Thirdparty.SharePoint
|
||||
if (clientContext != null)
|
||||
{
|
||||
clientContext.Dispose();
|
||||
clientContext = null;
|
||||
}
|
||||
|
||||
SharePointProviderInfoHelper.Invalidate();
|
||||
|
@ -116,7 +116,6 @@ namespace ASC.Files.Thirdparty.Sharpbox
|
||||
if (Wrapper != null)
|
||||
{
|
||||
Wrapper.Dispose();
|
||||
Wrapper = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,8 +366,8 @@ namespace ASC.Web.Files.Utils
|
||||
}
|
||||
}
|
||||
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalFiles : 1));
|
||||
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalSubFolders + 1 : 0));
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalFiles : 1));
|
||||
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalSubFolders + 1 : 0));
|
||||
}
|
||||
else if (parent.FolderType == FolderType.SHARE)
|
||||
{
|
||||
@ -376,8 +376,8 @@ namespace ASC.Web.Files.Utils
|
||||
|
||||
entries = entries.Concat(shared);
|
||||
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalFiles : 1));
|
||||
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalSubFolders + 1 : 0));
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalFiles : 1));
|
||||
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalSubFolders + 1 : 0));
|
||||
}
|
||||
else if (parent.FolderType == FolderType.Recent)
|
||||
{
|
||||
@ -385,7 +385,7 @@ namespace ASC.Web.Files.Utils
|
||||
var files = GetRecent(fileDao, filter, subjectGroup, subjectId, searchText, searchInContent);
|
||||
entries = entries.Concat(files);
|
||||
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalFiles : 1));
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalFiles : 1));
|
||||
}
|
||||
else if (parent.FolderType == FolderType.Favorites)
|
||||
{
|
||||
@ -397,8 +397,8 @@ namespace ASC.Web.Files.Utils
|
||||
entries = entries.Concat(folders);
|
||||
entries = entries.Concat(files);
|
||||
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalFiles : 1));
|
||||
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalSubFolders + 1 : 0));
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalFiles : 1));
|
||||
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalSubFolders + 1 : 0));
|
||||
}
|
||||
else if (parent.FolderType == FolderType.Templates)
|
||||
{
|
||||
@ -406,7 +406,7 @@ namespace ASC.Web.Files.Utils
|
||||
var files = GetTemplates(fileDao, filter, subjectGroup, subjectId, searchText, searchInContent);
|
||||
entries = entries.Concat(files);
|
||||
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalFiles : 1));
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalFiles : 1));
|
||||
parent.TotalSubFolders = 0;
|
||||
}
|
||||
else if (parent.FolderType == FolderType.Privacy)
|
||||
@ -422,12 +422,12 @@ namespace ASC.Web.Files.Utils
|
||||
entries = entries.Concat(files);
|
||||
|
||||
//share
|
||||
var shared = (IEnumerable<FileEntry<T>>)fileSecurity.GetPrivacyForMe<T>(filter, subjectGroup, subjectId, searchText, searchInContent, withSubfolders);
|
||||
var shared = fileSecurity.GetPrivacyForMe(filter, subjectGroup, subjectId, searchText, searchInContent, withSubfolders);
|
||||
|
||||
entries = entries.Concat(shared);
|
||||
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalFiles : 1));
|
||||
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((Folder<T>)f).TotalSubFolders + 1 : 0));
|
||||
parent.TotalFiles = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalFiles : 1));
|
||||
parent.TotalSubFolders = entries.Aggregate(0, (a, f) => a + (f.FileEntryType == FileEntryType.Folder ? ((IFolder)f).TotalSubFolders + 1 : 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ using SecurityContext = ASC.Core.SecurityContext;
|
||||
namespace ASC.Web.Files.Utils
|
||||
{
|
||||
[Singletone(Additional = typeof(FileConverterQueueExtension))]
|
||||
internal class FileConverterQueue<T>
|
||||
internal class FileConverterQueue<T> : IDisposable
|
||||
{
|
||||
private readonly object singleThread = new object();
|
||||
private readonly IDictionary<File<T>, ConvertFileOperationResult> conversionQueue;
|
||||
@ -398,7 +398,15 @@ namespace ASC.Web.Files.Utils
|
||||
FolderTitle = folderTitle ?? "",
|
||||
FileJson = JsonSerializer.Serialize(file, options)
|
||||
}, options);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (timer != null)
|
||||
{
|
||||
timer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Scope]
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "asc-web-common",
|
||||
"version": "1.0.275",
|
||||
"version": "1.0.276",
|
||||
"description": "Ascensio System SIA common components and solutions library",
|
||||
"license": "AGPL-3.0",
|
||||
"files": [
|
||||
|
@ -110,6 +110,7 @@ class FilterInput extends React.Component {
|
||||
openFilterItems: [],
|
||||
hiddenFilterItems: [],
|
||||
needUpdateFilter: false,
|
||||
asideView: false,
|
||||
};
|
||||
|
||||
this.searchWrapper = React.createRef();
|
||||
@ -454,6 +455,14 @@ class FilterInput extends React.Component {
|
||||
? sectionWidth - filterWidth - comboBoxWidth - sectionPaddings
|
||||
: fullWidth - filterWidth;
|
||||
|
||||
if (searchWidth) {
|
||||
const asideView = searchWidth && searchWidth < 350;
|
||||
|
||||
this.setState({
|
||||
asideView,
|
||||
});
|
||||
}
|
||||
|
||||
const filterArr = Array.from(
|
||||
Array.from(this.filterWrapper.current.children).find(
|
||||
(x) => x.id === "filter-items-container"
|
||||
@ -740,6 +749,8 @@ class FilterInput extends React.Component {
|
||||
hiddenFilterItems,
|
||||
sortId,
|
||||
sortDirection,
|
||||
asideView,
|
||||
needUpdateFilter,
|
||||
} = this.state;
|
||||
|
||||
const smallSectionWidth = sectionWidth ? sectionWidth < 900 : false;
|
||||
@ -795,7 +806,8 @@ class FilterInput extends React.Component {
|
||||
onFilterRender={this.onFilterRender}
|
||||
isDisabled={isDisabled}
|
||||
columnCount={filterColumnCount}
|
||||
needUpdateFilter={this.state.needUpdateFilter}
|
||||
needUpdateFilter={needUpdateFilter}
|
||||
asideView={asideView}
|
||||
/>
|
||||
</div>
|
||||
</SearchInput>
|
||||
@ -831,7 +843,7 @@ class FilterInput extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
FilterInput.protoTypes = {
|
||||
FilterInput.propTypes = {
|
||||
size: PropTypes.oneOf(["base", "middle", "big", "huge"]),
|
||||
autoRefresh: PropTypes.bool,
|
||||
selectedFilterData: PropTypes.object,
|
||||
@ -841,7 +853,7 @@ FilterInput.protoTypes = {
|
||||
className: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
needForUpdate: PropTypes.bool,
|
||||
needForUpdate: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
|
||||
filterColumnCount: PropTypes.number,
|
||||
onChangeViewAs: PropTypes.func,
|
||||
contextMenuHeader: PropTypes.string,
|
||||
|
@ -95,6 +95,7 @@ const StyledFilterInput = styled.div`
|
||||
|
||||
.dropdown-style {
|
||||
position: relative;
|
||||
z-index: 190;
|
||||
|
||||
.drop-down {
|
||||
padding: 16px;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from "react";
|
||||
import FilterButton from "./FilterButton";
|
||||
import HideFilter from "./HideFilter";
|
||||
import throttle from "lodash/throttle";
|
||||
import { ComboBox } from "asc-web-components";
|
||||
import CloseButton from "./CloseButton";
|
||||
import isEqual from "lodash/isEqual";
|
||||
@ -160,6 +159,7 @@ class FilterItem extends React.Component {
|
||||
defaultOptionLabel,
|
||||
groupsCaption,
|
||||
defaultOption,
|
||||
asideView,
|
||||
} = this.props;
|
||||
return (
|
||||
<StyledFilterItem key={id} id={id} block={block} opened={opened}>
|
||||
@ -186,6 +186,7 @@ class FilterItem extends React.Component {
|
||||
isMultiSelect={false}
|
||||
onCancel={this.onCancelSelector}
|
||||
onSelect={this.onSelectGroup}
|
||||
displayType={asideView ? "aside" : "auto"}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@ -213,6 +214,7 @@ class FilterItem extends React.Component {
|
||||
defaultOptionLabel={defaultOptionLabel}
|
||||
onCancel={this.onCancelSelector}
|
||||
onSelect={this.onSelectGroup}
|
||||
displayType={asideView ? "aside" : "auto"}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@ -329,6 +331,7 @@ class FilterBlock extends React.Component {
|
||||
};
|
||||
getFilterItems = () => {
|
||||
const { openFilterItems, hiddenFilterItems } = this.state;
|
||||
const { asideView } = this.props;
|
||||
const _this = this;
|
||||
let result = [];
|
||||
let openItems = [];
|
||||
@ -368,6 +371,7 @@ class FilterBlock extends React.Component {
|
||||
defaultSelectLabel={defaultSelectLabel}
|
||||
selectedItem={selectedItem}
|
||||
onFilterRender={_this.props.onFilterRender}
|
||||
asideView={asideView}
|
||||
></FilterItem>
|
||||
);
|
||||
});
|
||||
@ -409,6 +413,7 @@ class FilterBlock extends React.Component {
|
||||
defaultSelectLabel={defaultSelectLabel}
|
||||
selectedItem={selectedItem}
|
||||
onFilterRender={_this.props.onFilterRender}
|
||||
asideView={asideView}
|
||||
></FilterItem>
|
||||
);
|
||||
});
|
||||
@ -454,7 +459,7 @@ class FilterBlock extends React.Component {
|
||||
const _this = this;
|
||||
const filterItems = this.getFilterItems();
|
||||
const filterData = this.props.getFilterData();
|
||||
const { iconSize, isDisabled, contextMenuHeader } = this.props;
|
||||
const { iconSize, isDisabled, contextMenuHeader, asideView } = this.props;
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
@ -472,6 +477,7 @@ class FilterBlock extends React.Component {
|
||||
getData={_this.getData}
|
||||
isDisabled={isDisabled}
|
||||
asideHeader={contextMenuHeader}
|
||||
asideView={asideView}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
@ -488,6 +494,7 @@ FilterBlock.propTypes = {
|
||||
openFilterItems: PropTypes.array,
|
||||
columnCount: PropTypes.number,
|
||||
contextMenuHeader: PropTypes.string,
|
||||
asideView: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default FilterBlock;
|
||||
|
@ -11,6 +11,7 @@ class FilterButton extends React.PureComponent {
|
||||
iconSize,
|
||||
columnCount,
|
||||
asideHeader,
|
||||
asideView,
|
||||
} = this.props;
|
||||
//console.log('render FilterButton)
|
||||
return (
|
||||
@ -26,7 +27,7 @@ class FilterButton extends React.PureComponent {
|
||||
size={iconSize}
|
||||
title="Actions"
|
||||
columnCount={columnCount}
|
||||
displayType="auto"
|
||||
displayType={asideView ? "aside" : "auto"}
|
||||
asideHeader={asideHeader}
|
||||
></ContextMenuButton>
|
||||
);
|
||||
@ -39,5 +40,6 @@ FilterButton.propTypes = {
|
||||
isDisabled: PropTypes.bool,
|
||||
columnCount: PropTypes.number,
|
||||
asideHeader: PropTypes.string,
|
||||
asideView: PropTypes.bool,
|
||||
};
|
||||
export default FilterButton;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "asc-web-components",
|
||||
"version": "1.0.484",
|
||||
"version": "1.0.485",
|
||||
"description": "Ascensio System SIA component library",
|
||||
"license": "AGPL-3.0",
|
||||
"main": "dist/asc-web-components.js",
|
||||
|
@ -49,8 +49,8 @@ const Body = styled.div`
|
||||
margin-top: 17px;
|
||||
}
|
||||
|
||||
.context-menu-button_link-header{
|
||||
text-transform:uppercase;
|
||||
.context-menu-button_link-header {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.context-menu-button_link-header:not(:first-child) {
|
||||
@ -98,6 +98,8 @@ class ContextMenuButton extends React.Component {
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.throttledResize);
|
||||
window.removeEventListener("popstate", this.popstate, false);
|
||||
this.throttledResize.cancel();
|
||||
}
|
||||
|
||||
stopAction = (e) => e.preventDefault();
|
||||
@ -152,7 +154,8 @@ class ContextMenuButton extends React.Component {
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (
|
||||
this.props.opened === nextProps.opened &&
|
||||
this.state.isOpen === nextState.isOpen
|
||||
this.state.isOpen === nextState.isOpen &&
|
||||
this.props.displayType === nextProps.displayType
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
@ -88,7 +88,6 @@ class IconButton extends React.PureComponent {
|
||||
iconHoverName,
|
||||
iconName,
|
||||
color,
|
||||
onClick,
|
||||
onMouseUp,
|
||||
} = this.props;
|
||||
|
||||
@ -103,7 +102,6 @@ class IconButton extends React.PureComponent {
|
||||
currentIconColor: iconHoverName || color,
|
||||
});
|
||||
|
||||
onClick && onClick(e);
|
||||
onMouseUp && onMouseUp(e);
|
||||
break;
|
||||
case 3: //Right click
|
||||
@ -113,6 +111,12 @@ class IconButton extends React.PureComponent {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onClick = (e) => {
|
||||
const { onClick } = this.props;
|
||||
onClick && onClick(e);
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { iconName, color } = this.props;
|
||||
|
||||
@ -150,6 +154,7 @@ class IconButton extends React.PureComponent {
|
||||
onMouseLeave={this.onMouseLeave}
|
||||
onMouseDown={this.onMouseDown}
|
||||
onMouseUp={this.onMouseUp}
|
||||
onClick={this.onClick}
|
||||
isClickable={typeof onClick === "function" || isClickable}
|
||||
data-tip={dataTip}
|
||||
data-event="click focus"
|
||||
|
@ -24,7 +24,7 @@ const Dot = styled.div`
|
||||
animation-delay: ${(props) => props.delay};
|
||||
`;
|
||||
|
||||
Dot.protoTypes = {
|
||||
Dot.propTypes = {
|
||||
delay: PropTypes.string.isRequired,
|
||||
color: PropTypes.string.isRequired,
|
||||
size: PropTypes.number.isRequired,
|
||||
|
@ -69,7 +69,7 @@ const Romb = styled.div`
|
||||
2s ease-in-out 0s infinite;
|
||||
`;
|
||||
|
||||
Romb.protoTypes = {
|
||||
Romb.propTypes = {
|
||||
width: PropTypes.string.isRequired,
|
||||
height: PropTypes.string.isRequired,
|
||||
};
|
||||
@ -83,7 +83,7 @@ const Rombs = ({ size }) => (
|
||||
</>
|
||||
);
|
||||
|
||||
Rombs.protoTypes = {
|
||||
Rombs.propTypes = {
|
||||
size: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user