Skip to content

Commit

Permalink
feat: 스플래시 스크린 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
potados99 committed Sep 14, 2023
1 parent cd6fc21 commit 56a0abe
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 88 deletions.
64 changes: 9 additions & 55 deletions FocusTimer/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using FocusTimer.Data.DataContext;
using FocusTimer.Features.Splash;
using FocusTimer.Library;
using FocusTimer.Library.Extensions;
using FocusTimer.Library.Utility;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
Expand All @@ -30,77 +33,28 @@ namespace FocusTimer;
public partial class App
{
private log4net.ILog Logger => this.GetLogger();

[STAThread]
public static void Main()
{
SplashWindow.ShowAutoClosed();

var application = new App();
application.InitializeComponent();
application.Run();
}

protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Logger.Info("앱을 시작합니다.");

Modules.Initialize();
Logger.Info("의존성 주입기를 초기화하였습니다.");

Modules.Get<FocusTimerDatabaseContext>().Initialize();
Logger.Info("DB Context를 초기화하였습니다.");

#if !DEBUG
HandleUnhandledExceptions();
#endif
}

private void HandleUnhandledExceptions()
{
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;

Crashes.ShouldProcessErrorReport = _ => true;

AppCenter.Start("66ce761f-2892-41cd-b8f7-95ba75670719", typeof(Analytics), typeof(Crashes));
}

private void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
var e = (Exception) args.ExceptionObject;
Logger.Fatal("처리되지 않은 예외가 발생하여 런타임을 종료합니다.", e);

// 이 곳에서 modal dialog로 시간을 오래 끌게 되면 아래 코드가 실행되지 않습니다.
// 따라서 새 스레드로 빠르게 넘깁니다.
new Thread(() =>
MessageBox.Show("미처 예상하지 못한 문제가 발생하여 프로그램을 종료하게 되었습니다. 프로그램을 다시 실행하면 이 문제에 대한 자세한 정보가 전송됩니다.",
"죄송합니다.")).Start();

var didAppCrash = Crashes.HasCrashedInLastSessionAsync().GetAwaiter().GetResult();
if (didAppCrash)
{
Logger.Info("이전에 발생한 크래시가 있어, 프로그램 종료 전까지 기다립니다.");
var tcs = new TaskCompletionSource<bool>();

Crashes.SentErrorReport += (sender, e) =>
{
Logger.Info("크래시를 보고하였습니다. 이제 프로그램을 종료합니다.");
tcs.SetResult(true);
};

Crashes.FailedToSendErrorReport += (sender, e) =>
{
Logger.Info("크래시를 보내는 데에 실패하였습니다. 이제 프로그램을 종료합니다.");
tcs.SetResult(false);
};

Task.Delay(30 * 1000).ContinueWith(t =>
{
Logger.Info("크래시를 보내는 작업이 30초를 초과하였습니다. 이제 프로그램을 종료합니다.");
tcs.SetResult(false);
});

tcs.Task.GetAwaiter().GetResult();
Current.Shutdown();
}
new AppCenterCrashes().SetupExceptionHandler();
}
}
59 changes: 59 additions & 0 deletions FocusTimer/Features/Splash/SplashWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<Window x:Class="FocusTimer.Features.Splash.SplashWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
WindowStyle="None"
WindowStartupLocation="CenterScreen"
Background="#FF222425"
AllowsTransparency="True"
Topmost="True"
ShowInTaskbar="False"
Title="SplashWindow" Height="240" Width="230">

<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/materialdesigncolor.Grey.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>

<Border CornerRadius="6,6,6,6"
Background="#FFC9C9C9">
<Border BorderThickness="1"
CornerRadius="6,6,6,6"
Background="#FF222425">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
</Grid.RowDefinitions>

<ProgressBar
Grid.Row="1"
Width="36"
Height="36"
IsIndeterminate="True"
Style="{StaticResource MaterialDesignCircularProgressBar}"
Value="0" />

<Label Grid.Row="2"
HorizontalAlignment="Center" VerticalAlignment="Top"
FontSize="14"
Foreground="{StaticResource Text.Primary.Foreground}">
Focus 실행 중...
</Label>
</Grid>
</Border>
</Border>
</Window>
74 changes: 74 additions & 0 deletions FocusTimer/Features/Splash/SplashWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SplashWindow.xaml.cs
// 이 파일은 FocusTimer의 일부입니다.
//
// © 2023 Potados <song@potados.com>
//
// FocusTimer은(는) 자유 소프트웨어입니다.
// GNU General Public License v3.0을 준수하는 범위 내에서
// 누구든지 자유롭게 변경, 수정하거나 배포할 수 있습니다.
//
// 이 프로그램을 공유함으로서 다른 누군가에게 도움이 되기를 바랍니다.
// 다만 프로그램 배포와 함께 아무 것도 보증하지 않습니다. 자세한 내용은
// GNU General Public License를 참고하세요.
//
// 라이센스 전문은 이 프로그램과 함께 제공되었을 것입니다. 만약 아니라면,
// 다음 링크에서 받아볼 수 있습니다: <https://www.gnu.org/licenses/gpl-3.0.txt>

using System.Threading;
using System.Windows;
using System.Windows.Threading;

namespace FocusTimer.Features.Splash;

/// <summary>
/// 시작할 때에 보여줄 스플래시 화면입니다.
/// 새 스레드에서 보여주고, 자동으로 닫힙니다.
/// </summary>
public partial class SplashWindow
{
private static SplashWindow? _splash;

public SplashWindow()
{
InitializeComponent();
}

public static void ShowAutoClosed()
{
var t = new Thread(() =>
{
_splash = new SplashWindow();
_splash.Show();
Dispatcher.Run();
});
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = true;
t.Start();

Dispatcher.CurrentDispatcher.BeginInvoke(
DispatcherPriority.Loaded,
(DispatcherOperationCallback)(arg =>
{
CloseWindowSafe(_splash);
return null;
}),
_splash);
}

private static void CloseWindowSafe(Window? w)
{
if (w == null)
{
return;
}

if (w.Dispatcher.CheckAccess())
{
w.Close();
}
else
{
w.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(w.Close));
}
}
}
55 changes: 33 additions & 22 deletions FocusTimer/FocusTimer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
</PropertyGroup>

<ItemGroup>
<None Remove="Resources\DSEG7Classic-Bold.ttf"/>
<None Remove="Resources\DSEG7Classic-Regular.ttf"/>
<None Remove="Resources\log4net.config"/>
<None Remove="Resources\DSEG7Classic-Bold.ttf" />
<None Remove="Resources\DSEG7Classic-Regular.ttf" />
<None Remove="Resources\log4net.config" />
</ItemGroup>

<ItemGroup>
Expand All @@ -28,24 +28,25 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="CalcBinding" Version="2.5.2"/>
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.5.0"/>
<PackageReference Include="log4net" Version="2.0.15"/>
<PackageReference Include="Meziantou.Framework.Win32.CredentialManager" Version="1.4.2"/>
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="5.0.2"/>
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="5.0.2"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10"/>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0"/>
<PackageReference Include="System.Drawing.Common" Version="7.0.0"/>
<PackageReference Include="CalcBinding" Version="2.5.2" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.5.0" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="MaterialDesignThemes" Version="5.0.0-ci368" />
<PackageReference Include="Meziantou.Framework.Win32.CredentialManager" Version="1.4.2" />
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="5.0.2" />
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\skiasharp\LiveChartsCore.SkiaSharp.WPF\LiveChartsCore.SkiaSharpView.WPF.csproj"/>
<ProjectReference Include="..\skiasharp\LiveChartsCore.SkiaSharp.WPF\LiveChartsCore.SkiaSharpView.WPF.csproj" />
</ItemGroup>

<ItemGroup>
<Resource Include="Resources\DSEG7Classic-Bold.ttf"/>
<Resource Include="Resources\DSEG7Classic-Regular.ttf"/>
<Resource Include="Resources\DSEG7Classic-Bold.ttf" />
<Resource Include="Resources\DSEG7Classic-Regular.ttf" />
</ItemGroup>

<ItemGroup>
Expand Down Expand Up @@ -73,8 +74,8 @@
</ItemGroup>

<ItemGroup>
<ApplicationDefinition Remove="App.xaml"/>
<Page Include="App.xaml"/>
<ApplicationDefinition Remove="App.xaml" />
<Page Include="App.xaml" />
<Page Update="Features\Timer\Slot\TimerSlotControl.xaml">
<Generator>MSBuild:Compile</Generator>
<XamlRuntime>Wpf</XamlRuntime>
Expand All @@ -100,26 +101,36 @@
<XamlRuntime>Wpf</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="Library\Control\CircularProgressBar\MaterialDesignTheme.ProgressBar.xaml">
<Generator>MSBuild:Compile</Generator>
<XamlRuntime>Wpf</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="Features\Splash\SplashWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<XamlRuntime>Wpf</XamlRuntime>
<SubType>Designer</SubType>
</Page>
</ItemGroup>

<Target Name="SetAssemblyVersion" BeforeTargets="BeforeCompile">
<FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
<Output PropertyName="AssemblyVersion" TaskParameter="OutputVersion"/>
<Output PropertyName="AssemblyVersion" TaskParameter="OutputVersion" />
</FormatVersion>
<FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
<Output PropertyName="InformationalVersion" TaskParameter="OutputVersion"/>
<Output PropertyName="InformationalVersion" TaskParameter="OutputVersion" />
</FormatVersion>
<FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
<Output PropertyName="FileVersion" TaskParameter="OutputVersion"/>
<Output PropertyName="FileVersion" TaskParameter="OutputVersion" />
</FormatVersion>
</Target>

<Target Name="AutoSetMinimumRequiredVersion" BeforeTargets="GenerateDeploymentManifest">
<FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
<Output PropertyName="MinimumRequiredVersion" TaskParameter="OutputVersion"/>
<Output PropertyName="MinimumRequiredVersion" TaskParameter="OutputVersion" />
</FormatVersion>
<FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
<Output PropertyName="_DeploymentBuiltMinimumRequiredVersion" TaskParameter="OutputVersion"/>
<Output PropertyName="_DeploymentBuiltMinimumRequiredVersion" TaskParameter="OutputVersion" />
</FormatVersion>
</Target>

Expand Down
Loading

0 comments on commit 56a0abe

Please sign in to comment.