Skip to content

Commit

Permalink
Merge pull request #64 from zxbmmmmmmmmm/feat/secondary-tiles
Browse files Browse the repository at this point in the history
Feat/secondary tiles
  • Loading branch information
zxbmmmmmmmmm authored Aug 11, 2024
2 parents c69da11 + 458d135 commit 102b0e3
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 19 deletions.
26 changes: 25 additions & 1 deletion FluentWeather.Tasks/NotifyTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
using Windows.ApplicationModel.Resources;
using TileHelper = FluentWeather.Uwp.Shared.Helpers.TileHelper;
using FluentWeather.Uwp.Shared.Helpers;
using Windows.UI.Notifications;
using Windows.UI.StartScreen;
using System.Linq;

namespace FluentWeather.Tasks
{
Expand Down Expand Up @@ -54,7 +57,7 @@ public async void Run(IBackgroundTaskInstance taskInstance)

await PushDaily(lon,lat);
await PushWarnings(lon, lat);

await UpdateSecondaryTiles();

deferral.Complete();
}
Expand Down Expand Up @@ -193,6 +196,27 @@ private void PushTomorrow(List<WeatherDailyBase> data)

}



private async Task UpdateSecondaryTiles()
{
var tiles = await SecondaryTile.FindAllAsync();
foreach (var tile in tiles)
{

var geolocation = Settings.SavedCities.FirstOrDefault(p => p.Location.GetHashCode().ToString() == tile.TileId);
if (Settings.DefaultGeolocation.Location.GetHashCode().ToString() == tile.TileId)
{
geolocation = Settings.DefaultGeolocation;
}
if (geolocation is null)
continue;
var daily = await _dailyForecastProvider.GetDailyForecasts(geolocation.Location.Longitude, geolocation.Location.Latitude);
var dailyNotification= new TileNotification(TileHelper.GenerateForecastTileContent(daily).GetXml()) { Tag = "forecast" };
var updater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(tile.TileId);
updater.Update(dailyNotification);
}
}
}


Expand Down
46 changes: 46 additions & 0 deletions FluentWeather.Uwp.Shared/Helpers/TileHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,57 @@
using FluentWeather.Uwp.Shared.Helpers.ValueConverters;
using Microsoft.Toolkit.Uwp.Notifications;
using Microsoft.Toolkit.Uwp;
using Windows.ApplicationModel;
using Windows.UI.Shell;
using System.Threading.Tasks;
using Windows.UI.StartScreen;
using TileSize = Microsoft.Toolkit.Uwp.Notifications.TileSize;
using System.Linq;

