mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-24 13:33:34 +08:00
Adding recently installed indication.
--HG-- branch : dev
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Data.Migration;
|
||||
@@ -52,12 +53,15 @@ namespace Orchard.Modules.Controllers {
|
||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not allowed to manage modules")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var modules = _extensionManager.AvailableExtensions().Where(x => DefaultExtensionTypes.IsModule(x.ExtensionType));
|
||||
IEnumerable<Module> modules = _extensionManager.AvailableExtensions()
|
||||
.Where(x => DefaultExtensionTypes.IsModule(x.ExtensionType))
|
||||
.Select(extensionDescriptor => new Module(extensionDescriptor) {
|
||||
IsRecentlyInstalled = _moduleService.UpdateIsRecentlyInstalled(extensionDescriptor)
|
||||
});
|
||||
|
||||
return View(new ModulesIndexViewModel {
|
||||
Modules = modules,
|
||||
InstallModules = _featureManager.GetEnabledFeatures().FirstOrDefault(f => f.Id == "PackagingServices") != null,
|
||||
BrowseToGallery = _featureManager.GetEnabledFeatures().FirstOrDefault(f => f.Id == "Gallery") != null
|
||||
InstallModules = _featureManager.GetEnabledFeatures().FirstOrDefault(f => f.Id == "PackagingServices") != null
|
||||
});
|
||||
}
|
||||
|
||||
@@ -67,12 +71,14 @@ namespace Orchard.Modules.Controllers {
|
||||
|
||||
var featuresThatNeedUpdate = _dataMigrationManager.GetFeaturesThatNeedUpdate();
|
||||
|
||||
var features = _featureManager.GetAvailableFeatures()
|
||||
IEnumerable<ModuleFeature> features = _featureManager.GetAvailableFeatures()
|
||||
.Where(f => !DefaultExtensionTypes.IsTheme(f.Extension.ExtensionType))
|
||||
.Select(f=>new ModuleFeature{Descriptor=f,
|
||||
IsEnabled=_shellDescriptor.Features.Any(sf=>sf.Name==f.Id),
|
||||
NeedsUpdate=featuresThatNeedUpdate.Contains(f.Id)})
|
||||
.ToList();
|
||||
.Select(f => new ModuleFeature {
|
||||
Descriptor = f,
|
||||
IsEnabled = _shellDescriptor.Features.Any(sf => sf.Name == f.Id),
|
||||
IsRecentlyInstalled = _moduleService.UpdateIsRecentlyInstalled(f.Extension),
|
||||
NeedsUpdate = featuresThatNeedUpdate.Contains(f.Id)
|
||||
});
|
||||
|
||||
return View(new FeaturesViewModel { Features = features });
|
||||
}
|
||||
|
@@ -57,6 +57,8 @@
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="Extensions\StringExtensions.cs" />
|
||||
<Compile Include="Models\DoghouseComparer.cs" />
|
||||
<Compile Include="Services\IModuleService.cs" />
|
||||
<Compile Include="ViewModels\Module.cs" />
|
||||
<Compile Include="ViewModels\ModuleFeature.cs" />
|
||||
<Compile Include="ViewModels\FeaturesViewModel.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
|
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
|
||||
namespace Orchard.Modules.Services {
|
||||
public interface IModuleService : IDependency {
|
||||
void EnableFeatures(IEnumerable<string> featureNames);
|
||||
void EnableFeatures(IEnumerable<string> featureNames, bool force);
|
||||
void DisableFeatures(IEnumerable<string> featureNames);
|
||||
void DisableFeatures(IEnumerable<string> featureNames, bool force);
|
||||
bool UpdateIsRecentlyInstalled(ExtensionDescriptor module);
|
||||
}
|
||||
}
|
@@ -5,44 +5,35 @@ using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Modules.ViewModels;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Modules.Services {
|
||||
public interface IModuleService : IDependency {
|
||||
void EnableFeatures(IEnumerable<string> featureNames);
|
||||
void EnableFeatures(IEnumerable<string> featureNames, bool force);
|
||||
void DisableFeatures(IEnumerable<string> featureNames);
|
||||
void DisableFeatures(IEnumerable<string> featureNames, bool force);
|
||||
}
|
||||
|
||||
public class ModuleService : IModuleService {
|
||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly IShellDescriptorManager _shellDescriptorManager;
|
||||
|
||||
public ModuleService(
|
||||
IOrchardServices orchardServices,
|
||||
IVirtualPathProvider virtualPathProvider,
|
||||
IExtensionManager extensionManager,
|
||||
IShellDescriptorManager shellDescriptorManager) {
|
||||
|
||||
Services = orchardServices;
|
||||
|
||||
_virtualPathProvider = virtualPathProvider;
|
||||
_extensionManager = extensionManager;
|
||||
_shellDescriptorManager = shellDescriptorManager;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public IOrchardServices Services { get; set; }
|
||||
|
||||
//public IModule GetModuleByName(string moduleName) {
|
||||
// return _extensionManager
|
||||
// .AvailableExtensions()
|
||||
// .Where(e => string.Equals(e.Name, moduleName, StringComparison.OrdinalIgnoreCase))
|
||||
// .Where(e => string.Equals(e.ExtensionType, ModuleExtensionType, StringComparison.OrdinalIgnoreCase))
|
||||
// .Select(descriptor => AssembleModuleFromDescriptor(descriptor))
|
||||
// .FirstOrDefault();
|
||||
//}
|
||||
|
||||
public IEnumerable<ModuleFeature> GetAvailableFeatures() {
|
||||
var enabledFeatures = _shellDescriptorManager.GetShellDescriptor().Features;
|
||||
return _extensionManager.AvailableExtensions()
|
||||
@@ -103,6 +94,31 @@ namespace Orchard.Modules.Services {
|
||||
shellDescriptor.Parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the recently installed flag by using the project's last written time.
|
||||
/// </summary>
|
||||
/// <param name="descriptor">The extension descriptor.</param>
|
||||
public bool UpdateIsRecentlyInstalled(ExtensionDescriptor descriptor) {
|
||||
string projectFile = GetManifestPath(descriptor);
|
||||
if (!string.IsNullOrEmpty(projectFile)) {
|
||||
// If project file was modified less than 24 hours ago, the module was recently deployed
|
||||
return DateTime.UtcNow.Subtract(_virtualPathProvider.GetFileLastWriteTimeUtc(projectFile)) < new TimeSpan(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetManifestPath(ExtensionDescriptor descriptor) {
|
||||
string projectPath = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id,
|
||||
"module.txt");
|
||||
|
||||
if (!_virtualPathProvider.FileExists(projectPath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return projectPath;
|
||||
}
|
||||
|
||||
private IEnumerable<string> EnableFeature(string featureName, IEnumerable<ModuleFeature> features, bool force) {
|
||||
var featuresList = features.ToList();
|
||||
var getDisabledDependencies =
|
||||
|
@@ -5,4 +5,3 @@ namespace Orchard.Modules.ViewModels {
|
||||
public IEnumerable<ModuleFeature> Features { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
36
src/Orchard.Web/Modules/Orchard.Modules/ViewModels/Module.cs
Normal file
36
src/Orchard.Web/Modules/Orchard.Modules/ViewModels/Module.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
|
||||
namespace Orchard.Modules.ViewModels {
|
||||
/// <summary>
|
||||
/// Represents a module.
|
||||
/// </summary>
|
||||
public class Module {
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
public Module() {}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a module based on an extension descriptor.
|
||||
/// </summary>
|
||||
/// <param name="extensionDescriptor">The extension descriptor.</param>
|
||||
public Module(ExtensionDescriptor extensionDescriptor) {
|
||||
Descriptor = extensionDescriptor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The module's extension descriptor.
|
||||
/// </summary>
|
||||
public ExtensionDescriptor Descriptor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating if the module needs a version update.
|
||||
/// </summary>
|
||||
public bool NeedsVersionUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating if the feature was recently installed.
|
||||
/// </summary>
|
||||
public bool IsRecentlyInstalled { get; set; }
|
||||
}
|
||||
}
|
@@ -1,9 +1,33 @@
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
|
||||
namespace Orchard.Modules.ViewModels {
|
||||
/// <summary>
|
||||
/// Represents a module's feature.
|
||||
/// </summary>
|
||||
public class ModuleFeature {
|
||||
/// <summary>
|
||||
/// The feature descriptor.
|
||||
/// </summary>
|
||||
public FeatureDescriptor Descriptor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating if the feature is enabled.
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating if the feature needs a data update / migration.
|
||||
/// </summary>
|
||||
public bool NeedsUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating if the module needs a version update.
|
||||
/// </summary>
|
||||
public bool NeedsVersionUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating if the feature was recently installed.
|
||||
/// </summary>
|
||||
public bool IsRecentlyInstalled { get; set; }
|
||||
}
|
||||
}
|
@@ -1,11 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.Modules.ViewModels {
|
||||
public class ModulesIndexViewModel {
|
||||
public bool InstallModules { get; set; }
|
||||
public bool BrowseToGallery { get; set; }
|
||||
public IEnumerable<ExtensionDescriptor> Modules { get; set; }
|
||||
public IEnumerable<Module> Modules { get; set; }
|
||||
}
|
||||
}
|
@@ -43,6 +43,11 @@
|
||||
if (feature == features.Last()) {
|
||||
featureClassName += " last";
|
||||
}
|
||||
|
||||
if (feature.IsRecentlyInstalled) {
|
||||
featureClassName += " recentlyInstalledFeature";
|
||||
}
|
||||
|
||||
var dependencies = (from d in feature.Descriptor.Dependencies
|
||||
select (from f in Model.Features where f.Descriptor.Id == d select f).SingleOrDefault()).Where(f => f != null).OrderBy(f => f.Descriptor.Name);
|
||||
var missingDependencies = feature.Descriptor.Dependencies
|
||||
|
@@ -14,23 +14,27 @@
|
||||
}
|
||||
|
||||
@if (Model.Modules.Count() > 0) {
|
||||
<ul class="contentItems">
|
||||
@foreach (var module in Model.Modules.OrderBy(m => m.Name)) {
|
||||
<li>
|
||||
<ul class="contentItems">
|
||||
@foreach (var module in Model.Modules.OrderBy(m => m.Descriptor.Name)) {
|
||||
string moduleClasses = module.IsRecentlyInstalled ? "recentlyInstalledModule" : string.Empty;
|
||||
|
||||
<li class="@moduleClasses">
|
||||
<div class="summary">
|
||||
<div class="properties">
|
||||
<h2>@module.Name<span> - @T("Version: {0}", !string.IsNullOrEmpty(module.Version) ? module.Version : T("1.0").ToString())</span></h2>
|
||||
@if (!string.IsNullOrEmpty(module.Description)) {
|
||||
<p>@module.Description</p>}
|
||||
<h2>@module.Descriptor.Name<span> - @T("Version: {0}", !string.IsNullOrEmpty(module.Descriptor.Version) ? module.Descriptor.Version : T("1.0").ToString())</span></h2>
|
||||
@if (!string.IsNullOrEmpty(module.Descriptor.Description)) {
|
||||
<p>@module.Descriptor.Description</p>}
|
||||
<ul class="pageStatus" style="color:#666; margin:.6em 0 0 0;">
|
||||
<li>@T("Features: {0}", MvcHtmlString.Create(string.Join(", ", module.Features.Select(f => Html.Link(string.IsNullOrEmpty(f.Name) ? f.Id : f.Name, string.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), f.Id.AsFeatureId(n => T(n)))).ToString()).OrderBy(s => s).ToArray())))</li>
|
||||
<li> | @T("Author: {0}", !string.IsNullOrEmpty(module.Author) ? module.Author : T("Unknown").ToString())</li>
|
||||
<li>@T("Features: {0}", MvcHtmlString.Create(string.Join(", ", module.Descriptor.Features.Select(f => Html.Link(string.IsNullOrEmpty(f.Name) ? f.Id : f.Name, string.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), f.Id.AsFeatureId(n => T(n)))).ToString()).OrderBy(s => s).ToArray())))</li>
|
||||
<li> | @T("Author: {0}", !string.IsNullOrEmpty(module.Descriptor.Author) ? module.Descriptor.Author : T("Unknown").ToString())</li>
|
||||
<li> | @T("Website: ")
|
||||
@if (!string.IsNullOrEmpty(module.WebSite)) { <a href="@module.WebSite">@module.WebSite</a> }
|
||||
@if (!string.IsNullOrEmpty(module.Descriptor.WebSite)) { <a href="@module.Descriptor.WebSite">@module.Descriptor.WebSite</a> }
|
||||
else { @T("Unknown").ToString() }
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</li>}
|
||||
</ul>}
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
@@ -137,3 +137,12 @@
|
||||
.features .feature .actions a {
|
||||
margin-left:.5em;
|
||||
}
|
||||
.recentlyInstalledFeature {
|
||||
background-color: Green;
|
||||
}
|
||||
.recentlyInstalledModule {
|
||||
background-color: Green;
|
||||
}
|
||||
.updateAvailable {
|
||||
background-color: Lime;
|
||||
}
|
@@ -47,15 +47,11 @@
|
||||
width: 171px;
|
||||
height: 128px;
|
||||
}
|
||||
|
||||
.ratings {
|
||||
background:url(../Content/Images/stars.png) repeat-x;
|
||||
position: relative;
|
||||
height: 14px;
|
||||
width: 75px;
|
||||
display: block;
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.score {
|
||||
background: url(../Content/Images/stars.png) repeat-x 0 -14px;
|
||||
|
@@ -65,10 +65,6 @@
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="ratings" style="width:@(15*5)px" title="@T("Ratings: {0} ({1})", item.Rating, item.RatingsCount)">
|
||||
<div class="score" style="width:@(15*(item.Rating))px"> </div>
|
||||
</div>
|
||||
|
||||
<div class="related">
|
||||
@Html.ActionLink(T("Install").ToString(), "Install", new RouteValueDictionary { { "packageId", item.PackageId }, { "version", item.Version }, { "sourceId", item.Source.Id }, { "redirectTo", "Modules" } })@T(" | ")
|
||||
<a href="@item.PackageStreamUri">@T("Download")</a>
|
||||
@@ -83,6 +79,11 @@
|
||||
<li> | @T("Website: ")
|
||||
@if (!string.IsNullOrEmpty(item.ProjectUrl)) { <a href="@item.ProjectUrl">@item.ProjectUrl</a> } else { @T("Unknown").ToString() }
|
||||
</li>
|
||||
<li> | @T("Rating")
|
||||
<div class="ratings" style="width:@(15*5)px" title="@T("Ratings: {0} ({1})", item.Rating, item.RatingsCount)">
|
||||
<div class="score" style="width:@(15*(item.Rating))px"> </div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -71,10 +71,6 @@
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="ratings" style="width:@(15*5)px" title="@T("Ratings: {0} ({1})", item.Rating, item.RatingsCount)">
|
||||
<div class="score" style="width:@(15*(item.Rating))px"> </div>
|
||||
</div>
|
||||
|
||||
<div class="related">
|
||||
@Html.ActionLink(T("Install").ToString(), "Install", new RouteValueDictionary {{"packageId", item.PackageId}, {"version", item.Version}, {"sourceId", item.Source.Id}, {"redirectTo", "Themes"}})@T(" | ")
|
||||
<a href="@item.PackageStreamUri">@T("Download")</a>
|
||||
@@ -90,6 +86,11 @@
|
||||
@if(!string.IsNullOrEmpty(item.ProjectUrl)) { <a href="@item.ProjectUrl">@item.ProjectUrl</a> }
|
||||
else { @T("Unknown").ToString() }
|
||||
</li>
|
||||
<li> | @T("Rating")
|
||||
<div class="ratings" style="width:@(15*5)px" title="@T("Ratings: {0} ({1})", item.Rating, item.RatingsCount)">
|
||||
<div class="score" style="width:@(15*(item.Rating))px"> </div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -80,6 +80,7 @@ namespace Orchard.Themes.Controllers {
|
||||
})
|
||||
.Select(extensionDescriptor => new ThemeEntry(extensionDescriptor) {
|
||||
NeedsUpdate = featuresThatNeedUpdate.Contains(extensionDescriptor.Id),
|
||||
IsRecentlyInstalled = _themeService.UpdateIsRecentlyInstalled(extensionDescriptor),
|
||||
Enabled = _shellDescriptor.Features.Any(sf => sf.Name == extensionDescriptor.Id)
|
||||
})
|
||||
.ToArray();
|
||||
|
@@ -1,19 +1,51 @@
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
|
||||
namespace Orchard.Themes.Models {
|
||||
/// <summary>
|
||||
/// Represents a theme.
|
||||
/// </summary>
|
||||
public class ThemeEntry {
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
public ThemeEntry() {}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a theme based on an extension descriptor.
|
||||
/// </summary>
|
||||
/// <param name="extensionDescriptor">The extension descriptor.</param>
|
||||
public ThemeEntry(ExtensionDescriptor extensionDescriptor) {
|
||||
Descriptor = extensionDescriptor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The theme's extension descriptor.
|
||||
/// </summary>
|
||||
public ExtensionDescriptor Descriptor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating wether the theme is enabled.
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating wether the theme needs a data update / migration.
|
||||
/// </summary>
|
||||
public bool NeedsUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating if the module needs a version update.
|
||||
/// </summary>
|
||||
public bool NeedsVersionUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating if the feature was recently installed.
|
||||
/// </summary>
|
||||
public bool IsRecentlyInstalled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The theme's name.
|
||||
/// </summary>
|
||||
public string Name { get { return Descriptor.Name; } }
|
||||
}
|
||||
}
|
||||
|
@@ -62,6 +62,7 @@
|
||||
<Compile Include="Preview\PreviewThemeFilter.cs" />
|
||||
<Compile Include="Preview\PreviewThemeSelector.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\IThemeService.cs" />
|
||||
<Compile Include="Services\SafeModeThemeSelector.cs" />
|
||||
<Compile Include="Services\SiteThemeSelector.cs" />
|
||||
<Compile Include="Services\SiteThemeService.cs" />
|
||||
|
@@ -0,0 +1,9 @@
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
|
||||
namespace Orchard.Themes.Services {
|
||||
public interface IThemeService : IDependency {
|
||||
void DisableThemeFeatures(string themeName);
|
||||
void EnableThemeFeatures(string themeName);
|
||||
bool UpdateIsRecentlyInstalled(ExtensionDescriptor module);
|
||||
}
|
||||
}
|
@@ -3,38 +3,30 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Routing;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.Features;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
|
||||
namespace Orchard.Themes.Services {
|
||||
public interface IThemeService : IDependency {
|
||||
void DisableThemeFeatures(string themeName);
|
||||
void EnableThemeFeatures(string themeName);
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public class ThemeService : IThemeService {
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly IFeatureManager _featureManager;
|
||||
private readonly IEnumerable<IThemeSelector> _themeSelectors;
|
||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||
|
||||
public ThemeService(
|
||||
IShellDescriptorManager shellDescriptorManager,
|
||||
IExtensionManager extensionManager,
|
||||
IFeatureManager featureManager,
|
||||
IEnumerable<IThemeSelector> themeSelectors,
|
||||
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
ShellDescriptor shellDescriptor,
|
||||
IOrchardServices orchardServices) {
|
||||
IVirtualPathProvider virtualPathProvider) {
|
||||
_extensionManager = extensionManager;
|
||||
_featureManager = featureManager;
|
||||
_themeSelectors = themeSelectors;
|
||||
_virtualPathProvider = virtualPathProvider;
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
T = NullLocalizer.Instance;
|
||||
@@ -120,5 +112,30 @@ namespace Orchard.Themes.Services {
|
||||
}
|
||||
return themes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the recently installed flag by using the project's last written time.
|
||||
/// </summary>
|
||||
/// <param name="descriptor">The extension descriptor.</param>
|
||||
public bool UpdateIsRecentlyInstalled(ExtensionDescriptor descriptor) {
|
||||
string projectFile = GetManifestPath(descriptor);
|
||||
if (!string.IsNullOrEmpty(projectFile)) {
|
||||
// If project file was modified less than 24 hours ago, the module was recently deployed
|
||||
return DateTime.UtcNow.Subtract(_virtualPathProvider.GetFileLastWriteTimeUtc(projectFile)) < new TimeSpan(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetManifestPath(ExtensionDescriptor descriptor) {
|
||||
string projectPath = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id,
|
||||
"theme.txt");
|
||||
|
||||
if (!_virtualPathProvider.FileExists(projectPath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return projectPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -51,3 +51,6 @@
|
||||
.themePreviewImage {
|
||||
height:300px;
|
||||
}
|
||||
.recentlyInstalledTheme {
|
||||
background-color: Gray;
|
||||
}
|
@@ -44,7 +44,9 @@
|
||||
} else {
|
||||
<ul class="templates">
|
||||
@foreach (ThemeEntry theme in Model.Themes) {
|
||||
<li>
|
||||
string themeClasses = theme.IsRecentlyInstalled ? "recentlyInstalledTheme" : string.Empty;
|
||||
|
||||
<li class="@themeClasses">
|
||||
<div>
|
||||
<h3>@theme.Name</h3>
|
||||
@Html.Image(Href(Html.ThemePath(Model.CurrentTheme.Descriptor, "/Theme.png")), Html.Encode(Model.CurrentTheme.Name), null)
|
||||
|
Reference in New Issue
Block a user