GuestOps/src/GuestOps.Api/ConversationPaging.cs
2026-09-29 19:28:26 +01:00

20 lines
1.1 KiB
C#

using System.Text;
namespace GuestOps.Web;
public sealed record ConversationPage(IReadOnlyList<Conversation> Items,string? NextCursor);
public static class ConversationPaging
{
public static string Encode(Conversation item)=>Convert.ToBase64String(Encoding.UTF8.GetBytes(item.ReceivedAt.Ticks+"|"+item.Id)).TrimEnd('=').Replace('+','-').Replace('/','_');
public static bool TryDecode(string? value,out DateTime at,out string id)
{
at=default;id="";if(string.IsNullOrEmpty(value))return true;
try
{
if(value.Length>160)return false;var raw=value.Replace('-','+').Replace('_','/');raw=raw.PadRight((raw.Length+3)/4*4,'=');
var parts=Encoding.UTF8.GetString(Convert.FromBase64String(raw)).Split('|');
return parts.Length==2&&long.TryParse(parts[0],out var ticks)&&ticks>=DateTime.MinValue.Ticks&&ticks<=DateTime.MaxValue.Ticks&&System.Text.RegularExpressions.Regex.IsMatch(parts[1],"^[a-f0-9]{32}$")&&(at=new DateTime(ticks,DateTimeKind.Utc))!=default&&(id=parts[1]).Length>0;
}
catch{return false;}
}
}