Skip to content

Commit b18622a

Browse files
committed
Display subscription info
1 parent 98c4226 commit b18622a

9 files changed

Lines changed: 193 additions & 9 deletions

File tree

YtFlowApp/App.idl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ namespace YtFlowApp
281281
{
282282
get;
283283
};
284+
Boolean IsSubscription
285+
{
286+
get;
287+
};
284288
String DisplayType
285289
{
286290
get;
@@ -305,6 +309,18 @@ namespace YtFlowApp
305309
{
306310
get;
307311
};
312+
String SubscriptionTotalUsed
313+
{
314+
get;
315+
};
316+
Double SubscriptionPercentUsed
317+
{
318+
get;
319+
};
320+
Boolean SubscriptionHasDataUsage
321+
{
322+
get;
323+
};
308324
String SubscriptionBytesTotal
309325
{
310326
get;
@@ -313,6 +329,10 @@ namespace YtFlowApp
313329
{
314330
get;
315331
};
332+
String SubscriptionExpireAt
333+
{
334+
get;
335+
};
316336
Windows.Foundation.Collections.IObservableVector<ProxyModel> Proxies
317337
{
318338
get;

YtFlowApp/CoreSubscription.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ namespace winrt::YtFlowApp::implementation
5959
continue;
6060
}
6161
std::stringstream ss;
62-
ss << std::put_time(&ctime, "%F %T"); // ISO 8601 date + time
62+
// ISO 8601 date + time
63+
ss << std::put_time(&ctime, "%F") << 'T' << std::put_time(&ctime, "%T");
6364
ret.expires_at = {ss.str()};
6465
continue;
6566
}

YtFlowApp/LibraryPage.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ namespace winrt::YtFlowApp::implementation
248248
.expiresAt = nullptr};
249249
if (result->userinfo.expires_at.has_value())
250250
{
251-
result->expiresAt = userinfo.expires_at->c_str();
251+
result->expiresAt = result->userinfo.expires_at->c_str();
252252
}
253253
}
254254
fire_and_forget LibraryPage::CreateSubscriptionButton_Click(IInspectable const &, RoutedEventArgs const &)
@@ -365,6 +365,11 @@ namespace winrt::YtFlowApp::implementation
365365
for (auto &&[model, subscriptionInfo] : subscriptionInfoToAttach)
366366
{
367367
model->AttachSubscriptionInfo(subscriptionInfo);
368+
if (model->Proxies() != nullptr)
369+
{
370+
model->Proxies(nullptr);
371+
LoadProxiesForProxyGroup(*model);
372+
}
368373
}
369374
if (!errors.empty())
370375
{

YtFlowApp/LibraryPage.xaml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,65 @@
256256
ItemsSource="{x:Bind Model.CurrentProxyGroupModel.Proxies, Mode=OneWay, FallbackValue={x:Null}}"
257257
SelectionMode="Extended"
258258
SelectionChanged="ProxyGroupProxyList_SelectionChanged"
259+
Header="{x:Bind Model.CurrentProxyGroupModel, Mode=OneWay}"
259260
>
261+
<ListView.HeaderTemplate>
262+
<DataTemplate x:DataType="local:ProxyGroupModel">
263+
<Grid
264+
Visibility="{x:Bind IsSubscription}"
265+
Padding="12, 10, 0, 10"
266+
Background="{ThemeResource LayerFillColorDefaultBrush}"
267+
BorderThickness="0, 1, 0, 1"
268+
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
269+
>
270+
<Grid.RowDefinitions>
271+
<RowDefinition Height="24" />
272+
<RowDefinition Height="Auto" />
273+
<RowDefinition Height="24" />
274+
<RowDefinition Height="24" />
275+
</Grid.RowDefinitions>
276+
<Grid.ColumnDefinitions>
277+
<ColumnDefinition Width="Auto" />
278+
<ColumnDefinition Width="*" />
279+
</Grid.ColumnDefinitions>
280+
<TextBlock Grid.Row="0" Grid.Column="0" Text="URL" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
281+
<TextBlock Grid.Row="0" Grid.Column="1" Text="{x:Bind SubscriptionUrl}" IsTextSelectionEnabled="True" />
282+
<TextBlock
283+
Grid.Row="1"
284+
Grid.Column="0"
285+
Text="Data Usage"
286+
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
287+
Visibility="{x:Bind SubscriptionHasDataUsage, Mode=OneWay}"
288+
/>
289+
<Grid Grid.Row="1" Grid.Column="1" Margin="0, 8, 0, 8">
290+
<Grid.RowDefinitions>
291+
<RowDefinition Height="Auto" />
292+
<RowDefinition Height="Auto" />
293+
</Grid.RowDefinitions>
294+
<Grid.ColumnDefinitions>
295+
<!-- Hack to align the progress bar to the left -->
296+
<ColumnDefinition Width="*" MaxWidth="250" />
297+
<ColumnDefinition Width="Auto" />
298+
</Grid.ColumnDefinitions>
299+
<ProgressBar
300+
Grid.Row="0"
301+
x:Name="SubscriptionDataUsedBar"
302+
Value="{x:Bind SubscriptionPercentUsed, Mode=OneWay}"
303+
Margin="0, 0, 20, 0"
304+
/>
305+
<StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal">
306+
<TextBlock Text="{x:Bind SubscriptionTotalUsed, Mode=OneWay}" />
307+
<TextBlock Margin="8, 0, 8, 0">/</TextBlock>
308+
<TextBlock Text="{x:Bind SubscriptionBytesTotal, Mode=OneWay}" />
309+
</StackPanel>
310+
</Grid>
311+
<TextBlock Grid.Row="2" Grid.Column="0" Text="Expire" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" Margin="0, 0, 20, 0" />
312+
<TextBlock Grid.Row="2" Grid.Column="1" Text="{x:Bind SubscriptionExpireAt, Mode=OneWay}" />
313+
<TextBlock Grid.Row="3" Grid.Column="0" Text="Last Update" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" Margin="0, 0, 20, 0" />
314+
<TextBlock Grid.Row="3" Grid.Column="1" Text="{x:Bind SubscriptionRetrievedAt, Mode=OneWay}" />
315+
</Grid>
316+
</DataTemplate>
317+
</ListView.HeaderTemplate>
260318
<ListView.ItemTemplate>
261319
<DataTemplate x:DataType="local:ProxyModel">
262320
<Grid>

YtFlowApp/ProxyGroupModel.cpp

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace winrt::YtFlowApp::implementation
3131
m_type = value;
3232
m_propertyChanged(*this, PropertyChangedEventArgs(L"Type"));
3333
m_propertyChanged(*this, PropertyChangedEventArgs(L"IsManualGroup"));
34+
m_propertyChanged(*this, PropertyChangedEventArgs(L"IsSubscription"));
3435
m_propertyChanged(*this, PropertyChangedEventArgs(L"DisplayType"));
3536
m_propertyChanged(*this, PropertyChangedEventArgs(L"DisplayTypeIcon"));
3637
m_propertyChanged(*this, PropertyChangedEventArgs(L"TooltipText"));
@@ -39,13 +40,17 @@ namespace winrt::YtFlowApp::implementation
3940
{
4041
return m_type == L"manual";
4142
}
43+
bool ProxyGroupModel::IsSubscription() const
44+
{
45+
return m_type == L"subscription";
46+
}
4247
hstring ProxyGroupModel::DisplayType() const
4348
{
4449
if (IsManualGroup())
4550
{
4651
return L"Local";
4752
}
48-
else if (m_type == L"subscription")
53+
if (IsSubscription())
4954
{
5055
return L"Subscription";
5156
}
@@ -65,7 +70,7 @@ namespace winrt::YtFlowApp::implementation
6570
{
6671
return m_name + L" (Local)";
6772
}
68-
else if (m_type == L"subscription")
73+
else if (IsSubscription())
6974
{
7075
return m_name + L" (Subscription)";
7176
}
@@ -83,6 +88,18 @@ namespace winrt::YtFlowApp::implementation
8388
{
8489
return m_subscriptionDownloadUsed;
8590
}
91+
hstring ProxyGroupModel::SubscriptionTotalUsed() const
92+
{
93+
return m_subscriptionTotalUsed;
94+
}
95+
double ProxyGroupModel::SubscriptionPercentUsed() const
96+
{
97+
return m_subscriptionPercentUsed;
98+
}
99+
bool ProxyGroupModel::SubscriptionHasDataUsage() const
100+
{
101+
return m_subscriptionHasDataUsage;
102+
}
86103
hstring ProxyGroupModel::SubscriptionBytesTotal() const
87104
{
88105
return m_subscriptionBytesTotal;
@@ -91,6 +108,10 @@ namespace winrt::YtFlowApp::implementation
91108
{
92109
return m_subscriptionRetrievedAt;
93110
}
111+
hstring ProxyGroupModel::SubscriptionExpireAt() const
112+
{
113+
return m_subscriptionExpireAt;
114+
}
94115
void ProxyGroupModel::AttachSubscriptionInfo(FfiProxyGroupSubscription const &subscription)
95116
{
96117
m_subscriptionUrl = to_hstring(subscription.url);
@@ -100,23 +121,67 @@ namespace winrt::YtFlowApp::implementation
100121
{
101122
m_subscriptionUploadUsed = HumanizeByte(subscription.upload_bytes_used.value());
102123
}
124+
else
125+
{
126+
m_subscriptionUploadUsed = L"";
127+
}
103128
if (subscription.download_bytes_used.has_value())
104129
{
105130
m_subscriptionDownloadUsed = HumanizeByte(subscription.download_bytes_used.value());
106131
}
132+
else
133+
{
134+
m_subscriptionDownloadUsed = L"";
135+
}
107136
if (subscription.bytes_total.has_value())
108137
{
109138
m_subscriptionBytesTotal = HumanizeByte(subscription.bytes_total.value());
110139
}
140+
else
141+
{
142+
m_subscriptionBytesTotal = L"";
143+
}
144+
if (subscription.upload_bytes_used.has_value() && subscription.download_bytes_used.has_value() &&
145+
subscription.bytes_total.has_value())
146+
{
147+
m_subscriptionHasDataUsage = true;
148+
m_subscriptionTotalUsed =
149+
HumanizeByte(subscription.upload_bytes_used.value() + subscription.download_bytes_used.value());
150+
m_subscriptionPercentUsed =
151+
(subscription.upload_bytes_used.value() + subscription.download_bytes_used.value()) /
152+
static_cast<double>(subscription.bytes_total.value()) * 100;
153+
}
154+
else
155+
{
156+
m_subscriptionHasDataUsage = false;
157+
m_subscriptionTotalUsed = L"";
158+
m_subscriptionPercentUsed = 0;
159+
}
111160
if (subscription.retrieved_at.has_value())
112161
{
113-
m_subscriptionRetrievedAt = to_hstring(subscription.retrieved_at.value());
162+
m_subscriptionRetrievedAt = FormatNaiveDateTime(subscription.retrieved_at.value().c_str());
163+
}
164+
else
165+
{
166+
m_subscriptionRetrievedAt = L"Never";
167+
}
168+
if (subscription.expires_at.has_value())
169+
{
170+
m_subscriptionExpireAt = FormatNaiveDateTime(subscription.expires_at.value().c_str());
171+
}
172+
else
173+
{
174+
m_subscriptionExpireAt = L"";
114175
}
115176
m_propertyChanged(*this, PropertyChangedEventArgs(L"SubscriptionUrl"));
116177
m_propertyChanged(*this, PropertyChangedEventArgs(L"SubscriptionUploadUsed"));
117178
m_propertyChanged(*this, PropertyChangedEventArgs(L"SubscriptionDownloadUsed"));
179+
m_propertyChanged(*this, PropertyChangedEventArgs(L"SubscriptionTotalUsed"));
180+
m_propertyChanged(*this, PropertyChangedEventArgs(L"SubscriptionPercentUsed"));
181+
m_propertyChanged(*this, PropertyChangedEventArgs(L"SubscriptionHasDataUsage"));
118182
m_propertyChanged(*this, PropertyChangedEventArgs(L"SubscriptionBytesTotal"));
119183
m_propertyChanged(*this, PropertyChangedEventArgs(L"SubscriptionRetrievedAt"));
184+
m_propertyChanged(*this, PropertyChangedEventArgs(L"SubscriptionExpireAt"));
120185
}
121186

122187
IObservableVector<ProxyModel> ProxyGroupModel::Proxies() const

YtFlowApp/ProxyGroupModel.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,19 @@ namespace winrt::YtFlowApp::implementation
2020
hstring Type() const;
2121
void Type(hstring const &value);
2222
bool IsManualGroup() const;
23+
bool IsSubscription() const;
2324
hstring DisplayType() const;
2425
hstring DisplayTypeIcon() const;
2526
hstring TooltipText() const;
2627
hstring SubscriptionUrl() const;
2728
hstring SubscriptionUploadUsed() const;
2829
hstring SubscriptionDownloadUsed() const;
30+
hstring SubscriptionTotalUsed() const;
31+
double SubscriptionPercentUsed() const;
32+
bool SubscriptionHasDataUsage() const;
2933
hstring SubscriptionBytesTotal() const;
3034
hstring SubscriptionRetrievedAt() const;
35+
hstring SubscriptionExpireAt() const;
3136
IObservableVector<ProxyModel> Proxies() const;
3237
void Proxies(IObservableVector<ProxyModel> const &value);
3338
winrt::event_token PropertyChanged(winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler const &handler);
@@ -38,11 +43,13 @@ namespace winrt::YtFlowApp::implementation
3843
bool IsUpdating{false};
3944

4045
private:
41-
uint32_t m_id;
46+
uint32_t m_id{};
4247
hstring m_name;
4348
hstring m_type;
44-
hstring m_subscriptionUrl, m_subscriptionUploadUsed, m_subscriptionDownloadUsed, m_subscriptionBytesTotal,
45-
m_subscriptionRetrievedAt;
49+
hstring m_subscriptionUrl, m_subscriptionUploadUsed, m_subscriptionDownloadUsed, m_subscriptionTotalUsed,
50+
m_subscriptionBytesTotal, m_subscriptionRetrievedAt, m_subscriptionExpireAt;
51+
double m_subscriptionPercentUsed{};
52+
bool m_subscriptionHasDataUsage{false};
4653
IObservableVector<ProxyModel> m_proxies{nullptr};
4754
winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
4855
};

YtFlowApp/UI.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,31 @@ namespace winrt::YtFlowApp::implementation
141141
return L"";
142142
}
143143

144+
hstring FormatNaiveDateTime(char const *dateStr)
145+
{
146+
if (dateStr == nullptr)
147+
{
148+
return L"";
149+
}
150+
151+
std::istringstream ss{dateStr};
152+
153+
using namespace std::chrono;
154+
sys_seconds tp;
155+
time_zone const *tz{};
156+
try
157+
{
158+
tz = current_zone();
159+
}
160+
catch (std::runtime_error const &)
161+
{
162+
}
163+
if (tz == nullptr || !(ss >> parse("%Y-%m-%dT%H:%M:%S", tp)))
164+
{
165+
return L"";
166+
}
167+
168+
auto const ltp = tz->to_local(tp);
169+
return to_hstring(std::format("{:%Y-%m-%d %H:%M:%S}", ltp));
170+
}
144171
}

YtFlowApp/UI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ namespace winrt::YtFlowApp::implementation
1212

1313
hstring HumanizeByte(uint64_t num);
1414
hstring HumanizeByteSpeed(uint64_t num);
15+
hstring FormatNaiveDateTime(char const *dateStr);
1516
}

0 commit comments

Comments
 (0)