namespace FluentWeather.Uwp.Shared.Helpers
{
public static class TileHelper
{
public static async Task PinSecondaryTileToTaskBarAsync(GeolocationBase geolocation)
{
var access = Windows.ApplicationModel.LimitedAccessFeatures.TryUnlockFeature("com.microsoft.windows.taskbar.requestPinSecondaryTile","jf0w/jdkHVCaehrYkTQLMg==","we3nmnswjxrbg has registered their use of com.microsoft.windows.taskbar.requestPinSecondaryTile with Microsoft and agrees to the terms of use.");

if ((access.Status == LimitedAccessFeatureStatus.Available)||(access.Status == LimitedAccessFeatureStatus.AvailableWithoutToken))
{
TaskbarManager taskbarManager = TaskbarManager.GetDefault();

if (taskbarManager != null)
{
// Initialize the tile (all properties below are required)
var tile = CreateSecondaryTile(geolocation);
// Pin it to the taskbar
bool isPinnedToTaskBar = await taskbarManager.RequestPinSecondaryTileAsync(tile);
}
}
}
public static async Task PinSecondaryTileToStartAsync(GeolocationBase geolocation)
{
if (SecondaryTile.Exists(geolocation.Location.GetHashCode().ToString())) return;
// Pin it to the taskbar
var tile = CreateSecondaryTile(geolocation);
bool isPinned = await tile.RequestCreateAsync();
}

public static SecondaryTile CreateSecondaryTile(GeolocationBase geolocation)
{
var tile = new SecondaryTile(geolocation.Location.GetHashCode().ToString());
tile.DisplayName = geolocation.Name;
tile.Arguments = $"location={geolocation.Location.GetHashCode()}";
tile.VisualElements.Square44x44Logo = new Uri("ms-appx:///Assets/Square44x44Logo.png");
tile.VisualElements.Square150x150Logo = new Uri("ms-appx:///Assets/Square150x150Logo.png");
tile.VisualElements.Square310x310Logo = new Uri("ms-appx:///Assets/LargeTile.png");
tile.VisualElements.Wide310x150Logo = new Uri("ms-appx:///Assets/Wide310x150Logo.png");

tile.VisualElements.ShowNameOnSquare150x150Logo = true;
tile.VisualElements.ShowNameOnWide310x150Logo = true;
tile.VisualElements.ShowNameOnSquare310x310Logo = true;
return tile;
}

public static void UpdateBadge(int value)
{
Expand Down
9 changes: 8 additions & 1 deletion FluentWeather.Uwp/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using FluentWeather.Uwp.Shared.Helpers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Gaming.XboxGameBar;
using FluentWeather.Uwp.ViewModels;

namespace FluentWeather.Uwp;

Expand Down Expand Up @@ -96,7 +97,8 @@ protected override void OnActivated(IActivatedEventArgs e)
{
widgetArgs = e as XboxGameBarWidgetActivatedEventArgs;
}
if (scheme.Equals("weather")){
if (scheme.Equals("weather"))
{

}
}
Expand Down Expand Up @@ -203,6 +205,11 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
}
ActiveArguments = e.Arguments;

if(e.TileId is not null or "")
{
ActiveArguments = e.TileId;
}

if(Common.Settings.IsAnalyticsEnabled)
{
var service = DIContainer.Locator.ServiceProvider.GetService<AppAnalyticsService>();
Expand Down
5 changes: 3 additions & 2 deletions FluentWeather.Uwp/FluentWeather.Uwp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<PropertyGroup>
<LangVersion>latestMajor</LangVersion>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<PackageCertificateThumbprint>273B17C3FD4B2E52382899B29331EFADCD351294</PackageCertificateThumbprint>
<PackageCertificateThumbprint>E39CF1FCA51EDC5BD1FCA218F4565B737622C059</PackageCertificateThumbprint>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
<GenerateTestArtifacts>True</GenerateTestArtifacts>
Expand Down Expand Up @@ -226,6 +226,7 @@
<Compile Include="Helpers\CacheHelper.cs" />
<Compile Include="Helpers\DIFactory.cs" />
<Compile Include="Helpers\Extensions.cs" />
<Compile Include="Helpers\FeatureTokenGenerator.cs" />
<Compile Include="Helpers\HistoricalWeatherHelper.cs" />
<Compile Include="Helpers\InfoBarHelper.cs" />
<Compile Include="Helpers\JumpListHelper.cs" />
Expand Down Expand Up @@ -444,6 +445,7 @@
<Content Include="Assets\Wide310x150Logo.scale-125.png" />
<Content Include="Assets\Wide310x150Logo.scale-150.png" />
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
<None Include="FluentWeather.Uwp_TemporaryKey.pfx" />
<None Include="Package.StoreAssociation.xml" />
<Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
Expand Down Expand Up @@ -695,7 +697,6 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<None Include="App_TemporaryKey.pfx" />
<None Include="settings.xamlstyler" />
<PRIResource Include="Strings\zh-TW\Resources.resw" />
<PRIResource Include="Strings\en-US\Resources.resw" />
Expand Down
Binary file modified FluentWeather.Uwp/FluentWeather.Uwp_TemporaryKey.pfx
Binary file not shown.
51 changes: 51 additions & 0 deletions FluentWeather.Uwp/Helpers/FeatureTokenGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using System.Security.Cryptography;


namespace FluentWeather.Uwp.Helpers
{
static class FeatureTokenGenerator
{
static readonly Dictionary<string, string> LimitedAccessFeaturesMap = new Dictionary<string, string>()
{
{ "com.microsoft.windows.windowdecorations", "425261a8-7f73-4319-8a53-fc13f87e1717" },
{ "com.microsoft.windows.updateorchestrator.1", "20C662033A4007A55375BF00D986C280B41A418F" },
{ "com.microsoft.windows.update.1", "01B2AEA8-7DD5-4066-A081-1E4CD1479CCA" },
{ "com.microsoft.windows.taskbar.requestPinSecondaryTile", "04c19204-10d9-450a-95c4-2910c8f72be3" },
{ "com.microsoft.windows.richeditmath", "RDZCQjY2M0YtQkFDMi00NkIwLUI3NzEtODg4NjMxMEVENkFF" },
{ "com.microsoft.windows.holographic.xrruntime.2", "58AA36EF-7C1A-4A56-9308-FC882F56465A" },
{ "com.microsoft.windows.holographic.xrruntime.1", "036EFF74-8BF2-4249-82AF-92235C6E1A10" },
{ "com.microsoft.windows.holographic.shell", "527f4968-f193-419a-b91f-46b9106e1129" },
{ "com.microsoft.windows.holographic.keyboardcursor_v1", "FE676B8B-E396-4A80-9573-B67542840E5C" },
{ "com.microsoft.windows.callcontrolpublicapi_v1", "6e7e52aa-cddb-4e57-9f1c-7dd511ad7d01" },
{ "com.microsoft.windows.applicationwindow", "e5a85131-319b-4a56-9577-1c1d9c781218" },
{ "com.microsoft.windows.applicationmodel.phonelinetransportdevice_v1", "cb9WIvVfhp+8lFhaSrB6V6zUBGqctteKi/f/9AIeoZ4" },
{ "com.microsoft.windows.applicationmodel.conversationalagent_v1", "hhrovbOc/z8TgeoWheL4RF5vLLJrKNAQpdyvhlTee6I" },
{ "com.microsoft.services.cortana.cortanaactionableinsights_v1", "nEVyyzytE6ankNk1CIAu6sZsh8vKLw3Q7glTOHB11po=" }
};

public static string GenerateTokenFromFeatureId(string featureId)
=> GenerateFeatureToken(featureId, LimitedAccessFeaturesMap[featureId], AppInfo.Current.PackageFamilyName);

public static string GenerateAttestation(string featureId)
=> $"{AppInfo.Current.PackageFamilyName.Split('_').Last()} has registered their use of {featureId} with Microsoft and agrees to the terms of use.";

private static string GenerateFeatureToken(string featureId, string featureKey, string packageIdentity)
{
var fullBytes = Encoding.UTF8.GetBytes($"{featureId}!{featureKey}!{packageIdentity}");
var tokenBytes = new byte[16];
using (var shaCsp = new SHA256CryptoServiceProvider())
{
shaCsp.TransformFinalBlock(fullBytes, 0, fullBytes.Length);
Array.Copy(shaCsp.Hash, tokenBytes, tokenBytes.Length);
}

return Convert.ToBase64String(tokenBytes);
}
}
}
4 changes: 2 additions & 2 deletions FluentWeather.Uwp/Helpers/JumpListHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ public static async Task SetJumpList(GeolocationBase defaultLocation,IEnumerable
}
private static JumpListItem CreateDefaultItem(GeolocationBase geolocation)
{
var item = JumpListItem.CreateWithArguments("City_" + geolocation.Name,geolocation.Name);
var item = JumpListItem.CreateWithArguments(geolocation.Location.GetHashCode().ToString(),geolocation.Name);
item.GroupName = ResourceLoader.GetForCurrentView().GetString("CurrentLocation");
item.Logo = new Uri("ms-appx:///Assets/Icons/CurrentLocation.png");
return item;
}
private static JumpListItem CreateItem(GeolocationBase geolocation)
{
var item = JumpListItem.CreateWithArguments("City_" + geolocation.Name, geolocation.Name);
var item = JumpListItem.CreateWithArguments(geolocation.Location.GetHashCode().ToString(), geolocation.Name);
item.GroupName = ResourceLoader.GetForCurrentView().GetString("SavedLocations");
item.Logo = new Uri("ms-appx:///Assets/Icons/SavedCity.png");
return item;
Expand Down
10 changes: 10 additions & 0 deletions FluentWeather.Uwp/Pages/CitiesPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@
x:Uid="GetHistoricalWeatherItem"
Click="GetHistoricalWeatherItem_Click"
Icon="Download" />
<MenuFlyoutItem
x:Uid="PinSecondaryTilesItem"
Command="{x:Bind vm:CitiesPageViewModel.Instance.PinSecondaryTileCommand}"
CommandParameter="{x:Bind ViewModel.CurrentCity}"
Icon="Pin" />
</MenuFlyout>
</controls:CityItem.ContextFlyout>
</controls:CityItem>
Expand Down Expand Up @@ -92,6 +97,11 @@
Command="{x:Bind vm:CitiesPageViewModel.Instance.DeleteCityCommand}"
CommandParameter="{x:Bind}"
Icon="Delete" />
<MenuFlyoutItem
x:Uid="PinSecondaryTilesItem"
Command="{x:Bind vm:CitiesPageViewModel.Instance.PinSecondaryTileCommand}"
CommandParameter="{x:Bind}"
Icon="Pin" />
</MenuFlyout>
</controls:CityItem.ContextFlyout>
</controls:CityItem>
Expand Down
29 changes: 17 additions & 12 deletions FluentWeather.Uwp/Pages/CitiesPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,30 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
CitiesView.SelectionChanged += CitiesView_SelectionChanged;
if (App.ActiveArguments is null)
{
SetSelectedLocation(Common.Settings.DefaultGeolocation?.Name);
SetSelectedLocation(Common.Settings.DefaultGeolocation?.Location.GetHashCode().ToString());
return;
}
SetSelectedLocation(App.ActiveArguments.Replace("City_", ""));

if (MainPageViewModel.Instance.CurrentGeolocation is null)
{
CitiesPageViewModel.Instance.GetCurrentCity();
}
}

public void SetSelectedLocation(string name)
public void SetSelectedLocation(string hash)
{
if (Common.Settings.DefaultGeolocation?.Name is null)
{
CurrentCityView.SelectedIndex = 0;
return;
}
if (ViewModel.CurrentCity is null || name == ViewModel.CurrentCity.Name)
{
CurrentCityView.SelectedIndex = 0;
return;
}
var location = ViewModel.Cities.FirstOrDefault(p => p.Name == name);
//if (ViewModel.CurrentCity is null || hash == ViewModel.CurrentCity.Location.GetHashCode().ToString())
//{
// CurrentCityView.SelectedIndex = 0;
// return;
//}
var location = ViewModel.Cities.FirstOrDefault(p => p.Location.GetHashCode().ToString() == hash);
if (location is null) return;
var index = ViewModel.Cities.IndexOf(location);
CitiesView.SelectedIndex = index;
Expand All @@ -55,25 +60,25 @@ private void SettingsButton_Click(object sender, RoutedEventArgs e)
((Frame)Parent)?.Navigate(typeof(SettingsPage),null,Theme.GetSplitPaneNavigationTransition());
}

private void CitiesView_SelectionChanged(object sender, SelectionChangedEventArgs e)
private async void CitiesView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (CitiesView.SelectedIndex == -1) return;
CurrentCityView.SelectedIndex = -1;
MainPageViewModel.Instance.CurrentGeolocation = CitiesPageViewModel.Instance.Cities[CitiesView.SelectedIndex];
if (MainPageViewModel.Instance.CurrentGeolocation is null)
{
CitiesPageViewModel.Instance.GetCurrentCity();
await CitiesPageViewModel.Instance.GetCurrentCity();
}
}

private void CurrentCityView_SelectionChanged(object sender, SelectionChangedEventArgs e)
private async void CurrentCityView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (CurrentCityView.SelectedIndex != 0) return;
MainPageViewModel.Instance.CurrentGeolocation = CitiesPageViewModel.Instance.CurrentCity;
CitiesView.SelectedIndex = -1;
if (MainPageViewModel.Instance.CurrentGeolocation is null)
{
CitiesPageViewModel.Instance.GetCurrentCity();
await CitiesPageViewModel.Instance.GetCurrentCity();
}
}

Expand Down
3 changes: 3 additions & 0 deletions FluentWeather.Uwp/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ Split with "|", support Regex</value>
<data name="PersonalizationSettingsExpander.Header" xml:space="preserve">
<value>Personalization</value>
</data>
<data name="PinSecondaryTilesItem.Text" xml:space="preserve">
<value>Pin to Start</value>
</data>
<data name="Pressure" xml:space="preserve">
<value>Pressure</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions FluentWeather.Uwp/Strings/zh-CN/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@
<data name="PersonalizationSettingsExpander.Header" xml:space="preserve">
<value>个性化</value>
</data>
<data name="PinSecondaryTilesItem.Text" xml:space="preserve">
<value>固定到开始菜单</value>
</data>
<data name="Pressure" xml:space="preserve">
<value>气压</value>
</data>
Expand Down
16 changes: 15 additions & 1 deletion FluentWeather.Uwp/ViewModels/CitiesPageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
using Microsoft.Extensions.DependencyInjection;
using FluentWeather.Uwp.Shared;
using FluentWeather.Uwp.Helpers.Analytics;
using FluentWeather.Uwp.Shared.Helpers;
using Windows.ApplicationModel;
using Windows.UI.StartScreen;
using Windows.Networking.Sockets;
using FluentWeather.Tasks;
using Windows.UI.Xaml;

namespace FluentWeather.Uwp.ViewModels;

Expand Down Expand Up @@ -73,13 +79,21 @@ public void SaveCity(GeolocationBase city)
Query = city.Name;
Locator.ServiceProvider.GetService<AppAnalyticsService>()?.TrackCitySaved(city.Name);
}

[RelayCommand]
public void DeleteCity(GeolocationBase item)
{
Cities.Remove(item);
}

public async void GetCurrentCity()
[RelayCommand]
public async Task PinSecondaryTileAsync(GeolocationBase item)
{
await TileHelper.PinSecondaryTileToStartAsync(item);
}


public async Task GetCurrentCity()
{
var location = await LocationHelper.GetGeolocation();
if (Common.Settings.DefaultGeolocation?.Name is null)
Expand Down

0 comments on commit 102b0e3

Please sign in to comment.