Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

【新增】可以使用 IMessageService 动态调用 Message 组件 #126

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/TDesignBlazor.Docs.Shared/App.razor
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@
</LayoutView>
</NotFound>
</Router>

<TDesignContainer/>
29 changes: 27 additions & 2 deletions doc/TDesignBlazor.Docs.Shared/Pages/Components/MessagePage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,30 @@
")
</CodeContent>
</Example>
<h2>通过服务调用</h2>
代码建设中...
<Example Title="通过服务调用">
<Description>注入 <code>IMessageService</code> 接口动态调用消息</Description>
<RunContent>
<Button OnClick="@(e=>MessageService.Show(new MessageConfiguration{ Content="这是全局提示"}))">自定义提示</Button>
<Button Theme="Theme.Primary" OnClick="@(e=>MessageService.Info("普通的提示"))">普通</Button>
<Button Theme="Theme.Success" OnClick="@(e=>MessageService.Success("成功的提示"))">成功</Button>
<Button Theme="Theme.Warning" OnClick="@(e=>MessageService.Warning("警告的提示"))">警告</Button>
<Button Theme="Theme.Danger" OnClick="@(e=>MessageService.Danger("失败的提示"))">失败</Button>
<Button OnClick="@(e=>MessageService.Question("有问题的提示"))">疑问</Button>
<Button Theme="Theme.Primary" OnClick="@(e=>MessageService.Loading("系统加载中"))">加载</Button>
</RunContent>
<CodeContent>
@Code.Create(@"
```cs
@inject IMessageService MessageService

MessageService.Info(...)
MessageService.Success(...)
MessageService.Danger(...)
MessageService.Warning(...)
MessageService.Loading(...)
MessageService.Question(...)
```
")
</CodeContent>
</Example>
@inject IMessageService MessageService
22 changes: 22 additions & 0 deletions doc/TDesignBlazor.Docs.Shared/Pages/Startup/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,26 @@
```
builder.Services.AddTDesignBlazor();
```
")

<h3>修改 App.razor </h3>

@Code.Create(@"
```html
<Router AppAssembly=""@typeof(App).Assembly"">
<Found Context=""routeData"">
<RouteView RouteData=""@routeData"" DefaultLayout=""@typeof(MainLayout)"" />
<FocusOnNavigate RouteData=""@routeData"" Selector=""h1"" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout=""@typeof(MainLayout)"">
<p role=""alert"">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>

<!--增加组件-->
<TDesignContainer/>
```
")
18 changes: 18 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@
```cs
@using TDesignBlazor
```
- 在 `App.razor` 增加 `TDesignContainer` 组件,用于动态组件的渲染
```html
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>

<!--增加组件-->
<TDesignContainer/>
```

## :pencil: 参与贡献
* 如果你有意向参与贡献,请先阅读[贡献指南](./Contributing.md)
Expand Down
21 changes: 21 additions & 0 deletions src/TDesignBlazor/Components/Messages/IMessageService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace TDesignBlazor;
/// <summary>
/// 提供全局提示的功能。
/// </summary>
public interface IMessageService : IDisposable
{
/// <summary>
/// 显示指定消息配置的全局提示。
/// </summary>
/// <param name="configuration">执行消息服务的配置。</param>
Task? Show(MessageConfiguration configuration);
/// <summary>
/// 当消息被关闭后时触发的事件。
/// </summary>
event Action? OnClosed;
/// <summary>
/// 当消息正在显示时触发的事件。
/// </summary>

event Func<MessageConfiguration, Task>? OnShowing;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
namespace TDesignBlazor;

/// <summary>
/// 全局提示。
/// 对用户的操作作出轻量的全局反馈。
/// 请使用 <see cref="IMessageService"/> 进行动态调用。
/// </summary>
[CssClass("t-message")]
public class Message : MessageComponentBase
Expand All @@ -22,6 +23,10 @@ public class Message : MessageComponentBase
/// </summary>
public bool Closed { get; private set; }

/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="builder"></param>
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
if (Closed)
Expand Down Expand Up @@ -65,17 +70,23 @@ protected override void AddContent(RenderTreeBuilder builder, int sequence)
}, condition: Closable);
}

/// <summary>
/// <inheritdoc/>
/// </summary>
protected override IconName? GetIconByTheme
{
get
{
if (Theme == TDesignBlazor.MessageTheme.Question)
if (Theme == MessageTheme.Question)
{
return IconName.HelpCircleFilled;
}
return base.GetIconByTheme;
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
protected override void OnParametersSet()
{
base.OnParametersSet();
Expand Down
53 changes: 53 additions & 0 deletions src/TDesignBlazor/Components/Messages/MessageConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using OneOf;

namespace TDesignBlazor;

/// <summary>
/// 表示全局消息的配置。
/// </summary>
/// <remarks>该对象用于 <see cref="IMessageService"/> 调用时传值给 <see cref="Message"/> 组件。</remarks>
public class MessageConfiguration
{
internal Guid Key => Guid.NewGuid();
/// <summary>
/// 获取或设置消息提示的内容文本字符串。
/// </summary>
public string? Content { get; set; }
/// <summary>
/// 获取或设置消息提示的图标。
/// </summary>
public object? Icon { get; set; }
/// <summary>
/// 获取或设置消息提示的主题风格。
/// </summary>
public Theme Theme { get; set; } = Theme.Primary;

/// <summary>
/// 获取或设置消息提示具备加载中的状态。
/// </summary>
public bool Loading { get; set; }
/// <summary>
/// 获取或设置消息提示可以被用户关闭。
/// </summary>
public bool Closable { get; set; }

/// <summary>
/// 获取或设置消息提示持续多久自动关闭,单位是毫秒,默认 5 秒,即 5000 毫秒。
/// </summary>
public int? Delay { get; set; } = 3000;

/// <summary>
/// 获取或设置显示的位置。
/// </summary>
public OneOf<Placement, (int offsetX, int offsetY)> Placement { get; set; } = OneOf<Placement, (int offsetX, int offsetY)>.FromT0(TDesignBlazor.Placement.TopRight);

/// <summary>
/// 获取显示的位置。
/// </summary>
/// <returns>class 或 style</returns>
public static (bool classOrStyle, string value) GetPlacement(OneOf<Placement, (int offsetX, int offsetY)> placement)
=> placement.Match(
p => (true, p.GetCssClass()),
value => new(false, $"left:{value.offsetX}px;top:{value.offsetY}")
);
}
114 changes: 114 additions & 0 deletions src/TDesignBlazor/Components/Messages/MessageContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using Microsoft.AspNetCore.Components.Rendering;

using OneOf;

namespace TDesignBlazor;
/// <summary>
/// 用于 <see cref="IMessageService"/> 动态显示 <see cref="Message"/> 组件的容器组件。
/// </summary>
public class MessageContainer : BlazorComponentBase, IDisposable
{
[Inject] IMessageService? MessageService { get; set; }

Dictionary<OneOf<Placement, (int offsetX, int offsetY)>, List<MessageConfiguration>> _messageListDic = new();



/// <inheritdoc/>
protected override void OnInitialized()
{
base.OnInitialized();
MessageService.OnShowing += MessageService_OnShowing;
}

private async Task MessageService_OnShowing(MessageConfiguration configuration)
{
if (configuration is null)
{
throw new ArgumentNullException(nameof(configuration));
}

await AddItem(configuration);
await this.Refresh();
}


/// <inheritdoc/>
protected override void AddContent(RenderTreeBuilder builder, int sequence)
{
foreach (var item in _messageListDic)
{
builder.CreateElement(0, "div", content =>
{
foreach (var configuration in item.Value)
{

content.CreateComponent<Message>(sequence + 1, builder => builder.AddContent(0, configuration.Content), new
{
configuration.Icon,
configuration.Loading,
configuration.Closable,
Theme = (Theme?)configuration?.Theme,
});
}
},
HtmlHelper.CreateHtmlAttributes(attributes =>
{
var (classOrStyle, value) = MessageConfiguration.GetPlacement(item.Key);
attributes["class"] = HtmlHelper.CreateCssBuilder().Append("t-message__list").Append(value, classOrStyle);
if (!classOrStyle)
{
attributes["style"] = HtmlHelper.CreateCssBuilder().Append(value);
}
})
);
}
}

private async Task AddItem(MessageConfiguration configuration)
{
var key = configuration.Placement;
if (_messageListDic.ContainsKey(key))
{
_messageListDic[key].Add(configuration);
}
else
{
_messageListDic.Add(key, new() { configuration });
}

await this.Refresh();

await OnTimeoutRemove();

Task OnTimeoutRemove()
{
Timer timer = new(async (state) =>
{
await RemoveItem((MessageConfiguration)state);
}, configuration, configuration.Delay ??= Timeout.Infinite, Timeout.Infinite);
return Task.CompletedTask;
}
}

private Task RemoveItem(MessageConfiguration configuration)
{
var key = configuration.Placement;
if (_messageListDic.ContainsKey(key))
{
_messageListDic[key].Remove(configuration);

if (!_messageListDic[key].Any())
{
_messageListDic.Remove(key);
}
}
return this.Refresh();
}

public void Dispose()
{
MessageService.OnShowing -= MessageService_OnShowing;

}
}
22 changes: 22 additions & 0 deletions src/TDesignBlazor/Components/Messages/MessageService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace TDesignBlazor;
internal class MessageService : IMessageService
{
public event Action? OnClosed;
public event Func<MessageConfiguration, Task> OnShowing;
public void Dispose() => OnClosed?.Invoke();

/// <inheritdoc/>
public async Task Show(MessageConfiguration configuration)
{
if (configuration is null)
{
throw new ArgumentNullException(nameof(configuration));
}

if (OnShowing is not null)
{
await OnShowing.Invoke(configuration);
}

}
}
Loading