using System.Collections.ObjectModel;
using System.Text.Json;
using JiDangJia.Contracts;
using JiDangJia.Services;
namespace JiDangJia.Views;
// 页面离开或 APP 进入后台后停止轮询,避免继续展示已退出账户的数据。
public abstract class OnlinePage : ContentPage
{
protected readonly AuthClient Auth=AuthClient.Current;
protected readonly Label State=Ui.Text("",12,Ui.Muted);
private readonly string accountId=AuthClient.Current.AccountId;
private readonly IDispatcherTimer? poll;
private Window? attachedWindow;
private bool visible,paused,busy;
protected bool CanUpdate=>visible&&!paused&&!Auth.Locked&&accountId==Auth.AccountId;
protected OnlinePage(int seconds=0)
{
if(seconds>0){poll=Dispatcher.CreateTimer();poll.Interval=TimeSpan.FromSeconds(seconds);poll.Tick+=(_,_)=>_=Reload();}
}
protected override void OnAppearing()
{
base.OnAppearing();visible=true;paused=false;attachedWindow=Window;
if(attachedWindow is not null){attachedWindow.Stopped+=Pause;attachedWindow.Resumed+=Resume;}
poll?.Start();_=Reload();
}
protected override void OnDisappearing()
{
visible=false;poll?.Stop();if(attachedWindow is not null){attachedWindow.Stopped-=Pause;attachedWindow.Resumed-=Resume;attachedWindow=null;}base.OnDisappearing();
}
private void Pause(object? sender,EventArgs e){paused=true;poll?.Stop();}
private void Resume(object? sender,EventArgs e){paused=false;if(visible){poll?.Start();_=Reload();}}
public async Task Reload()
{
if(busy||!CanUpdate)return;busy=true;
try{await LoadData();if(CanUpdate)State.Text="";}
catch(Exception ex){if(visible&&!paused&&Auth.AccountId.Length==0)LoginPage.ShowLogin();else if(CanUpdate)State.Text=ex.Message;}
finally{busy=false;}
}
protected abstract Task LoadData();
}
internal static partial class CommunityUi
{
public static string Time(string value)=>DateTimeOffset.TryParse(value,out var time)?time.LocalDateTime.ToString(time.LocalDateTime.Date==DateTime.Today?"HH:mm":"MM-dd HH:mm"):"";
public static View Avatar(string name)
{
var letter=Ui.Text(string.IsNullOrWhiteSpace(name)?"友":System.Globalization.StringInfo.GetNextTextElement(name),17,Ui.Bronze,true);letter.HorizontalTextAlignment=TextAlignment.Center;
var box=Ui.Card(letter,13,new Thickness(8),Ui.Cream);box.WidthRequest=42;box.HeightRequest=42;return box;
}
public static View Person(string name,string time)=>Ui.Row(Avatar(name),Ui.Stack(Ui.Text(name,14,bold:true),Ui.Text(time,10,Ui.Muted)));
public static Grid Layout(View top,View body,View? bottom=null)
{
var grid=new Grid{RowDefinitions=[new(GridLength.Auto),new(GridLength.Star),new(GridLength.Auto)],RowSpacing=10,Padding=new Thickness(18,14,18,12)};
grid.Add(top);grid.Add(body,0,1);if(bottom is not null)grid.Add(bottom,0,2);return grid;
}
public static string Short(string text,int max=130)=>CommunityText.Preview(text,max);
}
using System.Collections.ObjectModel;
using System.Text.Json;
using JiDangJia.Contracts;
using JiDangJia.Services;
namespace JiDangJia.Views;
// 页面离开或 APP 进入后台后停止轮询,避免继续展示已退出账户的数据。
public abstract class OnlinePage : ContentPage
{
protected readonly AuthClient Auth=AuthClient.Current;
protected readonly Label State=Ui.Text("",12,Ui.Muted);
private readonly string accountId=AuthClient.Current.AccountId;
private readonly IDispatcherTimer? poll;
private Window? attachedWindow;
private bool visible,paused,busy;
protected bool CanUpdate=>visible&&!paused&&!Auth.Locked&&accountId==Auth.AccountId;
protected OnlinePage(int seconds=0)
{
if(seconds>0){poll=Dispatcher.CreateTimer();poll.Interval=TimeSpan.FromSeconds(seconds);poll.Tick+=(_,_)=>_=Reload();}
}
protected override void OnAppearing()
{
base.OnAppearing();visible=true;paused=false;attachedWindow=Window;
if(attachedWindow is not null){attachedWindow.Stopped+=Pause;attachedWindow.Resumed+=Resume;}
poll?.Start();_=Reload();
}
protected override void OnDisappearing()
{
visible=false;poll?.Stop();if(attachedWindow is not null){attachedWindow.Stopped-=Pause;attachedWindow.Resumed-=Resume;attachedWindow=null;}base.OnDisappearing();
}
private void Pause(object? sender,EventArgs e){paused=true;poll?.Stop();}
private void Resume(object? sender,EventArgs e){paused=false;if(visible){poll?.Start();_=Reload();}}
public async Task Reload()
{
if(busy||!CanUpdate)return;busy=true;
try{await LoadData();if(CanUpdate)State.Text="";}
catch(Exception ex){if(visible&&!paused&&Auth.AccountId.Length==0)LoginPage.ShowLogin();else if(CanUpdate)State.Text=ex.Message;}
finally{busy=false;}
}
protected abstract Task LoadData();
}
internal static partial class CommunityUi
{
public static string Time(string value)=>DateTimeOffset.TryParse(value,out var time)?time.LocalDateTime.ToString(time.LocalDateTime.Date==DateTime.Today?"HH:mm":"MM-dd HH:mm"):"";
public static View Avatar(string name)
{
var letter=Ui.Text(string.IsNullOrWhiteSpace(name)?"友":System.Globalization.StringInfo.GetNextTextElement(name),17,Ui.Bronze,true);letter.HorizontalTextAlignment=TextAlignment.Center;
var box=Ui.Card(letter,13,new Thickness(8),Ui.Cream);box.WidthRequest=42;box.HeightRequest=42;return box;
}
public static View Person(string name,string time)=>Ui.Row(Avatar(name),Ui.Stack(Ui.Text(name,14,bold:true),Ui.Text(time,10,Ui.Muted)));
public static Grid Layout(View top,View body,View? bottom=null)
{
var grid=new Grid{RowDefinitions=[new(GridLength.Auto),new(GridLength.Star),new(GridLength.Auto)],RowSpacing=10,Padding=new Thickness(18,14,18,12)};
grid.Add(top);grid.Add(body,0,1);if(bottom is not null)grid.Add(bottom,0,2);return grid;
}
public static string Short(string text,int max=130)=>CommunityText.Preview(text,max);
}