NotificationInbox
TsgcHTMLComponent_NotificationInbox: um sino com um badge de não lidas e uma lista dropdown das notificações de um usuário, em Delphi, C++ Builder e .NET. A sua aplicação guarda as linhas, o componente as renderiza.
TsgcHTMLComponent_NotificationInbox: um sino com um badge de não lidas e uma lista dropdown das notificações de um usuário, em Delphi, C++ Builder e .NET. A sua aplicação guarda as linhas, o componente as renderiza.
A biblioteca não guarda nada. A sua aplicação responde a OnLoadNotifications com as linhas que mantém e é informada por OnMarkRead e OnMarkAllRead do que o usuário fez, para poder persistir isso. O componente renderiza a interface e não impõe nenhuma autorização. Funciona em todas as edições, sobre WebSocket ou server-sent events.
TsgcHTMLComponent_NotificationInbox (unit sgcHTML_Component_NotificationInbox)
Markup de dropdown do Bootstrap: um sino, um badge de não lidas e uma lista
Delphi, C++ Builder, .NET
Dê à caixa de entrada um InboxID, preencha-a a partir do seu próprio armazenamento em OnLoadNotifications, persista o que o usuário fez em OnMarkRead e OnMarkAllRead, e encaminhe as ações enviadas para ProcessAction com o usuário tirado da sessão.
uses
sgcHTML_Session, sgcHTML_Component_NotificationInbox;
var
oInbox: TsgcHTMLComponent_NotificationInbox;
begin
oInbox := TsgcHTMLComponent_NotificationInbox.Create(nil);
try
oInbox.InboxID := 'inbox';
oInbox.Title := 'Notifications';
oInbox.MaxItems := 10;
oInbox.OnLoadNotifications := InboxLoad;
oInbox.OnMarkRead := InboxMarkRead;
oInbox.OnMarkAllRead := InboxMarkAllRead;
// the user comes from the session, never from the form
oInbox.LoadNotifications(sgcHTMLRequestSession.UserID);
Response := oInbox.HTML; // bell, unread badge and dropdown
finally
oInbox.Free;
end;
end;
// the application owns the rows: fill the list, newest first
procedure TMain.InboxLoad(Sender: TObject; const aUserID: string;
aList: TsgcHTMLInboxItems);
begin
with aList.Add do
begin
Id := '1042';
Title := 'New order';
Text := 'Order #1042 was placed.';
Timestamp := '2 min ago';
Read := False;
end;
end;
procedure TMain.InboxMarkRead(Sender: TObject; const aUserID,
aNotificationID: string);
begin
// persist it, after checking that aUserID owns aNotificationID
end;
// in the message handler that receives the actions the inbox posts
if oInbox.ProcessAction(vUser, vAction, vNotificationID) then
oHTMX.PushFragment(vGuid, oInbox.GetListFragmentHTML +
oInbox.GetBadgeFragmentHTML);
// includes: sgcHTML_Session.hpp, sgcHTML_Component_NotificationInbox.hpp
TsgcHTMLComponent_NotificationInbox *oInbox = new TsgcHTMLComponent_NotificationInbox(NULL);
try
{
oInbox->InboxID = "inbox";
oInbox->Title = "Notifications";
oInbox->MaxItems = 10;
oInbox->OnLoadNotifications = InboxLoad;
oInbox->OnMarkRead = InboxMarkRead;
oInbox->OnMarkAllRead = InboxMarkAllRead;
// the user comes from the session, never from the form
oInbox->LoadNotifications(sgcHTMLRequestSession()->UserID);
String html = oInbox->HTML; // bell, unread badge and dropdown
}
__finally
{
delete oInbox;
}
// the application owns the rows: fill the list, newest first
void __fastcall TMain::InboxLoad(TObject *Sender, const String aUserID,
TsgcHTMLInboxItems *aList)
{
TsgcHTMLInboxItem *item = aList->Add();
item->Id = "1042";
item->Title = "New order";
item->Text = "Order #1042 was placed.";
item->Timestamp = "2 min ago";
item->Read = false;
}
void __fastcall TMain::InboxMarkRead(TObject *Sender, const String aUserID,
const String aNotificationID)
{
// persist it, after checking that aUserID owns aNotificationID
}
// in the message handler that receives the actions the inbox posts
if (oInbox->ProcessAction(vUser, vAction, vNotificationID))
oHTMX->PushFragment(vGuid, oInbox->GetListFragmentHTML() +
oInbox->GetBadgeFragmentHTML());
using esegece.sgcWebSockets;
var inbox = new TsgcHTMLComponent_NotificationInbox();
inbox.InboxID = "inbox";
inbox.Title = "Notifications";
inbox.MaxItems = 10;
inbox.OnLoadNotifications += InboxLoad;
inbox.OnMarkRead += InboxMarkRead;
inbox.OnMarkAllRead += InboxMarkAllRead;
// the user comes from the session, never from the form
string user = sgcHTMLSessionHelpers.sgcHTMLRequestSession()?.UserID ?? "";
inbox.LoadNotifications(user);
string html = inbox.HTML; // bell, unread badge and dropdown
// the application owns the rows: fill the list, newest first
void InboxLoad(object sender, string userID, TsgcHTMLInboxItems list)
{
var item = list.Add();
item.Id = "1042";
item.Title = "New order";
item.Text = "Order #1042 was placed.";
item.Timestamp = "2 min ago";
item.Read = false;
}
void InboxMarkRead(object sender, string userID, string notificationID)
{
// persist it, after checking that userID owns notificationID
}
// in the message handler that receives the actions the inbox posts
if (inbox.ProcessAction(user, action, notificationId))
htmx.PushFragment(guid, inbox.GetListFragmentHTML() + inbox.GetBadgeFragmentHTML());
Os membros que você usa com mais frequência.
Items é uma coleção TsgcHTMLInboxItems; cada TsgcHTMLInboxItem tem Id, Title, Text, Timestamp, Url, Icon e Read. Tudo em uma linha é dado e é escapado ao ser renderizado, inclusive o Icon: passe um glifo literal, nunca uma entidade HTML nem markup. Url é sanitizada e os links javascript: e data: são rejeitados.
O componente guarda apenas o que está renderizando. OnLoadNotifications(aUserID, aList) dispara com aList já limpa: preencha-a com as notificações do usuário, das mais novas para as mais antigas. OnMarkRead(aUserID, aNotificationID) dispara depois que o item é marcado como lido, e OnMarkAllRead(aUserID) depois que todos são.
LoadNotifications(aUserID), MarkRead(aUserID, aNotificationID) e MarkAllRead(aUserID) fazem o trabalho. ProcessAction(aUserID, aAction, aNotificationID) encaminha uma ação enviada para o método certo e devolve False quando a ação não é uma ação da caixa de entrada, para que você possa continuar procurando o seu dono.
O dropdown envia inboxMarkRead (campos action, inbox, id), inboxMarkAllRead e inboxRefresh (campos action, inbox) como formulários data-sgc-ws-send. O campo inbox carrega o id do elemento da caixa de entrada que renderizou o formulário, que é InboxID quando você o define, e é assim que uma página com várias caixas de entrada encaminha a ação para o componente certo.
O componente renderiza a interface e não impõe nenhuma autorização. Toda ação viaja como dado enviado pelo cliente, então um cliente hostil pode forjar qualquer ação e qualquer id de notificação. Nenhum id de usuário é escrito no markup: obtenha o usuário que age a partir da sessão da requisição (sgcHTMLRequestSession), nunca do formulário, e confira se o usuário é dono do id de notificação que chegou antes de persistir qualquer coisa.
Title é o título do dropdown, EmptyText o placeholder quando não há nada a mostrar e BellIcon o glifo do gatilho, markup confiável com uma entidade HTML por padrão. MaxItems limita as linhas visíveis (padrão 10, 0 mostra todas), ShowMarkAllRead e ShowBadge vêm ativados por padrão, e AddNotification(aId, aTitle, aText, aTimestamp, aUrl, aIcon) adiciona uma linha ou atualiza a que tem o mesmo id.
Cada notificação, o badge e a lista carregam um id de elemento estável. Depois de uma alteração, renderize apenas o markup afetado com GetItemFragmentHTML(aId), GetBadgeFragmentHTML ou GetListFragmentHTML e envie-o com TsgcHTMX_Engine_Server.PushFragment ou BroadcastFragment, em vez de renderizar a página de novo. UnreadCount conta os itens cujo Read é False.
A unit compila quando SGC_HTML está definido, o que o sgcVer.inc não faz para Android e iOS. Funciona em todas as edições, sobre WebSocket ou server-sent events. O sgcHTML é um pacote autônomo, vendido de forma independente do sgcWebSockets.
A caixa de entrada não escolhe por si só entre a página e um push: isso é feito por TsgcHTMLComponent_Notification, veja Notification e WebPush. Os canais que cada usuário quer são definidos em NotificationPreferences.
| Ajuda onlineReferência completa da API e guia de uso para este componente. | Abrir | |
| Todos os Componentes sgcHTMLExplore a matriz completa de recursos com mais de 80 componentes. | Abrir | |
| Baixar Versão de Avaliação GratuitaA avaliação de 30 dias inclui os projetos de demonstração 60.HTML, entre eles o 17.FieldService, que usa a caixa de entrada. | Abrir | |
| PreçosLicenças Single, Team e Site com código-fonte completo. | Abrir |