20 lines
1.1 KiB
C#
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;}
|
|
}
|
|
}
|