Skip to content

Instantly share code, notes, and snippets.

@realLiangshiwei
Last active January 2, 2024 06:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save realLiangshiwei/70e19e34389ce7e567b5078a42db230a to your computer and use it in GitHub Desktop.
Save realLiangshiwei/70e19e34389ce7e567b5078a42db230a to your computer and use it in GitHub Desktop.
QA6084
<abp-style-bundle name="@BlazorLeptonXThemeBundles.Styles.Global" />
<leptonx-theme-appearance /> // add this line
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling
@addTagHelper *, Volo.Abp.AspNetCore.Components.Server.LeptonXTheme // Add this line
namespace Volo.Abp.AspNetCore.Components.Server.LeptonXTheme;
public class LeptonXStyleProvider : ITransientDependency
{
private const string LEPTONX_STYLE_COOKIE_NAME = "lpx_loaded-css";
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly LeptonXThemeOptions _leptonXThemeOption;
public LeptonXStyleProvider(IHttpContextAccessor httpContextAccessor, IOptions<LeptonXThemeOptions> leptonXThemeOption)
{
_httpContextAccessor = httpContextAccessor;
_leptonXThemeOption = leptonXThemeOption.Value;
}
public virtual Task<string> GetSelectedStyleAsync()
{
var styleName = _httpContextAccessor.HttpContext?.Request.Cookies[LEPTONX_STYLE_COOKIE_NAME];
if (string.IsNullOrWhiteSpace(styleName) || !_leptonXThemeOption.Styles.ContainsKey(styleName))
{
if (_leptonXThemeOption.DefaultStyle == LeptonXStyleNames.System)
{
return Task.FromResult(LeptonXStyleNames.Dim);
}
return Task.FromResult(_leptonXThemeOption.DefaultStyle);
}
return Task.FromResult(styleName);
}
}
namespace Volo.Abp.AspNetCore.Components.Server.LeptonXTheme.TagHelpers;
[HtmlTargetElement("leptonx-theme-appearance", TagStructure = TagStructure.NormalOrSelfClosing)]
public class LeptonXThemeAppearanceTagHelper : AbpTagHelper, ITransientDependency
{
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; } = default!;
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
output.TagName = null;
output.Content.Clear();
var options = ViewContext.HttpContext.RequestServices.GetRequiredService<IOptions<LeptonXThemeBlazorOptions>>().Value;
var leptonXStyleProvider = ViewContext.HttpContext.RequestServices.GetRequiredService<LeptonXStyleProvider>();
var layout = options.Layout == LeptonXBlazorLayouts.SideMenu ? "side-menu" : "top-menu";
var selectedStyle = await leptonXStyleProvider.GetSelectedStyleAsync();
var selectedStyleFileName = CultureHelper.IsRtl ? selectedStyle + ".rtl" : selectedStyle;
output.Content.AppendHtml(GetLinkHtml(layout, $"bootstrap-{selectedStyleFileName}.css", $"lpx-theme-bootstrap-{selectedStyle}"));
output.Content.AppendHtml(GetLinkHtml(layout, $"{selectedStyleFileName}.css", $"lpx-theme-color-{selectedStyle}"));
}
private string GetLinkHtml(string layout, string fileName, string id)
{
return $"<link href=\"/_content/Volo.Abp.AspNetCore.Components.Web.LeptonXTheme/{layout}/css/{fileName}\" type=\"text/css\" rel=\"stylesheet\" id=\"{id}\"/>{Environment.NewLine}";
}
}
public class MyBlazorLeptonXThemeStyleContributor : BundleContributor
{
private const string RootPath = "/_content/Volo.Abp.AspNetCore.Components.Web.LeptonXTheme";
public override Task ConfigureBundleAsync(BundleConfigurationContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<LeptonXThemeBlazorOptions>>().Value;
var rtl = CultureHelper.IsRtl ? ".rtl" : string.Empty;
var layout = options.Layout == LeptonXBlazorLayouts.SideMenu ? "side-menu" : "top-menu";
context.Files.AddIfNotContains($"{RootPath}/{layout}/css/layout-bundle{rtl}.css");
context.Files.AddIfNotContains($"{RootPath}/{layout}/css/abp-bundle{rtl}.css");
context.Files.AddIfNotContains($"{RootPath}/{layout}/css/blazor-bundle{rtl}.css");
context.Files.AddIfNotContains($"{RootPath}/{layout}/css/font-bundle{rtl}.css");
return Task.CompletedTask;
}
}
Configure<AbpBundlingOptions>(options =>
{
options.StyleBundles.Configure(
BlazorLeptonXThemeBundles.Styles.Global,
bundle =>
{
bundle.AddContributors(new MyBlazorLeptonXThemeStyleContributor());
}
);
});
(function () {
(function(history){
var pushState = history.pushState;
history.pushState = function(state) {
if (typeof history.onpushstate == "function") {
history.onpushstate({state: state});
}
setTimeout(function(){
var scrollBars = leptonx.init.initializers?.get('initPerfectScrollbar');
if(scrollBars)
{
let scrollBar = scrollBars()[0];
if (scrollBar) {
scrollBar.element.scrollTop = 0;
}
}
leptonx.mobileNavbar.closeMenu();
}, 100);
return pushState.apply(history, arguments);
};
})(window.history);
function isAlreadyLoaded(id) {
return document.querySelector(`link[id^="lpx-theme-${id}-"]`)?.id;
}
function loadThemeCSS(key, event, cssPrefix) {
const newThemeId = createId(event.detail.theme, key);
const previousThemeId = createId(event.detail.previousTheme, key);
const loadedCSS = isAlreadyLoaded(key);
if (newThemeId !== loadedCSS) {
replaceStyleWith(
createStyleUrl(cssPrefix + event.detail.theme),
newThemeId,
previousThemeId || loadedCSS
);
}
}
function createId(theme, type) {
return theme && `lpx-theme-${type}-${theme}`;
}
window.initLeptonX = function (layout = currentLayout, defaultStyle = "dim") {
window.currentLayout = layout;
leptonx.globalConfig.defaultSettings =
{
appearance: defaultStyle,
containerWidth: 'full',
};
leptonx.CSSLoadEvent.on(event => {
loadThemeCSS('bootstrap', event, 'bootstrap-');
loadThemeCSS('color', event, '');
});
leptonx.init.run();
}
const oldAfterLeptonXInitialization = window.afterLeptonXInitialization;
window.afterLeptonXInitialization = function () {
if(oldAfterLeptonXInitialization){
oldAfterLeptonXInitialization();
}
}
function createStyleUrl(theme, type) {
if (isRtl()) {
theme = theme + '.rtl';
}
if (type) {
return `/_content/Volo.Abp.AspNetCore.Components.Web.LeptonXTheme/${window.currentLayout}/css/${type}-${theme}.css`
}
return `/_content/Volo.Abp.AspNetCore.Components.Web.LeptonXTheme/${window.currentLayout}/css/${theme}.css`;
}
function replaceStyleWith(path, id, previousId) {
let needToCreateElement = false;
let link = document.querySelector(`[href*="${path}"]`) ?? document.querySelector(`link[id^="${previousId}"]`);
if(link == null){
link = document.createElement('link');
needToCreateElement = true;
}
let href = link.getAttribute('href');
href = href?.replace(href.substring(href.indexOf('?_v')), '');
if(href !== path){
link.href = path;
}
link.type = 'text/css';
link.rel = 'stylesheet';
link.id = id;
if(needToCreateElement){
document.getElementsByTagName('head')[0].appendChild(link);
}
return link;
}
function isRtl() {
return document.documentElement.getAttribute('dir') === 'rtl';
}
})();
public class MyScriptContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.RemoveAll(x => x.Contains("leptonx-blazor-compatibility.js"));
context.Files.AddIfNotContains("/myleptonx-blazor-compatibility.js");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment