Skip to content
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 exclusion.dic
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,5 @@ dotx
Modbus
Protocol
vditor
alertdialog
blazorbootstrap
17 changes: 13 additions & 4 deletions src/BootstrapBlazor.Server/Components/Samples/Messages.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@page "/message"
@page "/message"
@inject IStringLocalizer<Messages> Localizer
@inject MessageService MessageService

Expand All @@ -20,8 +20,18 @@ private MessageService? MessageService { get; set; }
});</Pre>

<DemoBlock Title="@Localizer["MessagesNormalTitle"]" Introduction="@Localizer["MessagesNormalIntro"]" Name="Normal">
<button class="btn btn-primary" @onclick="@ShowMessage">@Localizer["MessagesMessagePrompt"]</button>
<Message @ref="Message" Placement="Placement.Bottom" />
<section ignore class="row form-inline g-3">
<div class="col-12">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="Placement"></BootstrapInputGroupLabel>
<RadioList @bind-Value="@_placement" Items="@_items"></RadioList>
</BootstrapInputGroup>
</div>
<div class="col-12">
<button class="btn btn-primary" @onclick="@ShowMessage">@Localizer["MessagesMessagePrompt"]</button>
</div>
</section>
<Message @ref="Message" Placement="@Placement"></Message>
</DemoBlock>

<DemoBlock Title="@Localizer["MessagesAsyncTitle"]" Introduction="@Localizer["MessagesAsyncIntro"]" Name="Async">
Expand Down Expand Up @@ -70,7 +80,6 @@ private MessageService? MessageService { get; set; }

<DemoBlock Title="@Localizer["MessagesTemplateTitle"]" Introduction="@Localizer["MessagesTemplateIntro"]" Name="Template">
<button class="btn btn-primary" @onclick="@ShowTemplateMessage">@Localizer["MessagesTemplatePrompt"]</button>
<Message @ref="Message1" Placement="Placement.Bottom" />
</DemoBlock>

<DemoBlock Title="@Localizer["MessagesShowModeTitle"]" Introduction="@Localizer["MessagesShowModeIntro"]" Name="ShowMode">
Expand Down
21 changes: 13 additions & 8 deletions src/BootstrapBlazor.Server/Components/Samples/Messages.razor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
Expand All @@ -18,13 +18,20 @@ public sealed partial class Messages

private readonly MessageOption _option = new();

private long _count = 0;

private string _placement = "Top";

private readonly List<SelectedItem> _items = [new SelectedItem("Top", "Top"), new SelectedItem("Bottom", "Bottom")];

private Placement Placement => _placement == "Top" ? Placement.Top : Placement.Bottom;

private async Task ShowMessage()
{
Message.SetPlacement(Placement.Top);
await MessageService.Show(new MessageOption()
{
Content = "This is a reminder message"
});
Content = $"This is a reminder message {_count++}"
}, Message);
}

private async Task ShowAsyncMessage()
Expand Down Expand Up @@ -97,7 +104,7 @@ private async Task ShowBottomMessage()
{
await MessageService.Show(new MessageOption()
{
Content = $"This is a reminder message - {DateTime.Now:mm:ss}",
Content = $"This is a reminder message - {_count++}",
Icon = "fa-solid fa-circle-info",
}, Message1);
}
Expand All @@ -111,13 +118,11 @@ await MessageService.Show(new MessageOption()
});
}

private int lastCount = 0;

private Task ShowLastOnlyMessage() => MessageService.Show(new MessageOption()
{
ShowShadow = true,
ShowMode = MessageShowMode.Single,
Content = lastCount++.ToString()
Content = $"This is a reminder message - {_count++}"
});

private static AttributeItem[] GetAttributes() =>
Expand Down
64 changes: 17 additions & 47 deletions src/BootstrapBlazor/Components/Message/Message.razor
Original file line number Diff line number Diff line change
@@ -1,59 +1,29 @@
@namespace BootstrapBlazor.Components
@namespace BootstrapBlazor.Components
@inherits BootstrapModuleComponentBase
@attribute [BootstrapModuleAutoLoader(JSObjectReference = true)]

<div id="@Id" class="@ClassString" style="@StyleName" role="alert">
@if (Placement == Placement.Top)
@foreach (var item in MessagesForRender)
{
foreach (var item in _messages)
{
<div @key="item" id="@GetItemId(item)" role="alertdialog" class="@GetItemClassString(item)" data-bb-autohide="@GetAutoHideString(item)" data-bb-delay="@item.Delay">
@if (!string.IsNullOrEmpty(item.Icon))
<div @key="item" id="@GetItemId(item)" role="alertdialog" class="@GetItemClassString(item)" data-bb-autohide="@GetAutoHideString(item)" data-bb-delay="@item.Delay">
@if (!string.IsNullOrEmpty(item.Icon))
{
<i class="@item.Icon"></i>
}
<div>
@if (item.ChildContent != null)
{
<i class="@item.Icon"></i>
@item.ChildContent
}
<div>
@if (item.ChildContent != null)
{
@item.ChildContent
}
else
{
@item.Content
}
</div>
@if (item.ShowDismiss)
else
{
<button type="button" class="btn-close" aria-label="close"></button>
@item.Content
}
</div>
}
}
else
{
for (var index = _messages.Count; index > 0; index--)
{
var item = _messages[index - 1];
<div @key="item" id="@GetItemId(item)" role="alertdialog" class="@GetItemClassString(item)" data-bb-autohide="@GetAutoHideString(item)" data-bb-delay="@item.Delay">
@if (!string.IsNullOrEmpty(item.Icon))
{
<i class="@item.Icon"></i>
}
<div>
@if (item.ChildContent != null)
{
@item.ChildContent
}
else
{
@item.Content
}
</div>
@if (item.ShowDismiss)
{
<button type="button" class="btn-close" aria-label="close"></button>
}
</div>
}
@if (item.ShowDismiss)
{
<button type="button" class="btn-close" aria-label="close"></button>
}
</div>
}
</div>
26 changes: 18 additions & 8 deletions src/BootstrapBlazor/Components/Message/Message.razor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
Expand Down Expand Up @@ -27,6 +27,10 @@ public partial class Message

private readonly List<MessageOption> _messages = [];

private IEnumerable<MessageOption> MessagesForRender => Placement == Placement.Bottom
? _messages.AsEnumerable().Reverse()
: _messages;

/// <summary>
/// 获得/设置 显示位置 默认为 Top
/// </summary>
Expand Down Expand Up @@ -55,7 +59,7 @@ protected override void OnInitialized()
/// <inheritdoc/>
/// </summary>
/// <returns></returns>
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, nameof(Clear));
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop);

private static string? GetAutoHideString(MessageOption option) => option.IsAutoHide ? "true" : null;

Expand Down Expand Up @@ -86,7 +90,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
}

/// <summary>
/// 设置 Toast 容器位置方法
/// 设置 容器位置方法
/// </summary>
/// <param name="placement"></param>
public void SetPlacement(Placement placement)
Expand All @@ -105,33 +109,39 @@ private async Task Show(MessageOption option)
if (!_messages.Contains(option))
{
_messages.Add(option);
_msgId = GetItemId(option);
}
_msgId = GetItemId(option);
await InvokeAsync(StateHasChanged);
}

/// <summary>
/// 清除 Message 方法 由 JSInvoke 触发
/// </summary>
[JSInvokable]
public Task Clear()
public void Clear(string id)
{
_messages.Clear();
var option = _messages.Find(i => GetItemId(i) == id);
if (option != null)
{
_messages.Remove(option);
}

StateHasChanged();
return Task.CompletedTask;
}

/// <summary>
/// OnDismiss 回调方法 由 JSInvoke 触发
/// </summary>
/// <param name="id"></param>
[JSInvokable]
public async Task Dismiss(string id)
public async ValueTask Dismiss(string id)
{
var option = _messages.Find(i => GetItemId(i) == id);
if (option is { OnDismiss: not null })
{
await option.OnDismiss();
_messages.Remove(option);
StateHasChanged();
}
}

Expand Down
31 changes: 14 additions & 17 deletions src/BootstrapBlazor/Components/Message/Message.razor.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import Data from "../../modules/data.js"
import Data from "../../modules/data.js"
import EventHandler from "../../modules/event-handler.js"

export function init(id, invoke, callback) {
export function init(id, invoke) {
const el = document.getElementById(id)
const msg = { el, invoke, callback, items: [] }
const msg = { el, invoke, items: [] }
Data.set(id, msg)
}

export function show(id, msgId) {
const msg = Data.get(id)
const el = document.getElementById(msgId)
if (el === null) {
return
}

const msg = Data.get(id)
let msgItem = msg.items.find(i => i.el.id === msgId)
if (msgItem === void 0) {
msgItem = { el, animationId: null }
msg.items.push(msgItem)
}

if (msgItem.animationId) {
cancelAnimationFrame(msgItem.animationId);
return;
}

const autoHide = el.getAttribute('data-bb-autohide') === 'true';
Expand All @@ -46,28 +46,25 @@ export function show(id, msgId) {
el.classList.add('show');

const close = () => {
EventHandler.off(el, 'click')
el.classList.remove('show');
const hideHandler = setTimeout(function () {
clearTimeout(hideHandler);
el.classList.add("d-none");

msg.items.pop();
if (msg.items.length === 0) {
msg.invoke.invokeMethodAsync(msg.callback);
}
}, 500);
msg.items = msg.items.filter(i => i.el.id !== msgId);
msg.invoke.invokeMethodAsync("Clear", msgId);
};

EventHandler.on(el, 'click', '.btn-close', e => {
EventHandler.on(el, 'click', '.btn-close', async e => {
e.preventDefault();
e.stopPropagation();

const alert = e.delegateTarget.closest('.alert');
if (alert) {
EventHandler.off(el, 'click')
alert.classList.add("d-none");

const alertId = alert.getAttribute('id');
msg.invoke.invokeMethodAsync('Dismiss', alertId);
msg.items = msg.items.filter(i => i.el.id !== alertId);
await msg.invoke.invokeMethodAsync('Dismiss', alertId);
}
close();
});
}

Expand Down
Loading
Loading