I don't know, media shit, does not work

This commit is contained in:
2020-11-25 14:01:55 +01:00
parent aa7d2dbea9
commit d6ca934883
14 changed files with 149 additions and 68 deletions
+76 -4
View File
@@ -7,6 +7,7 @@ using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
@@ -20,6 +21,9 @@ namespace zero.Core.Collections
{
public class MediaCollection : CollectionBase<IMedia>, IMediaCollection
{
private IAsyncDocumentSession _coreSession;
public MediaCollection(IZeroContext context, ICollectionInterceptorHandler interceptor, IValidator<IMedia> validator, IPaths paths) : base(context, interceptor, validator)
{
PreSave = model => model.IsActive = true;
@@ -27,6 +31,24 @@ namespace zero.Core.Collections
}
/// <summary>
/// Create an an async document session
/// </summary>
protected IAsyncDocumentSession CoreSession
{
get
{
if (_coreSession != null)
{
return _coreSession;
}
_coreSession = Store.OpenCoreSession();
_coreSession.Advanced.WaitForIndexesAfterSaveChanges(throwOnTimeout: false);
return _coreSession;
}
}
protected const char PATH_SEPARATOR = '/';
protected const string PATH_PREFIX = "/uploads";
@@ -40,13 +62,49 @@ namespace zero.Core.Collections
protected IPaths Paths { get; set; }
public override Task<IMedia> GetById(string id)
{
ApplyScopeBasedOnId(id);
return base.GetById(id);
}
public override async Task<Dictionary<string, IMedia>> GetByIds(params string[] ids)
{
string[] localIds = ids.Where(x => !x.StartsWith(Constants.Database.CoreIdPrefix)).ToArray();
string[] coreIds = ids.Except(localIds).ToArray();
Dictionary<string, IMedia> result = new Dictionary<string, IMedia>();
Dictionary<string, IMedia> models = null;
if (localIds.Length > 0)
{
models = await Session.LoadAsync<IMedia>(localIds);
foreach (string id in localIds)
{
models.TryGetValue(id, out IMedia model);
result.Add(id, model);
}
}
if (coreIds.Length > 0)
{
models = await CoreSession.LoadAsync<IMedia>(coreIds);
foreach (string id in coreIds)
{
models.TryGetValue(id, out IMedia model);
result.Add(id, model);
}
}
return result;
}
/// <inheritdoc />
public async Task<string> GetSourceById(string id, bool thumb = false)
{
if (id.StartsWith(Constants.Database.CoreIdPrefix))
{
ApplyScope("shared");
}
ApplyScopeBasedOnId(id);
IMedia media = await Session.LoadAsync<IMedia>(id);
if (media == null)
@@ -66,6 +124,8 @@ namespace zero.Core.Collections
/// <inheritdoc />
public async Task<ListResult<IMedia>> GetByQuery(MediaListQuery query)
{
ApplyScopeBasedOnId(query.FolderId);
query.SearchFor(entity => entity.Name);
return await Query
@@ -195,6 +255,18 @@ namespace zero.Core.Collections
}
/// <summary>
/// Applies the shared scope when an ID is prefixed with core.
/// </summary>
void ApplyScopeBasedOnId(string id)
{
if (!id.IsNullOrWhiteSpace() && id.StartsWith(Constants.Database.CoreIdPrefix, StringComparison.InvariantCultureIgnoreCase))
{
ApplyScope("shared");
}
}
/// <summary>
/// Saves a thumbnail of an image
/// </summary>
+14
View File
@@ -0,0 +1,14 @@
namespace zero.Core.Entities
{
/// <summary>
/// By default most entities are app aware and stored in their own database context.
/// Exceptions (like media) are stored in the core database and need to be marked as app aware
/// </summary>
public interface IAppAwareEntity
{
/// <summary>
/// Associated app id of the entity
/// </summary>
string AppId { get; set; }
}
}
+4 -9
View File
@@ -6,6 +6,9 @@ namespace zero.Core.Entities
/// <inheritdoc />
public class Media : ZeroEntity, IMedia
{
/// <inheritdoc />
public string AppId { get; set; }
/// <inheritdoc />
public string FileId { get; set; }
@@ -38,9 +41,6 @@ namespace zero.Core.Entities
/// <inheritdoc />
public MediaType Type { get; set; }
/// <inheritdoc />
public bool IsCore { get; set; }
}
@@ -48,7 +48,7 @@ namespace zero.Core.Entities
/// A media file (can contain an image or other media like videos and documents)
/// </summary>
[Collection("Media", LongId = true)]
public interface IMedia : IZeroEntity, IZeroDbConventions
public interface IMedia : IZeroEntity, IZeroDbConventions, IAppAwareEntity
{
/// <summary>
/// Id/name of the phyiscal folder which is stored on disk/cloud
@@ -104,10 +104,5 @@ namespace zero.Core.Entities
/// Type of the media
/// </summary>
MediaType Type { get; set; }
/// <summary>
/// Whether this media item is part of the core database (for multi-tenant setup)
/// </summary>
bool IsCore { get; set; }
}
}
+3 -8
View File
@@ -6,10 +6,10 @@ namespace zero.Core.Entities
public class MediaFolder : ZeroEntity, IMediaFolder
{
/// <inheritdoc />
public string ParentId { get; set; }
public string AppId { get; set; }
/// <inheritdoc />
public bool IsCore { get; set; }
public string ParentId { get; set; }
}
@@ -17,16 +17,11 @@ namespace zero.Core.Entities
/// A media folder contains media and other folders
/// </summary>
[Collection("MediaFolders", LongId = true)]
public interface IMediaFolder : IZeroEntity, IZeroDbConventions
public interface IMediaFolder : IZeroEntity, IZeroDbConventions, IAppAwareEntity
{
/// <summary>
/// Parent folder id
/// </summary>
string ParentId { get; set; }
/// <summary>
/// Whether this media folder is part of the core database (for multi-tenant setup)
/// </summary>
bool IsCore { get; set; }
}
}
@@ -30,22 +30,16 @@ namespace zero.Core.Extensions
store.Conventions.RegisterAsyncIdConvention<IZeroEntity>((_, entity) =>
{
string prefix = String.Empty;
string guid = IdGenerator.Create();
string collection = store.Conventions.GetCollectionName(entity);
//CollectionAttribute collectionAttribute = entity.GetType().GetCustomAttribute<CollectionAttribute>(true);
if ((entity is IMedia && ((IMedia)entity).IsCore) || (entity is IMediaFolder && ((IMediaFolder)entity).IsCore))
{
prefix = Constants.Database.CoreIdPrefix;
}
if (entity is IBackofficeUser or IBackofficeUserRole)
{
guid = IdGenerator.Create(8);
}
string tag = store.Conventions.TransformTypeCollectionNameToDocumentIdPrefix(collection);
return Task.FromResult(prefix + tag + store.Conventions.IdentityPartsSeparator + guid);
return Task.FromResult(tag + store.Conventions.IdentityPartsSeparator + guid);
});
store.Conventions.RegisterAsyncIdConvention<IPage>((_, entity) =>
+1 -10
View File
@@ -93,17 +93,8 @@ namespace zero.Core.Routing
return routes;
}
List<IRoute> allRoutes = new List<IRoute>();
IList<IPage> pages = await session.Query<IPage>().ToListAsync();
//IEnumerable<IGrouping<string, IPage>> groupedPages = pages. pages.GroupBy(x => x.AppId);
//foreach (var group in groupedPages)
//{
IList<IRoute> routes = TraversePageChildren(null, new List<IPage>() { }, pages);
allRoutes.AddRange(routes);
//}
return allRoutes;
return TraversePageChildren(null, new List<IPage>() { }, pages);
}
+25 -18
View File
@@ -161,31 +161,38 @@ namespace zero.Core.Routing
{
int count = 0;
List<IRoute> all = new List<IRoute>();
using IAsyncDocumentSession session = Store.OpenAsyncSession();
session.Advanced.MaxNumberOfRequestsPerSession = 1000;
foreach (IRouteProvider provider in Providers)
using IAsyncDocumentSession coreSession = Store.OpenCoreSession();
List<IApplication> apps = await coreSession.Query<IApplication>().ToListAsync();
foreach (IApplication app in apps)
{
// get all routes for this provider
IList<IRoute> routes = await provider.GetAllRoutes(session);
using IAsyncDocumentSession session = Store.OpenAsyncSession(app.Database);
session.Advanced.MaxNumberOfRequestsPerSession = 1000;
// delete all registered routes in the database for this provider
await Store.PurgeAsync<IRoute>(null, $"where {nameof(IRoute.ProviderAlias)} = $alias", new Raven.Client.Parameters()
foreach (IRouteProvider provider in Providers)
{
{ "alias", provider.Alias }
});
// get all routes for this provider
IList<IRoute> routes = await provider.GetAllRoutes(session);
// store new routes
using (BulkInsertOperation bulkInsert = Store.BulkInsert())
{
foreach (IRoute route in routes)
// delete all registered routes in the database for this provider
await Store.PurgeAsync<IRoute>(app.Database, $"where {nameof(IRoute.ProviderAlias)} = $alias", new Raven.Client.Parameters()
{
await bulkInsert.StoreAsync(route, route.Id);
count += 1;
}
}
{ "alias", provider.Alias }
});
all.AddRange(routes);
// store new routes
using (BulkInsertOperation bulkInsert = Store.BulkInsert(app.Database))
{
foreach (IRoute route in routes)
{
await bulkInsert.StoreAsync(route, route.Id);
count += 1;
}
}
all.AddRange(routes);
}
}
return all;
@@ -155,7 +155,7 @@
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
max-width: 300px;
max-width: 100%;
&.has-icon
{
+2 -1
View File
@@ -714,7 +714,8 @@
}
.ui-pick-preview + .ui-pick-preview,
.ui-pick-previews + .ui-select-button
.ui-pick-previews + .ui-select-button,
.ui-pick-previews + .ui-pick-add
{
margin-top: 10px;
}
+1 -1
View File
@@ -90,7 +90,7 @@ a.app-nav-item, button.app-nav-item
.app-nav-item-icon
{
color: var(--color-text);
color: var(--color-primary);
}
.app-nav-item-arrow
+1 -1
View File
@@ -7,5 +7,5 @@
--padding-l: 64px;
--height-top: 74px;
--radius: 3px;
--radius: 5px;
}
+1 -1
View File
@@ -3,7 +3,7 @@
{
--shadow: 0 3px 20px rgba(0, 0, 0, 0.07);
--shadow-mid: 0 1px 12px rgba(0, 0, 0, 0.03);
--shadow-short: 0.5px 0.5px 1.5px 0 rgba(0, 0, 0, 0.06);
--shadow-short: 0.5px 0.5px 2px 0 rgba(0, 0, 0, 0.07);
//--shadow-dropdown: rgba(0, 0, 0, 0.15);
--shadow-dropdown: 3px 6px 15px rgba(0, 0, 0, 0.07);
--shadow-overlay: -30px 0 40px rgba(0, 0, 0, 0.07);
+9 -3
View File
@@ -2,11 +2,13 @@
.theme-dark
{
// accent colors
$color-primary: #1db1b6;
$color-primary: #3c9a92; //#18a471
$color-primary-fg: #fff;
$color-primary-low: #{rgba(#2c3036, 0.2)};
$color-secondary: #f9e0c4;
$color-secondary-fg: #20242a;
$color-secondary: #24b4a6;
$color-secondary-fg: #fff;
$color-tertiary: #c4e4de;
$color-tertiary-fg: #2c3036;
// foreground colors
$color-fg: #fff;
@@ -32,6 +34,10 @@
--color-primary: #{$color-primary};
--color-primary-low: #{$color-primary-low};
--color-primary-text: #{$color-primary-fg};
--color-secondary: #{$color-secondary};
--color-secondary-text: #{$color-secondary-fg};
--color-tertiary: #{$color-tertiary};
--color-tertiary-text: #{$color-tertiary-fg};
// generic shades
// (try to avoid them)
+10 -4
View File
@@ -5,8 +5,10 @@
$color-primary: #2c3036; //#18a471
$color-primary-fg: #fff;
$color-primary-low: #{rgba(#2c3036, 0.2)};
$color-secondary: #f9e0c4;
$color-secondary-fg: #20242a;
$color-secondary: #24b4a6;
$color-secondary-fg: #fff;
$color-tertiary: #c4e4de;
$color-tertiary-fg: #2c3036;
// foreground colors
$color-fg: #2c3036;
@@ -15,9 +17,9 @@
$color-fg-shade-3: #c8cbcf;
// background colors
$color-bg: #f4f4f7;
$color-bg: #f4f4f6;
$color-bg-shade-1: #fff; // bright
$color-bg-shade-2: #f8f8fa; // dim
$color-bg-shade-2: #f8f8f9; // dim
$color-bg-shade-3: #f5f5f6; // bright-two
$color-bg-shade-4: #efeff1; // bright-three
$color-bg-shade-5: #eaecef;
@@ -34,6 +36,10 @@
--color-primary: #{$color-primary};
--color-primary-low: #{$color-primary-low};
--color-primary-text: #{$color-primary-fg};
--color-secondary: #{$color-secondary};
--color-secondary-text: #{$color-secondary-fg};
--color-tertiary: #{$color-tertiary};
--color-tertiary-text: #{$color-tertiary-fg};
// generic shades
// (try to avoid them)