NotificationInbox

TsgcHTMLComponent_NotificationInbox: una campana con una insignia de no leídas y una lista desplegable con las notificaciones de un usuario, en Delphi, C++ Builder y .NET. Tu aplicación guarda las filas, el componente las renderiza.

TsgcHTMLComponent_NotificationInbox

La biblioteca no almacena nada. Tu aplicación responde a OnLoadNotifications con las filas que guarda y se entera por OnMarkRead y OnMarkAllRead de lo que hizo el usuario, para poder guardarlo. El componente renderiza la interfaz y no aplica ninguna autorización. Funciona en todas las ediciones, sobre WebSocket o eventos enviados por el servidor.

Clase del componente

TsgcHTMLComponent_NotificationInbox (unidad sgcHTML_Component_NotificationInbox)

Genera

Marcado de desplegable de Bootstrap: una campana, una insignia de no leídas y una lista

Lenguajes

Delphi, C++ Builder, .NET

Créalo, responde a tres eventos, enruta las acciones

Dale a la bandeja un InboxID, rellénala desde tu propio almacenamiento en OnLoadNotifications, guarda lo que hizo el usuario en OnMarkRead y OnMarkAllRead, y enruta las acciones recibidas a ProcessAction con el usuario tomado de la sesión.

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());

Propiedades y métodos clave

Los miembros que usarás con más frecuencia.

Items

Items es una colección TsgcHTMLInboxItems; cada TsgcHTMLInboxItem tiene Id, Title, Text, Timestamp, Url, Icon y Read. Todo lo de una fila son datos y se escapa al renderizarse, incluido Icon: pasa un glifo literal, nunca una entidad HTML ni marcado. Url se sanea y los enlaces javascript: y data: se rechazan.

Eventos de almacenamiento

El componente solo guarda lo que está renderizando. OnLoadNotifications(aUserID, aList) se dispara con aList ya vaciada: rellénala con las notificaciones del usuario, las más recientes primero. OnMarkRead(aUserID, aNotificationID) se dispara después de marcar el elemento como leído, y OnMarkAllRead(aUserID) después de marcarlos todos.

Acciones del lado del servidor

LoadNotifications(aUserID), MarkRead(aUserID, aNotificationID) y MarkAllRead(aUserID) hacen el trabajo. ProcessAction(aUserID, aAction, aNotificationID) enruta una acción recibida a la correcta y devuelve False cuando la acción no es de una bandeja, de modo que puedas seguir buscando a su propietario.

Acciones que envía

El desplegable envía inboxMarkRead (campos action, inbox, id), inboxMarkAllRead y inboxRefresh (campos action, inbox) como formularios data-sgc-ws-send. El campo inbox lleva el id del elemento de la bandeja que renderizó el formulario, que es InboxID cuando lo defines, y así es como una página con varias bandejas enruta la acción al componente correcto.

Autorización

El componente renderiza la interfaz y no aplica ninguna autorización. Cada acción viaja como datos enviados por el cliente, de modo que un cliente hostil puede falsificar cualquier acción y cualquier id de notificación. No se escribe ningún id de usuario en el marcado: toma el usuario que actúa de la sesión de la petición (sgcHTMLRequestSession), nunca del formulario, y comprueba que el usuario es el propietario del id de notificación recibido antes de guardar nada.

Apariencia

Title es el encabezado del desplegable, EmptyText el texto de relleno cuando no hay nada que mostrar y BellIcon el glifo del disparador, marcado de confianza con una entidad HTML por defecto. MaxItems limita las filas visibles (por defecto 10, 0 muestra todas), ShowMarkAllRead y ShowBadge están activados por defecto, y AddNotification(aId, aTitle, aText, aTimestamp, aUrl, aIcon) añade una fila o actualiza la que tiene el mismo id.

Actualizaciones en vivo

Cada notificación, la insignia y la lista llevan un id de elemento estable. Tras un cambio, renderiza solo el marcado afectado con GetItemFragmentHTML(aId), GetBadgeFragmentHTML o GetListFragmentHTML y envíalo con TsgcHTMX_Engine_Server.PushFragment o BroadcastFragment, en lugar de renderizar de nuevo la página. UnreadCount cuenta los elementos cuyo Read es False.

Ediciones y canales

La unidad se compila cuando SGC_HTML está definido, algo que sgcVer.inc no hace para Android e iOS. Funciona en todas las ediciones, sobre WebSocket o eventos enviados por el servidor. sgcHTML es un pack autónomo, que se vende de forma independiente de sgcWebSockets.

Página o push

La bandeja no elige por sí misma entre la página y un push: eso lo hace TsgcHTMLComponent_Notification, consulta Notification y WebPush. Los canales que quiere cada usuario se establecen en NotificationPreferences.

Sigue explorando

Ayuda en líneaReferencia completa de la API y guía de uso para este componente.
Todos los componentes de sgcHTMLExplora la matriz completa de más de 80 componentes.
Descargar prueba gratuitaLa prueba de 30 días incluye los proyectos de demostración 60.HTML, entre ellos 17.FieldService, que usa la bandeja.
PreciosLicencias Single, Team y Site con código fuente completo.
La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

¿Listo para empezar?

Descarga la prueba gratuita y empieza a crear interfaces web en Delphi, C++ Builder y .NET.