Skip to content

Commit

Permalink
Show relative time within chat
Browse files Browse the repository at this point in the history
  • Loading branch information
FrayxRulez committed Dec 6, 2024
1 parent 880e6b0 commit d29a464
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 20 deletions.
72 changes: 66 additions & 6 deletions Telegram/Converters/LastSeenConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static int GetIndex(User user)
}
}

public static string GetLabel(User user, bool details)
public static string GetLabel(User user, bool details, bool relative = false)
{
if (user == null)
{
Expand Down Expand Up @@ -97,7 +97,7 @@ public static string GetLabel(User user, bool details)

if (user.Status is UserStatusOffline offline)
{
return FormatDateOnline(offline.WasOnline);
return FormatDateOnline(offline.WasOnline, relative);
}
else if (user.Status is UserStatusOnline online)
{
Expand All @@ -107,7 +107,7 @@ public static string GetLabel(User user, bool details)
}
else
{
return FormatDateOnline(online.Expires);
return FormatDateOnline(online.Expires, relative);
}
}
else if (user.Status is UserStatusRecently)
Expand All @@ -128,18 +128,39 @@ public static string GetLabel(User user, bool details)
}
}

private static string FormatDateOnline(long date)
private static string FormatDateOnline(long till, bool relative)
{
try
{
var rightNow = DateTime.Now;
var now = rightNow.ToTimestamp();

int day = rightNow.DayOfYear;
int year = rightNow.Year;

var online = Formatter.ToLocalTime(date);
var online = Formatter.ToLocalTime(till);
int dateDay = online.DayOfYear;
int dateYear = online.Year;

if (relative)
{
var minutes = (now - till) / 60;
if (minutes < 1)
{
return Strings.LastSeenNow;
}
else if (minutes < 60)
{
return Locale.Declension(Strings.R.LastSeenMinutes, minutes);
}

var hours = (now - till) / 3600;
if (hours < 12)
{
return Locale.Declension(Strings.R.LastSeenHours, hours);
}
}

if (dateDay == day && year == dateYear)
{
return string.Format(Strings.LastSeenFormatted, string.Format(Strings.TodayAtFormatted, Formatter.Time(online)));
Expand All @@ -148,7 +169,7 @@ private static string FormatDateOnline(long date)
{
return string.Format(Strings.LastSeenFormatted, string.Format(Strings.YesterdayAtFormatted, Formatter.Time(online)));
}
else if (Math.Abs(DateTime.Now.ToTimestamp() / 1000 - date) < 31536000000L)
else if (Math.Abs(DateTime.Now.ToTimestamp() / 1000 - till) < 31536000000L)
{
string format = string.Format(Strings.formatDateAtTime, online.ToString(Strings.formatterMonth), Formatter.Time(online));
return string.Format(Strings.LastSeenDateFormatted, format);
Expand Down Expand Up @@ -186,5 +207,44 @@ public static bool IsSupportUser(User user)
user.Id == 496000 || user.Id == 497000 || user.Id == 498000 ||
user.Id == 4298000);
}

public static double OnlinePhraseChange(UserStatus status, DateTime now)
{
return Math.Clamp(OnlinePhraseChangeInSeconds(status, now.ToTimestamp()), 0, 86400);
}

public static double OnlinePhraseChangeInSeconds(UserStatus status, int now)
{
var till = status switch
{
UserStatusOnline online => online.Expires,
UserStatusOffline offline => offline.WasOnline,
_ => -1
};

if (till < 0)
{
return till;
}

if (till > now)
{
return till - now;
}

var minutes = (now - till) / 60;
if (minutes < 60)
{
return (minutes + 1) * 60 - (now - till);
}
var hours = (now - till) / 3600;
if (hours < 12)
{
return (hours + 1) * 3600 - (now - till);
}
var nowFull = Formatter.ToLocalTime(now);
var tomorrow = nowFull.Date.AddDays(1);
return (tomorrow - nowFull).TotalSeconds;
}
}
}
9 changes: 8 additions & 1 deletion Telegram/Strings/en/Resources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// <auto-generatedInfo>
// This code was generated by TdParseOptions (http://github.com/UnigramDev/UnigramUtils/)
//
// Generated: 12/06/2024 14:07:49
// Generated: 12/06/2024 17:15:50
// </auto-generatedInfo>
// --------------------------------------------------------------------------------------------------
namespace Telegram
Expand Down Expand Up @@ -154,6 +154,8 @@ public static class R
public const string items = "items";
public const string JoinRequests = "JoinRequests";
public const string Languages = "Languages";
public const string LastSeenHours = "LastSeenHours";
public const string LastSeenMinutes = "LastSeenMinutes";
public const string Likes = "Likes";
public const string Links = "Links";
public const string MaximumReactionsValue = "MaximumReactionsValue";
Expand Down Expand Up @@ -10192,6 +10194,11 @@ public static class R
/// </summary>
public static string LastSeenNobodyPremium => Resource.GetString("LastSeenNobodyPremium");

/// <summary>
/// Localized resource similar to "last seen just now"
/// </summary>
public static string LastSeenNow => Resource.GetString("LastSeenNow");

/// <summary>
/// Localized resource similar to "Who can see my last seen time?"
/// </summary>
Expand Down
15 changes: 15 additions & 0 deletions Telegram/Strings/en/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -6848,12 +6848,27 @@ You can change your language back at any time in Settings.</value>
<data name="LastSeenFormatted" xml:space="preserve">
<value>last seen {0}</value>
</data>
<data name="LastSeenHours_one" xml:space="preserve">
<value>last seen {0} hour ago</value>
</data>
<data name="LastSeenHours_other" xml:space="preserve">
<value>last seen {0} hours ago</value>
</data>
<data name="LastSeenMinutes_one" xml:space="preserve">
<value>last seen {0} minute ago</value>
</data>
<data name="LastSeenMinutes_other" xml:space="preserve">
<value>last seen {0} minutes ago</value>
</data>
<data name="LastSeenNobody" xml:space="preserve">
<value>Nobody</value>
</data>
<data name="LastSeenNobodyPremium" xml:space="preserve">
<value>Premium users</value>
</data>
<data name="LastSeenNow" xml:space="preserve">
<value>last seen just now</value>
</data>
<data name="LastSeenTitle" xml:space="preserve">
<value>Who can see my last seen time?</value>
</data>
Expand Down
37 changes: 37 additions & 0 deletions Telegram/ViewModels/DialogViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ public override Chat Chat
private DialogType _type => Type;
public virtual DialogType Type => DialogType.History;

private DispatcherTimer _lastSeenTimer;

private string _lastSeen;
public string LastSeen
{
Expand All @@ -237,6 +239,40 @@ public string LastSeen
}
}

public void UpdateLastSeen(string value)
{
_lastSeenTimer?.Stop();
LastSeen = value;
}

public void UpdateLastSeen(User user)
{
var interval = LastSeenConverter.OnlinePhraseChange(user.Status, DateTime.Now);
if (interval > 0 && _lastSeenTimer == null)
{
_lastSeenTimer ??= new DispatcherTimer();
_lastSeenTimer.Tick += LastSeenTimer_Tick;
}

_lastSeenTimer?.Stop();

if (interval > 0)
{
_lastSeenTimer.Interval = TimeSpan.FromSeconds(interval);
_lastSeenTimer.Start();
}

LastSeen = LastSeenConverter.GetLabel(user, true, true);
}

private void LastSeenTimer_Tick(object sender, object e)
{
if (ClientService.TryGetUser(Chat, out User user))
{
UpdateLastSeen(user);
}
}

