using System; using System.Collections.Generic; using ChatComponents; using Unity.UIWidgets.foundation; using Unity.UIWidgets.ui; using UnityEngine; using Color = Unity.UIWidgets.ui.Color; namespace UIWidgetsSample { public static class ChatUtils { public static string REGEX_LINK = @"([\w+]+\:\/\/)?([\w\d-]+\.)*[\w-]+[\.\:]\w+([\/\?\=\&\#\.]?[\w-]+)*\/?"; public static string formatBytes(int size, int fractionDigits = 2) { List profix = new List() { "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; if (size <= 0) return "0 B"; var multiple = (log(size) / log(1024)).floor(); return (size / Mathf.Pow(1024, multiple)).ToString("D3") + " " + profix[multiple]; } public static float log(int num) { if (num == 0) return float.NegativeInfinity; else if (num < 0) return Single.NaN; else return num * 1f; } /// Returns user avatar and name color based on the ID public static Color getUserAvatarNameColor(User user, List colors) { var index = user.id.GetHashCode() % colors.Count; return colors[0]; } /// Returns user name as joined firstName and lastName public static string getUserName(User user) => $"{user.firstName ?? ""} {user.lastName ?? ""}"; /// Returns formatted date used as a divider between different days in the /// chat history public static string getVerboseDateTimeRepresentation( DateTime dateTime, DateTime? dateFormat = null, string dateLocale = null, DateTime? timeFormat = null ) { var formattedDate = //dateFormat != null ? dateFormat.ToString().Format(dateTime) : DateTime.MMMd(dateLocale).format(dateTime); dateTime.ToString("MMM-dd"); var formattedTime = //timeFormat != null ? timeFormat.format(dateTime) : DateTime.Hm(dateLocale).format(dateTime); dateTime.ToString("hh:mm"); var localDateTime = dateTime.ToLocalTime(); var now = DateTime.Now; if (localDateTime.Day == now.Day && localDateTime.Month == now.Month && localDateTime.Year == now.Year) return formattedTime; return $"{formattedDate}, {formattedTime}"; } /// Parses provided messages to chat messages (with headers and spacers) and /// returns them with a gallery public static List calculateChatMessages( List messages, User user, bool showUserNames, CustomDateHeaderText customDateHeaderText = null, DateTime? dateFormat = null, string dateLocale = null, DateTime? timeFormat = null ) { var chatMessages = new List(); var gallery = new List(); var shouldShowName = false; for (var i = messages.Count - 1; i >= 0; i--) { var isFirst = i == messages.Count - 1; var isLast = i == 0; var message = messages[i]; var messageHasCreatedAt = message.createdAt != null; ChatComponents.Message nextMessage = isLast ? null : messages[i - 1]; bool nextMessageHasCreatedAt = isLast ? true : nextMessage.createdAt != null; bool nextMessageSameAuthor = isLast ? false : message.author.id == nextMessage.author.id; bool notMyMessage = message.author.id != user.id; bool nextMessageDateThreshold = false; bool nextMessageDifferentDay = false; bool nextMessageInGroup = false; bool showName = false; if (showUserNames) { var previousMessage = isFirst ? null : messages[i + 1]; var isFirstInGroup = notMyMessage && (message.author.id != previousMessage?.author.id || message.createdAt != null && previousMessage?.createdAt != null && (int)message.createdAt - (int)previousMessage.createdAt > 60000); if (isFirstInGroup) { shouldShowName = false; if (message.type == MessageType.text) showName = true; else shouldShowName = true; } if (message.type == MessageType.text && shouldShowName) { showName = true; shouldShowName = false; } } if (messageHasCreatedAt && nextMessageHasCreatedAt) { nextMessageDateThreshold = isLast ? false : (int) nextMessage?.createdAt - (int) message.createdAt >= 900000; nextMessageDifferentDay = TimeSpan.FromMilliseconds(message.createdAt == null ? 0 : (int)message.createdAt).Days != TimeSpan.FromMilliseconds(nextMessage?.createdAt == null ? 0 : (int)nextMessage?.createdAt).Days; nextMessageInGroup = nextMessageSameAuthor && (int)nextMessage?.createdAt - (int)message.createdAt <= 60000; } if (isFirst && messageHasCreatedAt) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); var timeSend = epoch.AddTicks((message.createdAt == null ? 0 : (int) message.createdAt) * 1000000000); chatMessages.Insert( 0, new DateHeader( customDateHeaderText != null ? customDateHeaderText( new DateTime(timeSend.Year,timeSend.Month,timeSend.Day,timeSend.Hour,timeSend.Minute,timeSend.Second) ) : getVerboseDateTimeRepresentation( new DateTime(timeSend.Year,timeSend.Month,timeSend.Day,timeSend.Hour,timeSend.Minute,timeSend.Second),//new DateTime((int) TimeSpan.FromMilliseconds(message.createdAt == null ? 0 : (int)message.createdAt).TotalMilliseconds ),//DateTime.FromFileTime(message.createdAt == null ? 0 : (int)message.createdAt),// dateFormat, dateLocale, timeFormat ) ) ); } var _message = new Dictionary { {"message", message}, {"nextMessageInGroup", nextMessageInGroup}, {"showName", notMyMessage && showUserNames && showName && getUserName(message.author).isNotEmpty() }, {"showStatus", true} }; chatMessages.Insert(0, _message); if (!nextMessageInGroup) { chatMessages.Insert( 0, new MessageSpacer( 12, message.id ) ); } if (nextMessageDifferentDay || nextMessageDateThreshold) { chatMessages.Insert( 0, new DateHeader( customDateHeaderText != null ? customDateHeaderText( DateTime.Now)//DateTime.FromFileTime(isLast ? 0 : (int) nextMessage?.createdAt) ) : getVerboseDateTimeRepresentation( DateTime.Now,//DateTime.FromFileTime(isLast ? 0 : (int) nextMessage?.createdAt), dateFormat, dateLocale, timeFormat ) ) ); } if (message is ImageMessage) { if (foundation_.kIsWeb) { if (((ImageMessage) message).uri.StartsWith("http")) gallery.Add(new PreviewImage(message.id, ((ImageMessage) message).uri)); } gallery.Add(new PreviewImage(message.id, ((ImageMessage) message).uri)); } } var results = new List(){chatMessages,gallery}; //results.AddRange(chatMessages); //results.AddRange(gallery); return results; } } }