Complete UWP app (without translations)
@@ -79,7 +79,7 @@
|
|||||||
<!-- AboutActivity -->
|
<!-- AboutActivity -->
|
||||||
<string name="aboutTitle">About application</string>
|
<string name="aboutTitle">About application</string>
|
||||||
<string name="appDescription">Application for SPbSUT professors\' and students\' schedule export</string>
|
<string name="appDescription">Application for SPbSUT professors\' and students\' schedule export</string>
|
||||||
<string name="developedBy">Developed by Michael Gordeev (IS-907, INS) in the \"Technologies of Informational and Educational Systems\" Research Facility</string>
|
<string name="developedBy">Developed by Michael Gordeev (ICT-907, INS) in the \"Technologies of Informational and Educational Systems\" Research Facility</string>
|
||||||
<string name="contributorsTitle">Contributors</string>
|
<string name="contributorsTitle">Contributors</string>
|
||||||
|
|
||||||
<string name="specialThanksTitle">Special thanks</string>
|
<string name="specialThanksTitle">Special thanks</string>
|
||||||
|
|||||||
@@ -2,21 +2,64 @@
|
|||||||
x:Class="GUTSchedule.UWP.AboutPage"
|
x:Class="GUTSchedule.UWP.AboutPage"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:GUTSchedule.UWP"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||||
|
Loaded="Page_Loaded">
|
||||||
|
|
||||||
<Page.TopAppBar>
|
<Page.TopAppBar>
|
||||||
<CommandBar ClosedDisplayMode="Compact" Background="{StaticResource SystemAccentColor}" RequestedTheme="Dark">
|
<CommandBar ClosedDisplayMode="Compact" Background="{StaticResource SystemAccentColor}" RequestedTheme="Dark">
|
||||||
<CommandBar.Content>
|
<CommandBar.Content>
|
||||||
<TextBlock Text="About application" Style="{StaticResource TitleTextBlockStyle}" Margin="10,6"/>
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Button Width="48" Height="48" Margin="0" Background="Transparent" Click="BackRequested">
|
||||||
|
<SymbolIcon Symbol="Back"/>
|
||||||
|
</Button>
|
||||||
|
<TextBlock Text="About application" Style="{StaticResource TitleTextBlockStyle}" Margin="10,6" Grid.Column="1"/>
|
||||||
|
</Grid>
|
||||||
</CommandBar.Content>
|
</CommandBar.Content>
|
||||||
</CommandBar>
|
</CommandBar>
|
||||||
</Page.TopAppBar>
|
</Page.TopAppBar>
|
||||||
|
|
||||||
<Grid>
|
<ScrollViewer>
|
||||||
|
<StackPanel Margin="10">
|
||||||
|
<TextBlock Style="{StaticResource TitleTextBlockStyle}" Text="GUT.Schedule"/>
|
||||||
|
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="v$(Build.BuildNumber) (ci-id #$(Build.BuildId))" Foreground="DarkGray" Margin="0,0,0,10" x:Name="version"/>
|
||||||
|
|
||||||
</Grid>
|
<TextBlock Text="appDescription"/>
|
||||||
|
|
||||||
|
<TextBlock Text="developedBy"/>
|
||||||
|
|
||||||
|
<TextBlock x:Name="contributorsTitle" Style="{StaticResource SubtitleTextBlockStyle}" Text="Contributors" Margin="0,10,0,0" Visibility="Collapsed"/>
|
||||||
|
<TextBlock x:Name="contributors" Visibility="Collapsed"/>
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="Special thanks" Margin="0,10,0,0"/>
|
||||||
|
<TextBlock Text="specialThanksPeople"/>
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="Contacts" Margin="0,10,0,0"/>
|
||||||
|
<TextBlock>
|
||||||
|
<Run>Website</Run>: <Hyperlink NavigateUri="https://xfox111.net">https://xfox111.net</Hyperlink><LineBreak/>
|
||||||
|
<Run>Twitter</Run>: <Hyperlink NavigateUri="https://twitter.com/xfox111">@xfox111</Hyperlink><LineBreak/>
|
||||||
|
<Run>VKontakte</Run>: <Hyperlink NavigateUri="https://vk.com/xfox.mike">@xfox.mike</Hyperlink><LineBreak/>
|
||||||
|
<Run>LinkedIn</Run>: <Hyperlink NavigateUri="https://linkedin.com/in/xfox">@xfox</Hyperlink><LineBreak/>
|
||||||
|
<Run>GitHub</Run>: <Hyperlink NavigateUri="https://github.com/xfox111">@xfox111</Hyperlink>
|
||||||
|
</TextBlock>
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="Useful links" Margin="0,10,0,0"/>
|
||||||
|
<TextBlock>
|
||||||
|
<Hyperlink NavigateUri="https://xfox111.net/Projects/GUTSchedule/PrivacyPolicy.txt">Privacy policy</Hyperlink><LineBreak/>
|
||||||
|
<Hyperlink NavigateUri="https://www.gnu.org/licenses/gpl-3.0">General Public License v3</Hyperlink><LineBreak/>
|
||||||
|
<Hyperlink NavigateUri="https://github.com/xfox111/gutschedule">GitHub repository</Hyperlink><LineBreak/>
|
||||||
|
<Hyperlink NavigateUri="http://tios.spbgut.ru/index.php">"TIES" RF</Hyperlink><LineBreak/>
|
||||||
|
<Hyperlink NavigateUri="https://sut.ru">SPbSUT</Hyperlink><LineBreak/>
|
||||||
|
</TextBlock>
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="©2020 Michael "XFox" Gordeev" Margin="0,10,0,0"/>
|
||||||
|
<Button Content="Leave feedback" HorizontalAlignment="Left" Margin="5" Click="Feedback_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
</Page>
|
</Page>
|
||||||
@@ -1,30 +1,90 @@
|
|||||||
using System;
|
using Microsoft.Services.Store.Engagement;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.Net.Http;
|
||||||
using System.Linq;
|
using Windows.ApplicationModel;
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
using Windows.ApplicationModel.Resources;
|
||||||
using Windows.Foundation;
|
using Windows.System;
|
||||||
using Windows.Foundation.Collections;
|
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Controls.Primitives;
|
using Windows.UI.Xaml.Documents;
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
using Windows.UI.Xaml.Input;
|
|
||||||
using Windows.UI.Xaml.Media;
|
|
||||||
using Windows.UI.Xaml.Navigation;
|
|
||||||
|
|
||||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
|
||||||
|
|
||||||
namespace GUTSchedule.UWP
|
namespace GUTSchedule.UWP
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
|
||||||
/// </summary>
|
|
||||||
public sealed partial class AboutPage : Page
|
public sealed partial class AboutPage : Page
|
||||||
{
|
{
|
||||||
|
private readonly ResourceLoader resources = ResourceLoader.GetForCurrentView();
|
||||||
public AboutPage()
|
public AboutPage()
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
InitializeComponent();
|
||||||
|
KeyDown += (s, e) =>
|
||||||
|
{
|
||||||
|
if (e.Key == VirtualKey.Back || e.Key == VirtualKey.GoBack)
|
||||||
|
BackRequested(s, null);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void Page_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
PackageVersion ver = Package.Current.Id.Version;
|
||||||
|
version.Text = $"v{ver.Major}{ver.Major}.{ver.Revision} (ci-id #{ver.Build})";
|
||||||
|
|
||||||
|
List<string> contributorsList = new List<string>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HttpClient client = new HttpClient();
|
||||||
|
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/repos/xfox111/gutschedule/contributors");
|
||||||
|
request.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0");
|
||||||
|
|
||||||
|
HttpResponseMessage response = await client.SendAsync(request);
|
||||||
|
string resposeContent = await response.Content.ReadAsStringAsync();
|
||||||
|
dynamic parsedResponse = JsonConvert.DeserializeObject(resposeContent);
|
||||||
|
|
||||||
|
foreach (var i in parsedResponse)
|
||||||
|
if (i.type == "User" && ((string)i.login).ToLower() != "xfox111")
|
||||||
|
contributorsList.Add((string)i.login);
|
||||||
|
|
||||||
|
request.Dispose();
|
||||||
|
client.Dispose();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (contributorsList.Count > 0)
|
||||||
|
{
|
||||||
|
foreach(string i in contributorsList)
|
||||||
|
{
|
||||||
|
Hyperlink link = new Hyperlink
|
||||||
|
{
|
||||||
|
NavigateUri = new Uri("https://github.com.i")
|
||||||
|
};
|
||||||
|
link.Inlines.Add(new Run
|
||||||
|
{
|
||||||
|
Text = "@" + i
|
||||||
|
});
|
||||||
|
contributors.Inlines.Add(link);
|
||||||
|
contributors.Inlines.Add(new Run
|
||||||
|
{
|
||||||
|
Text = ", "
|
||||||
|
});
|
||||||
|
}
|
||||||
|
contributors.Inlines.RemoveAt(contributors.Inlines.Count - 1);
|
||||||
|
|
||||||
|
contributorsTitle.Visibility = Visibility.Visible;
|
||||||
|
contributors.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void Feedback_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (StoreServicesFeedbackLauncher.IsSupported())
|
||||||
|
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
|
||||||
|
else
|
||||||
|
await Launcher.LaunchUriAsync(new Uri("mailto:feedback@xfox111.net"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BackRequested(object sender, RoutedEventArgs e) =>
|
||||||
|
Frame.GoBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<Application
|
<Application
|
||||||
x:Class="GUTSchedule.UWP.App"
|
x:Class="GUTSchedule.UWP.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
RequestedTheme="Light">
|
||||||
|
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<Style TargetType="Button">
|
<Style TargetType="Button">
|
||||||
|
|||||||
@@ -38,11 +38,9 @@ namespace GUTSchedule.UWP
|
|||||||
/// <param name="e">Details about the launch request and process.</param>
|
/// <param name="e">Details about the launch request and process.</param>
|
||||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||||
{
|
{
|
||||||
Frame rootFrame = Window.Current.Content as Frame;
|
|
||||||
|
|
||||||
// Do not repeat app initialization when the Window already has content,
|
// Do not repeat app initialization when the Window already has content,
|
||||||
// just ensure that the window is active
|
// just ensure that the window is active
|
||||||
if (rootFrame == null)
|
if (!(Window.Current.Content is Frame rootFrame))
|
||||||
{
|
{
|
||||||
// Create a Frame to act as the navigation context and navigate to the first page
|
// Create a Frame to act as the navigation context and navigate to the first page
|
||||||
rootFrame = new Frame();
|
rootFrame = new Frame();
|
||||||
|
|||||||
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 525 B |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 525 B |
|
After Width: | Height: | Size: 766 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 32 KiB |
@@ -1,17 +1,59 @@
|
|||||||
using GUTSchedule.Models;
|
using GUTSchedule.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Windows.ApplicationModel.Appointments;
|
||||||
|
|
||||||
namespace GUTSchedule.UWP
|
namespace GUTSchedule.UWP
|
||||||
{
|
{
|
||||||
public static class Calendar
|
public static class Calendar
|
||||||
{
|
{
|
||||||
public static void Export(List<Occupation> schedule)
|
public static async Task<IReadOnlyList<AppointmentCalendar>> GetCalendars()
|
||||||
{
|
{
|
||||||
|
AppointmentStore calendarStore = await AppointmentManager.RequestStoreAsync(AppointmentStoreAccessType.AllCalendarsReadWrite);
|
||||||
|
return await calendarStore.FindAppointmentCalendarsAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task Export(List<Occupation> schedule, bool addGroupToTitle, int reminder, string calendar)
|
||||||
|
{
|
||||||
|
AppointmentStore calendarStore = await AppointmentManager.RequestStoreAsync(AppointmentStoreAccessType.AllCalendarsReadWrite);
|
||||||
|
AppointmentCalendar cal = await calendarStore.GetAppointmentCalendarAsync(calendar);
|
||||||
|
|
||||||
|
foreach (Occupation item in schedule)
|
||||||
|
{
|
||||||
|
Appointment appointment = new Appointment
|
||||||
|
{
|
||||||
|
BusyStatus = AppointmentBusyStatus.Busy,
|
||||||
|
Details = item.Opponent + "\xFEFF",
|
||||||
|
DetailsKind = AppointmentDetailsKind.PlainText,
|
||||||
|
Location = item.Cabinet,
|
||||||
|
Reminder = reminder < 0 ? (TimeSpan?)null : TimeSpan.FromMinutes(reminder),
|
||||||
|
Subject = string.Format("{0}.{1} {2} ({3})",
|
||||||
|
item.Order,
|
||||||
|
addGroupToTitle && !string.IsNullOrWhiteSpace(item.Group) ? $" [{item.Group}]" : "",
|
||||||
|
item.Name,
|
||||||
|
item.Type),
|
||||||
|
StartTime = item.StartTime,
|
||||||
|
Duration = item.EndTime.Subtract(item.StartTime)
|
||||||
|
};
|
||||||
|
|
||||||
|
await cal.SaveAppointmentAsync(appointment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task Clear(bool keepPrevious = true)
|
||||||
|
{
|
||||||
|
AppointmentStore appointmentStore = await AppointmentManager.RequestStoreAsync(AppointmentStoreAccessType.AppCalendarsReadWrite);
|
||||||
|
|
||||||
|
List<Appointment> appointments = (await appointmentStore.FindAppointmentsAsync(keepPrevious ? DateTime.Today : DateTime.Today.Subtract(TimeSpan.FromDays(3000)), TimeSpan.FromDays(10000))).ToList();
|
||||||
|
|
||||||
|
foreach(Appointment i in appointments)
|
||||||
|
if (i.Details.Contains('\xFEFF'))
|
||||||
|
{
|
||||||
|
AppointmentCalendar cal = await appointmentStore.GetAppointmentCalendarAsync(i.CalendarId);
|
||||||
|
await cal.DeleteAppointmentAsync(i.LocalId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,13 +134,52 @@
|
|||||||
</AppxManifest>
|
</AppxManifest>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Content Include="Assets\LargeTile.scale-100.png" />
|
||||||
|
<Content Include="Assets\LargeTile.scale-125.png" />
|
||||||
|
<Content Include="Assets\LargeTile.scale-150.png" />
|
||||||
|
<Content Include="Assets\LargeTile.scale-200.png" />
|
||||||
|
<Content Include="Assets\LargeTile.scale-400.png" />
|
||||||
|
<Content Include="Assets\SmallTile.scale-100.png" />
|
||||||
|
<Content Include="Assets\SmallTile.scale-125.png" />
|
||||||
|
<Content Include="Assets\SmallTile.scale-150.png" />
|
||||||
|
<Content Include="Assets\SmallTile.scale-200.png" />
|
||||||
|
<Content Include="Assets\SmallTile.scale-400.png" />
|
||||||
|
<Content Include="Assets\SplashScreen.scale-100.png" />
|
||||||
|
<Content Include="Assets\SplashScreen.scale-125.png" />
|
||||||
|
<Content Include="Assets\SplashScreen.scale-150.png" />
|
||||||
|
<Content Include="Assets\SplashScreen.scale-400.png" />
|
||||||
|
<Content Include="Assets\Square150x150Logo.scale-100.png" />
|
||||||
|
<Content Include="Assets\Square150x150Logo.scale-125.png" />
|
||||||
|
<Content Include="Assets\Square150x150Logo.scale-150.png" />
|
||||||
|
<Content Include="Assets\Square150x150Logo.scale-400.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-16.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-256.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-32.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-48.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.scale-100.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.scale-125.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.scale-150.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.scale-400.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-16.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-24.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-256.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-32.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-48.png" />
|
||||||
|
<Content Include="Assets\StoreLogo.scale-100.png" />
|
||||||
|
<Content Include="Assets\StoreLogo.scale-125.png" />
|
||||||
|
<Content Include="Assets\StoreLogo.scale-150.png" />
|
||||||
|
<Content Include="Assets\StoreLogo.scale-200.png" />
|
||||||
|
<Content Include="Assets\StoreLogo.scale-400.png" />
|
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-100.png" />
|
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-125.png" />
|
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-150.png" />
|
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
|
||||||
<Content Include="Properties\Default.rd.xml" />
|
<Content Include="Properties\Default.rd.xml" />
|
||||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||||
<Content Include="Assets\StoreLogo.png" />
|
|
||||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -161,6 +200,12 @@
|
|||||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||||
<Version>6.2.9</Version>
|
<Version>6.2.9</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Services.Store.Engagement">
|
||||||
|
<Version>10.1901.28001</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>12.0.3</Version>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\GUTSchedule\GUTSchedule.csproj">
|
<ProjectReference Include="..\GUTSchedule\GUTSchedule.csproj">
|
||||||
@@ -168,6 +213,17 @@
|
|||||||
<Name>GUTSchedule</Name>
|
<Name>GUTSchedule</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PRIResource Include="Strings\en-US\Resources.resw" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<SDKReference Include="Microsoft.Services.Store.Engagement, Version=10.0">
|
||||||
|
<Name>Microsoft Engagement Framework</Name>
|
||||||
|
</SDKReference>
|
||||||
|
<SDKReference Include="Microsoft.VCLibs, Version=14.0">
|
||||||
|
<Name>Visual C++ 2015 Runtime for Universal Windows Platform Apps</Name>
|
||||||
|
</SDKReference>
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -5,13 +5,14 @@
|
|||||||
xmlns:local="using:GUTSchedule.UWP"
|
xmlns:local="using:GUTSchedule.UWP"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d"
|
||||||
|
Loaded="Page_Loaded">
|
||||||
|
|
||||||
<Page.Background>
|
<Page.Background>
|
||||||
<ImageBrush ImageSource="https://cabs.itut.ru/cabinet/ini/general/0/cabinet/img/bg_n.jpg" Stretch="UniformToFill"/>
|
<ImageBrush ImageSource="https://cabs.itut.ru/cabinet/ini/general/0/cabinet/img/bg_n.jpg" Stretch="UniformToFill"/>
|
||||||
</Page.Background>
|
</Page.Background>
|
||||||
|
|
||||||
<VisualStateManager.VisualStateGroups>
|
<!--<VisualStateManager.VisualStateGroups>
|
||||||
<VisualStateGroup>
|
<VisualStateGroup>
|
||||||
<VisualState>
|
<VisualState>
|
||||||
<VisualState.StateTriggers>
|
<VisualState.StateTriggers>
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
</VisualState.Setters>
|
</VisualState.Setters>
|
||||||
</VisualState>
|
</VisualState>
|
||||||
</VisualStateGroup>
|
</VisualStateGroup>
|
||||||
</VisualStateManager.VisualStateGroups>
|
</VisualStateManager.VisualStateGroups>-->
|
||||||
|
|
||||||
<Page.TopAppBar>
|
<Page.TopAppBar>
|
||||||
<CommandBar ClosedDisplayMode="Compact" Background="{StaticResource SystemAccentColor}" RequestedTheme="Dark">
|
<CommandBar ClosedDisplayMode="Compact" Background="{StaticResource SystemAccentColor}" RequestedTheme="Dark">
|
||||||
@@ -55,21 +56,21 @@
|
|||||||
<StackPanel Padding="10" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
<StackPanel Padding="10" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="Schedule parameters"/>
|
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="Schedule parameters"/>
|
||||||
|
|
||||||
<CheckBox Content="Authorize via personal cabinet" Checked="ChangeAuthorizationMethod" IsChecked="True" x:Name="authorize"/>
|
<CheckBox Content="Authorize via personal cabinet" Checked="ChangeAuthorizationMethod" Unchecked="ChangeAuthorizationMethod" IsChecked="True" x:Name="authorize"/>
|
||||||
<StackPanel x:Name="credentialMethod">
|
<StackPanel x:Name="credentialMethod">
|
||||||
<TextBox PlaceholderText="E-mail" x:Name="email"/>
|
<TextBox PlaceholderText="E-mail" x:Name="email"/>
|
||||||
<PasswordBox PlaceholderText="Password" x:Name="password"/>
|
<PasswordBox PlaceholderText="Password" x:Name="password"/>
|
||||||
<CheckBox Content="Remember" x:Name="rememberCredential" IsChecked="True"/>
|
<CheckBox Content="Remember" x:Name="rememberCredential" Checked="RememberCredential_Checked" Unchecked="RememberCredential_Checked"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel x:Name="defaultMethod" Visibility="Collapsed">
|
<StackPanel x:Name="defaultMethod" Visibility="Collapsed">
|
||||||
<ComboBox x:Name="faculty" PlaceholderText="No schedule is available" Header="Course" SelectionChanged="Faculty_SelectionChanged"/>
|
<ComboBox x:Name="faculty" PlaceholderText="No schedule is available" Header="Course" SelectionChanged="Faculty_SelectionChanged"/>
|
||||||
<ComboBox x:Name="course" SelectedIndex="0" Header="Course" SelectionChanged="Course_SelectionChanged">
|
<ComboBox x:Name="course" Header="Course" SelectionChanged="Course_SelectionChanged">
|
||||||
<ComboBoxItem Content="1"/>
|
<ComboBoxItem Content="1"/>
|
||||||
<ComboBoxItem Content="2"/>
|
<ComboBoxItem Content="2"/>
|
||||||
<ComboBoxItem Content="3"/>
|
<ComboBoxItem Content="3"/>
|
||||||
<ComboBoxItem Content="4"/>
|
<ComboBoxItem Content="4"/>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<ComboBox x:Name="group" PlaceholderText="No schedule is available" Header="Group"/>
|
<ComboBox x:Name="group" PlaceholderText="No schedule is available" Header="Group" SelectionChanged="Group_SelectionChanged"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="Export parameters"/>
|
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="Export parameters"/>
|
||||||
@@ -96,21 +97,22 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<ComboBox Header="Set reminder for:" x:Name="reminder" SelectedIndex="0">
|
<ComboBox Header="Set reminder for:" x:Name="reminder" SelectionChanged="Reminder_SelectionChanged">
|
||||||
<ComboBoxItem Content="None"/>
|
|
||||||
<ComboBoxItem Content="None"/>
|
|
||||||
<ComboBoxItem Content="None"/>
|
<ComboBoxItem Content="None"/>
|
||||||
|
<ComboBoxItem Content="At the begining of event"/>
|
||||||
|
<ComboBoxItem Content="5 minutes"/>
|
||||||
|
<ComboBoxItem Content="10 minutes"/>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
|
||||||
<CheckBox Content="Add group number to event title" x:Name="addGroupToTitle"/>
|
<CheckBox Content="Add group number to event title" x:Name="addGroupToTitle" Checked="AddGroupToTitle_Checked" Unchecked="AddGroupToTitle_Checked"/>
|
||||||
|
|
||||||
<ComboBox Header="Destination calendar" x:Name="calendar" SelectedIndex="0" PlaceholderText="No calendar is available"/>
|
<ComboBox Header="Destination calendar" x:Name="calendar" SelectionChanged="Calendar_SelectionChanged"/>
|
||||||
|
|
||||||
<TextBlock Foreground="Red" Visibility="Collapsed" Text="Error" x:Name="errorPlaceholder"/>
|
<TextBlock Foreground="Red" Visibility="Collapsed" Text="Error" x:Name="errorPlaceholder"/>
|
||||||
<Button Content="Add schedule" Background="{StaticResource SystemAccentColor}" RequestedTheme="Dark" FontWeight="Bold" Margin="0,10" Click="Export"/>
|
<Button Content="Add schedule" Background="{StaticResource SystemAccentColor}" Foreground="White" FontWeight="Bold" Margin="0,10" Click="Export"/>
|
||||||
|
|
||||||
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="©2020 Michael Gordeev, INS, ICT-907"/>
|
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="©2020 Michael Gordeev, INS, ICT-907"/>
|
||||||
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="v$(Build.BuildNumber) (ci-id #$(Build.BuildId))"/>
|
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="v$(Build.BuildNumber) (ci-id #$(Build.BuildId))" x:Name="version"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
@@ -118,7 +120,7 @@
|
|||||||
<Grid Background="{StaticResource SystemAccentColor}" x:Name="loading" Visibility="Collapsed">
|
<Grid Background="{StaticResource SystemAccentColor}" x:Name="loading" Visibility="Collapsed">
|
||||||
<StackPanel VerticalAlignment="Center">
|
<StackPanel VerticalAlignment="Center">
|
||||||
<ProgressRing Width="100" Height="100" Foreground="White" IsActive="True" HorizontalAlignment="Center"/>
|
<ProgressRing Width="100" Height="100" Foreground="White" IsActive="True" HorizontalAlignment="Center"/>
|
||||||
<TextBlock Style="{StaticResource TitleTextBlockStyle}" x:Name="status" Text="Processing..." HorizontalAlignment="Center" Foreground="White"/>
|
<TextBlock Style="{StaticResource TitleTextBlockStyle}" x:Name="status" Text="Processing..." HorizontalAlignment="Center" Foreground="White" Margin="0,20"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -11,47 +11,75 @@ using Windows.UI.Popups;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Windows.ApplicationModel.Resources;
|
using Windows.ApplicationModel.Resources;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
|
using Microsoft.Services.Store.Engagement;
|
||||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
|
using Windows.ApplicationModel;
|
||||||
|
|
||||||
namespace GUTSchedule.UWP
|
namespace GUTSchedule.UWP
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
|
||||||
/// </summary>
|
|
||||||
public sealed partial class MainPage : Page
|
public sealed partial class MainPage : Page
|
||||||
{
|
{
|
||||||
private readonly PasswordVault vault = new PasswordVault();
|
private readonly PasswordVault vault = new PasswordVault();
|
||||||
private readonly ResourceLoader resources = ResourceLoader.GetForCurrentView();
|
private readonly ResourceLoader resources = ResourceLoader.GetForCurrentView();
|
||||||
static readonly ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
static readonly ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
||||||
|
|
||||||
public static List<(string id, string name)> Faculties { get; set; }
|
public MainPage() =>
|
||||||
|
|
||||||
public MainPage()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
startDate.Date = DateTime.Today;
|
|
||||||
endDate.Date = startDate.Date.Value.AddDays(6);
|
|
||||||
|
|
||||||
if (vault.FindAllByResource("xfox111.gutschedule") is IReadOnlyList<PasswordCredential> credentials && credentials.Count > 0)
|
private async void Page_Loaded(object sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PackageVersion ver = Package.Current.Id.Version;
|
||||||
|
version.Text = $"v{ver.Major}{ver.Major}.{ver.Revision} (ci-id #{ver.Build})";
|
||||||
|
|
||||||
|
authorize.IsChecked = (bool?)settings.Values["Authorize"] ?? true;
|
||||||
|
if (vault.RetrieveAll() is IReadOnlyList<PasswordCredential> credentials && credentials.Count > 0)
|
||||||
{
|
{
|
||||||
email.Text = credentials.First().UserName;
|
email.Text = credentials.First().UserName;
|
||||||
credentials.First().RetrievePassword();
|
credentials.First().RetrievePassword();
|
||||||
password.Password = credentials.First().Password;
|
password.Password = credentials.First().Password;
|
||||||
}
|
}
|
||||||
|
|
||||||
authorize.IsChecked = (bool?)settings.Values["Authorize"] ?? true;
|
|
||||||
rememberCredential.IsChecked = (bool?)settings.Values["RememberCredential"] ?? true;
|
rememberCredential.IsChecked = (bool?)settings.Values["RememberCredential"] ?? true;
|
||||||
reminder.SelectedIndex = (int?)settings.Values["Reminder"] ?? 1;
|
|
||||||
addGroupToTitle.IsChecked = (bool?)settings.Values["AddGroupToTitle"] ?? false;
|
|
||||||
|
|
||||||
faculty.ItemsSource = Faculties.Select(i => new ComboBoxItem
|
faculty.ItemsSource = (await Parser.GetFaculties()).Select(i => new ComboBoxItem
|
||||||
{
|
{
|
||||||
Content = i.name,
|
Content = i.name,
|
||||||
Tag = i.id
|
Tag = i.id,
|
||||||
});
|
IsSelected = (string)settings.Values["Faculty"] == i.id
|
||||||
faculty.SelectedIndex = (int?)settings.Values["Faculty"] ?? 0;
|
}).ToList();
|
||||||
|
faculty.SelectedIndex = (faculty.ItemsSource as List<ComboBoxItem>).FindIndex(i => i.IsSelected);
|
||||||
|
if (faculty.SelectedIndex < 0)
|
||||||
|
faculty.SelectedIndex = 0;
|
||||||
course.SelectedIndex = (int?)settings.Values["Course"] ?? 0;
|
course.SelectedIndex = (int?)settings.Values["Course"] ?? 0;
|
||||||
|
|
||||||
|
startDate.Date = DateTime.Today;
|
||||||
|
endDate.Date = startDate.Date.Value.AddDays(6);
|
||||||
|
|
||||||
|
reminder.SelectedIndex = (int?)settings.Values["Reminder"] ?? 2;
|
||||||
|
addGroupToTitle.IsChecked = (bool?)settings.Values["AddGroupToTitle"] ?? false;
|
||||||
|
|
||||||
|
calendar.ItemsSource = (await Calendar.GetCalendars()).Select(i => new ComboBoxItem
|
||||||
|
{
|
||||||
|
Content = i.DisplayName,
|
||||||
|
Tag = i.LocalId,
|
||||||
|
IsSelected = (string)settings.Values["Calendar"] == i.LocalId
|
||||||
|
}).ToList();
|
||||||
|
calendar.SelectedIndex = (calendar.ItemsSource as List<ComboBoxItem>).FindIndex(i => i.IsSelected);
|
||||||
|
if (calendar.SelectedIndex < 0)
|
||||||
|
calendar.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
catch (HttpRequestException e)
|
||||||
|
{
|
||||||
|
PushInternetExceptionMessage(e, () => Page_Loaded(sender, args));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageDialog dialog = new MessageDialog(e.Message, e.GetType().ToString());
|
||||||
|
dialog.Commands.Add(new UICommand("OK", (command) => loading.Visibility = Visibility.Collapsed));
|
||||||
|
|
||||||
|
await dialog.ShowAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AppBarButton_Click(object sender, RoutedEventArgs e)
|
private async void AppBarButton_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -59,11 +87,23 @@ namespace GUTSchedule.UWP
|
|||||||
switch (((FrameworkElement)sender).Tag)
|
switch (((FrameworkElement)sender).Tag)
|
||||||
{
|
{
|
||||||
case "clear":
|
case "clear":
|
||||||
|
MessageDialog dialog = new MessageDialog(resources.GetString("clearScheduleMessage"), resources.GetString("clearScheduleTitle"));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("clearUpcomingOption"), (command) => Clear()));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("clearAllOption"), (command) => Clear(true)));
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("cancelOption")));
|
||||||
|
|
||||||
|
dialog.CancelCommandIndex = 2;
|
||||||
|
dialog.DefaultCommandIndex = 0;
|
||||||
|
|
||||||
|
await dialog.ShowAsync();
|
||||||
break;
|
break;
|
||||||
case "about":
|
case "about":
|
||||||
Frame.Navigate(typeof(AboutPage));
|
Frame.Navigate(typeof(AboutPage));
|
||||||
break;
|
break;
|
||||||
case "report":
|
case "report":
|
||||||
|
if (StoreServicesFeedbackLauncher.IsSupported())
|
||||||
|
await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
|
||||||
|
else
|
||||||
await Launcher.LaunchUriAsync(new Uri("mailto:feedback@xfox111.net"));
|
await Launcher.LaunchUriAsync(new Uri("mailto:feedback@xfox111.net"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -71,23 +111,28 @@ namespace GUTSchedule.UWP
|
|||||||
|
|
||||||
private void ChangeAuthorizationMethod(object sender, RoutedEventArgs e)
|
private void ChangeAuthorizationMethod(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (credentialMethod == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (authorize.IsChecked.Value)
|
if (authorize.IsChecked.Value)
|
||||||
{
|
{
|
||||||
credentialMethod.Visibility = Visibility.Visible;
|
credentialMethod.Visibility = Visibility.Visible;
|
||||||
credentialMethod.Visibility = Visibility.Collapsed;
|
defaultMethod.Visibility = Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
credentialMethod.Visibility = Visibility.Collapsed;
|
credentialMethod.Visibility = Visibility.Collapsed;
|
||||||
credentialMethod.Visibility = Visibility.Visible;
|
defaultMethod.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settings.Values["Authorize"] = authorize.IsChecked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetTodayDate(object sender, RoutedEventArgs e) =>
|
private void SetTodayDate(object sender, RoutedEventArgs e) =>
|
||||||
startDate.Date = DateTime.Today;
|
startDate.Date = DateTime.Today;
|
||||||
|
|
||||||
private void SetEndDate(object sender, RoutedEventArgs e) =>
|
private void SetEndDate(object sender, RoutedEventArgs e) =>
|
||||||
endDate.Date = startDate.Date.Value.AddDays((int)((FrameworkElement)sender).Tag);
|
endDate.Date = startDate.Date.Value.AddDays(int.Parse(((FrameworkElement)sender).Tag as string));
|
||||||
|
|
||||||
private void SetForSemester(object sender, RoutedEventArgs e)
|
private void SetForSemester(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -130,9 +175,14 @@ namespace GUTSchedule.UWP
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (rememberCredential.IsChecked.Value)
|
if (rememberCredential.IsChecked.Value)
|
||||||
vault.Add(new PasswordCredential("xfox111.gutschedule", email.Text, password.Password));
|
vault.Add(new PasswordCredential
|
||||||
|
{
|
||||||
|
UserName = email.Text,
|
||||||
|
Password = password.Password,
|
||||||
|
Resource = "xfox111.gutschedule"
|
||||||
|
});
|
||||||
else
|
else
|
||||||
foreach (PasswordCredential credential in vault.FindAllByResource("xfox111.gutschedule"))
|
foreach (PasswordCredential credential in vault.RetrieveAll())
|
||||||
vault.Remove(credential);
|
vault.Remove(credential);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -154,33 +204,22 @@ namespace GUTSchedule.UWP
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
AddGroupToTitle = addGroupToTitle.IsChecked;
|
|
||||||
SelectedCalendarIndex = calendar.SelectedItemPosition;
|
|
||||||
Reminder = (reminder.SelectedIndex - 1) * 5;
|
|
||||||
|
|
||||||
loading.Visibility = Visibility.Visible;
|
loading.Visibility = Visibility.Visible;
|
||||||
|
TopAppBar.Visibility = Visibility.Collapsed;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
status.Text = resources.GetString("loadingStatus");
|
status.Text = resources.GetString("loadingStatus");
|
||||||
|
|
||||||
List<Occupation> schedule = await Parser.GetSchedule(exportParameters);
|
List<Occupation> schedule = await Parser.GetSchedule(exportParameters);
|
||||||
|
|
||||||
status.Text = resources.GetString("calendarExportStatus");
|
status.Text = resources.GetString("calendarExportStatus");
|
||||||
Calendar.Export(schedule);
|
await Calendar.Export(schedule, addGroupToTitle.IsChecked.Value, (reminder.SelectedIndex - 1) * 5, ((ComboBoxItem)calendar.SelectedItem).Tag as string);
|
||||||
|
|
||||||
status.Text = resources.GetString("doneStatus");
|
status.Text = resources.GetString("doneStatus");
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
}
|
}
|
||||||
catch (HttpRequestException e)
|
catch (HttpRequestException e)
|
||||||
{
|
{
|
||||||
MessageDialog dialog = new MessageDialog(resources.GetString("connectionFailMessage"), e.Message);
|
PushInternetExceptionMessage(e, () => Export(sender, args));
|
||||||
dialog.Commands.Add(new UICommand(resources.GetString("repeat"), (command) => Export(sender, args)));
|
|
||||||
dialog.Commands.Add(new UICommand("OK", (command) => loading.Visibility = Visibility.Collapsed));
|
|
||||||
|
|
||||||
dialog.CancelCommandIndex = 1;
|
|
||||||
dialog.DefaultCommandIndex = 0;
|
|
||||||
|
|
||||||
await dialog.ShowAsync();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -192,28 +231,87 @@ namespace GUTSchedule.UWP
|
|||||||
}
|
}
|
||||||
|
|
||||||
loading.Visibility = Visibility.Collapsed;
|
loading.Visibility = Visibility.Collapsed;
|
||||||
|
TopAppBar.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void Clear(bool keepPrevious = true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Calendar.Clear(keepPrevious);
|
||||||
|
|
||||||
|
MessageDialog dialog = new MessageDialog(resources.GetString("clearScheduleDone"), resources.GetString("clearScheduleTitle"));
|
||||||
|
dialog.Commands.Add(new UICommand("OK", (command) => loading.Visibility = Visibility.Collapsed));
|
||||||
|
|
||||||
|
await dialog.ShowAsync();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageDialog dialog = new MessageDialog(e.Message, e.GetType().ToString());
|
||||||
|
dialog.Commands.Add(new UICommand("OK", (command) => loading.Visibility = Visibility.Collapsed));
|
||||||
|
|
||||||
|
await dialog.ShowAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Faculty_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void Faculty_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
UpdateGroupsList();
|
||||||
|
settings.Values["Faculty"] = ((ComboBoxItem)faculty.SelectedItem).Tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Course_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void Course_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
UpdateGroupsList();
|
||||||
|
settings.Values["Course"] = course.SelectedIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Reminder_SelectionChanged(object sender, SelectionChangedEventArgs e) =>
|
||||||
|
settings.Values["Reminder"] = reminder.SelectedIndex;
|
||||||
|
|
||||||
|
private void Calendar_SelectionChanged(object sender, SelectionChangedEventArgs e) =>
|
||||||
|
settings.Values["Calendar"] = (calendar.SelectedItem as ComboBoxItem).Tag;
|
||||||
|
|
||||||
|
private void Group_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if(group.SelectedItem != null)
|
||||||
|
settings.Values["Group"] = ((ComboBoxItem)group.SelectedItem).Tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RememberCredential_Checked(object sender, RoutedEventArgs e) =>
|
||||||
|
settings.Values["RememberCredential"] = rememberCredential.IsChecked;
|
||||||
|
|
||||||
|
private void AddGroupToTitle_Checked(object sender, RoutedEventArgs e) =>
|
||||||
|
settings.Values["AddGroupToTitle"] = rememberCredential.IsChecked;
|
||||||
|
|
||||||
private async void UpdateGroupsList()
|
private async void UpdateGroupsList()
|
||||||
{
|
{
|
||||||
List<(string id, string name)> groups = await Parser.GetGroups(Faculties[faculty.SelectedIndex].id, (course.SelectedIndex + 1).ToString());
|
List<(string id, string name)> groups = await Parser.GetGroups(((ComboBoxItem)faculty.SelectedItem).Tag as string, (course.SelectedIndex + 1).ToString());
|
||||||
group.ItemsSource = groups.Select(i => new ComboBoxItem
|
group.ItemsSource = groups.Select(i => new ComboBoxItem
|
||||||
{
|
{
|
||||||
Content = i.name,
|
Content = i.name,
|
||||||
Tag = i.id
|
Tag = i.id,
|
||||||
});
|
IsSelected = (string)settings.Values["Group"] == i.id
|
||||||
|
}).ToList();
|
||||||
|
group.SelectedIndex = (group.ItemsSource as List<ComboBoxItem>).FindIndex(i => i.IsSelected);
|
||||||
|
if (group.SelectedIndex < 0)
|
||||||
|
group.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
group.SelectedIndex = (int?)settings.Values["Group"] ?? 0;
|
public async void PushInternetExceptionMessage(HttpRequestException e, Action retryAction)
|
||||||
|
{
|
||||||
|
MessageDialog dialog = new MessageDialog(resources.GetString("connectionFailMessage"), e.Message);
|
||||||
|
dialog.Commands.Add(new UICommand(resources.GetString("repeat"), (command) => retryAction()));
|
||||||
|
dialog.Commands.Add(new UICommand("OK", (command) => loading.Visibility = Visibility.Collapsed));
|
||||||
|
|
||||||
|
dialog.CancelCommandIndex = 1;
|
||||||
|
dialog.DefaultCommandIndex = 0;
|
||||||
|
|
||||||
|
await dialog.ShowAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Reminder prefs broken
|
||||||
|
// TODO: Calendar prefs broken
|
||||||
|
// TODO: Faculty prefs broken
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||||
|
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||||
IgnorableNamespaces="uap mp">
|
IgnorableNamespaces="uap mp">
|
||||||
|
|
||||||
<Identity
|
<Identity
|
||||||
@@ -36,9 +37,9 @@
|
|||||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||||
Square44x44Logo="Assets\Square44x44Logo.png"
|
Square44x44Logo="Assets\Square44x44Logo.png"
|
||||||
Description="Application which exports SPbSUT timetable to calendar"
|
Description="Application which exports SPbSUT timetable to calendar"
|
||||||
BackgroundColor="transparent">
|
BackgroundColor="#FF8000">
|
||||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
|
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square71x71Logo="Assets\SmallTile.png" Square310x310Logo="Assets\LargeTile.png"/>
|
||||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
<uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#FF8000"/>
|
||||||
</uap:VisualElements>
|
</uap:VisualElements>
|
||||||
</Application>
|
</Application>
|
||||||
</Applications>
|
</Applications>
|
||||||
@@ -46,5 +47,6 @@
|
|||||||
<Capabilities>
|
<Capabilities>
|
||||||
<Capability Name="internetClient" />
|
<Capability Name="internetClient" />
|
||||||
<uap:Capability Name="appointments"/>
|
<uap:Capability Name="appointments"/>
|
||||||
|
<rescap:Capability Name="appointmentSystem"/>
|
||||||
</Capabilities>
|
</Capabilities>
|
||||||
</Package>
|
</Package>
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="calendarExportStatus" xml:space="preserve">
|
||||||
|
<value>calendarExportStatus</value>
|
||||||
|
</data>
|
||||||
|
<data name="cancelOption" xml:space="preserve">
|
||||||
|
<value>cancelOption</value>
|
||||||
|
</data>
|
||||||
|
<data name="clearAllOption" xml:space="preserve">
|
||||||
|
<value>clearAllOption</value>
|
||||||
|
</data>
|
||||||
|
<data name="clearScheduleDone" xml:space="preserve">
|
||||||
|
<value>clearScheduleDone</value>
|
||||||
|
</data>
|
||||||
|
<data name="clearScheduleMessage" xml:space="preserve">
|
||||||
|
<value>clearScheduleMessage</value>
|
||||||
|
</data>
|
||||||
|
<data name="clearScheduleTitle" xml:space="preserve">
|
||||||
|
<value>clearScheduleTitle</value>
|
||||||
|
</data>
|
||||||
|
<data name="clearUpcomingOption" xml:space="preserve">
|
||||||
|
<value>clearUpcomingOption</value>
|
||||||
|
</data>
|
||||||
|
<data name="connectionFailMessage" xml:space="preserve">
|
||||||
|
<value>connectionFailMessage</value>
|
||||||
|
</data>
|
||||||
|
<data name="doneStatus" xml:space="preserve">
|
||||||
|
<value>doneStatus</value>
|
||||||
|
</data>
|
||||||
|
<data name="groupSelectionError" xml:space="preserve">
|
||||||
|
<value>groupSelectionError</value>
|
||||||
|
</data>
|
||||||
|
<data name="invalidAuthorizationError" xml:space="preserve">
|
||||||
|
<value>invalidAuthorizationError</value>
|
||||||
|
</data>
|
||||||
|
<data name="invalidDateRangeError" xml:space="preserve">
|
||||||
|
<value>invalidDateRangeError</value>
|
||||||
|
</data>
|
||||||
|
<data name="loadingStatus" xml:space="preserve">
|
||||||
|
<value>loadingStatus</value>
|
||||||
|
</data>
|
||||||
|
<data name="repeat" xml:space="preserve">
|
||||||
|
<value>repeat</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -85,7 +85,7 @@ namespace GUTSchedule
|
|||||||
schedule.RemoveAt(k--);
|
schedule.RemoveAt(k--);
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule = schedule.FindAll(i => i.StartTime.Date >= exportParameters.StartDate && i.StartTime.Date <= exportParameters.EndDate);
|
schedule = schedule.FindAll(i => i.StartTime.Date >= exportParameters.StartDate.Date && i.EndTime.Date <= exportParameters.EndDate.Date);
|
||||||
if (schedule.Count < 1)
|
if (schedule.Count < 1)
|
||||||
throw new NullReferenceException("Не удалось найти расписание соответствующее критериям. Ничего не экспортировано");
|
throw new NullReferenceException("Не удалось найти расписание соответствующее критериям. Ничего не экспортировано");
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ namespace GUTSchedule
|
|||||||
DateTime date = new DateTime(DateTime.Today.Year, DateTime.Today.Month >= 8 ? 9 : 2, offsetDay);
|
DateTime date = new DateTime(DateTime.Today.Year, DateTime.Today.Month >= 8 ? 9 : 2, offsetDay);
|
||||||
|
|
||||||
date = date.AddDays(--week * 7);
|
date = date.AddDays(--week * 7);
|
||||||
date = date.AddDays(--weekday);
|
date = date.AddDays(weekday - 1);
|
||||||
|
|
||||||
dates.Add(date);
|
dates.Add(date);
|
||||||
}
|
}
|
||||||
|
|||||||