private string _onlineCount;
public string OnlineCount
{
Expand Down Expand Up @@ -2356,6 +2392,7 @@ protected override void OnNavigatedFrom(NavigationState suspensionState, bool su
return;
}

_lastSeenTimer?.Stop();
_groupedMessages.Clear();
_hasLoadedLastPinnedMessage = false;
_chatActionManager = null;
Expand Down
25 changes: 12 additions & 13 deletions Telegram/Views/ChatView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5376,15 +5376,15 @@ public void UpdateUserStatus(Chat chat, User user)
var options = ViewModel.ClientService.Options;
if (chat.Id == options.MyId || chat.Id == options.RepliesBotChatId || chat.Id == options.VerificationCodesBotChatId)
{
ViewModel.LastSeen = null;
ViewModel.UpdateLastSeen(null as string);
}
else if (ViewModel.Type == DialogType.ScheduledMessages)
{
ViewModel.LastSeen = null;
ViewModel.UpdateLastSeen(null as string);
}
else
{
ViewModel.LastSeen = LastSeenConverter.GetLabel(user, true);
ViewModel.UpdateLastSeen(user);
}
}

Expand Down Expand Up @@ -5474,8 +5474,7 @@ public void UpdateBasicGroupFullInfo(Chat chat, BasicGroup group, BasicGroupFull
else if (group.Status is ChatMemberStatusLeft or ChatMemberStatusBanned)
{
ShowAction(Strings.DeleteThisGroup, true);

ViewModel.LastSeen = Strings.YouLeft;
ViewModel.UpdateLastSeen(Strings.YouLeft);
}
else if (group.Status is ChatMemberStatusCreator creator && !creator.IsMember)
{
Expand Down Expand Up @@ -5507,15 +5506,15 @@ public void UpdateBasicGroupFullInfo(Chat chat, BasicGroup group, BasicGroupFull
TextField.IsReadOnly = readOnly;
}

ViewModel.LastSeen = Locale.Declension(Strings.R.Members, group.MemberCount);
ViewModel.UpdateLastSeen(Locale.Declension(Strings.R.Members, group.MemberCount));
}

if (fullInfo == null)
{
return;
}

ViewModel.LastSeen = Locale.Declension(Strings.R.Members, fullInfo.Members.Count);
ViewModel.UpdateLastSeen(Locale.Declension(Strings.R.Members, fullInfo.Members.Count));

btnVoiceMessage.IsRestricted = false;

Expand Down Expand Up @@ -5672,15 +5671,15 @@ public void UpdateSupergroupFullInfo(Chat chat, Supergroup group, SupergroupFull

if (ViewModel.Type == DialogType.History)
{
ViewModel.LastSeen = Locale.Declension(group.IsChannel ? Strings.R.Subscribers : Strings.R.Members, group.MemberCount);
ViewModel.UpdateLastSeen(Locale.Declension(group.IsChannel ? Strings.R.Subscribers : Strings.R.Members, group.MemberCount));
}
else if (ViewModel.Type == DialogType.Thread && ViewModel.Topic != null)
{
ViewModel.LastSeen = string.Format(Strings.TopicProfileStatus, chat.Title);
ViewModel.UpdateLastSeen(string.Format(Strings.TopicProfileStatus, chat.Title));
}
else
{
ViewModel.LastSeen = null;
ViewModel.UpdateLastSeen(null as string);
}

if (group.IsChannel)
Expand All @@ -5698,15 +5697,15 @@ public void UpdateSupergroupFullInfo(Chat chat, Supergroup group, SupergroupFull

if (ViewModel.Type == DialogType.History)
{
ViewModel.LastSeen = Locale.Declension(group.IsChannel ? Strings.R.Subscribers : Strings.R.Members, fullInfo.MemberCount);
ViewModel.UpdateLastSeen(Locale.Declension(group.IsChannel ? Strings.R.Subscribers : Strings.R.Members, fullInfo.MemberCount));
}
else if (ViewModel.Type == DialogType.Thread && ViewModel.Topic != null)
{
ViewModel.LastSeen = string.Format(Strings.TopicProfileStatus, chat.Title);
ViewModel.UpdateLastSeen(string.Format(Strings.TopicProfileStatus, chat.Title));
}
else
{
ViewModel.LastSeen = null;
ViewModel.UpdateLastSeen(null as string);
}

btnVoiceMessage.IsRestricted = false;
Expand Down

0 comments on commit d29a464

Please sign in to comment.