├── Work-Timer
├── Assets
│ ├── AppLogo.png
│ ├── StoreLogo.png
│ ├── SplashScreen.scale-200.png
│ ├── LockScreenLogo.scale-200.png
│ ├── Logo
│ │ ├── LargeTile.scale-100.png
│ │ ├── LargeTile.scale-125.png
│ │ ├── LargeTile.scale-150.png
│ │ ├── LargeTile.scale-200.png
│ │ ├── LargeTile.scale-400.png
│ │ ├── SmallTile.scale-100.png
│ │ ├── SmallTile.scale-125.png
│ │ ├── SmallTile.scale-150.png
│ │ ├── SmallTile.scale-200.png
│ │ ├── SmallTile.scale-400.png
│ │ ├── StoreLogo.scale-100.png
│ │ ├── StoreLogo.scale-125.png
│ │ ├── StoreLogo.scale-150.png
│ │ ├── StoreLogo.scale-200.png
│ │ ├── StoreLogo.scale-400.png
│ │ ├── SplashScreen.scale-100.png
│ │ ├── SplashScreen.scale-125.png
│ │ ├── SplashScreen.scale-150.png
│ │ ├── SplashScreen.scale-200.png
│ │ ├── SplashScreen.scale-400.png
│ │ ├── Square44x44Logo.scale-100.png
│ │ ├── Square44x44Logo.scale-125.png
│ │ ├── Square44x44Logo.scale-150.png
│ │ ├── Square44x44Logo.scale-200.png
│ │ ├── Square44x44Logo.scale-400.png
│ │ ├── Wide310x150Logo.scale-100.png
│ │ ├── Wide310x150Logo.scale-125.png
│ │ ├── Wide310x150Logo.scale-150.png
│ │ ├── Wide310x150Logo.scale-200.png
│ │ ├── Wide310x150Logo.scale-400.png
│ │ ├── Square150x150Logo.scale-100.png
│ │ ├── Square150x150Logo.scale-125.png
│ │ ├── Square150x150Logo.scale-150.png
│ │ ├── Square150x150Logo.scale-200.png
│ │ ├── Square150x150Logo.scale-400.png
│ │ ├── Square44x44Logo.targetsize-16.png
│ │ ├── Square44x44Logo.targetsize-24.png
│ │ ├── Square44x44Logo.targetsize-256.png
│ │ ├── Square44x44Logo.targetsize-32.png
│ │ ├── Square44x44Logo.targetsize-48.png
│ │ ├── Square44x44Logo.altform-unplated_targetsize-16.png
│ │ ├── Square44x44Logo.altform-unplated_targetsize-24.png
│ │ ├── Square44x44Logo.altform-unplated_targetsize-256.png
│ │ ├── Square44x44Logo.altform-unplated_targetsize-32.png
│ │ ├── Square44x44Logo.altform-unplated_targetsize-48.png
│ │ ├── Square44x44Logo.altform-lightunplated_targetsize-16.png
│ │ ├── Square44x44Logo.altform-lightunplated_targetsize-24.png
│ │ ├── Square44x44Logo.altform-lightunplated_targetsize-256.png
│ │ ├── Square44x44Logo.altform-lightunplated_targetsize-32.png
│ │ └── Square44x44Logo.altform-lightunplated_targetsize-48.png
│ ├── Square44x44Logo.scale-200.png
│ ├── Wide310x150Logo.scale-200.png
│ ├── Square150x150Logo.scale-200.png
│ └── Square44x44Logo.targetsize-24_altform-unplated.png
├── Others
│ ├── Update_zh_CN.txt
│ └── Update_en_US.txt
├── Template
│ ├── Converter.xaml
│ ├── Text.xaml
│ └── Button.xaml
├── Models
│ ├── Enums
│ │ ├── Settings.cs
│ │ ├── StyleName.cs
│ │ ├── ColorName.cs
│ │ └── LanguageName.cs
│ ├── UI
│ │ ├── DateTimeConverter.cs
│ │ ├── CustomResourceLoader.cs
│ │ └── SelectedColorConverter.cs
│ └── Core
│ │ ├── AppViewModel.Properties.cs
│ │ └── AppViewModel.cs
├── Components
│ ├── Dialog
│ │ ├── ConfirmDialog.xaml
│ │ ├── ConfirmDialog.xaml.cs
│ │ ├── FolderSelectionDialog.xaml
│ │ ├── FolderSelectionDialog.xaml.cs
│ │ ├── FolderDialog.xaml
│ │ └── FolderDialog.xaml.cs
│ ├── Layout
│ │ ├── HistoryPanel.xaml.cs
│ │ ├── FolderPanel.xaml.cs
│ │ ├── SettingPanel.xaml
│ │ ├── HistoryPanel.xaml
│ │ ├── FolderPanel.xaml
│ │ └── SettingPanel.xaml.cs
│ └── Widget
│ │ ├── WorkDurationBlock.xaml
│ │ └── WorkDurationBlock.xaml.cs
├── Properties
│ ├── AssemblyInfo.cs
│ └── Default.rd.xml
├── App.xaml
├── Package.appxmanifest
├── Theme
│ ├── Light.xaml
│ └── Dark.xaml
├── MainPage.xaml.cs
├── App.xaml.cs
├── MainPage.xaml
├── Language
│ ├── zh-CN
│ │ └── Resources.resw
│ └── en-US
│ │ └── Resources.resw
└── Work-Timer.csproj
├── Lib_Share
├── Models
│ ├── StaticExtension.cs
│ ├── StaticString.cs
│ ├── FolderItem.cs
│ └── HistoryItem.cs
├── Properties
│ ├── AssemblyInfo.cs
│ └── Lib_Share.rd.xml
└── Lib_Share.csproj
├── README.md
├── .gitattributes
├── Work-Timer.sln
└── .gitignore
/Work-Timer/Assets/AppLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/AppLogo.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/Work-Timer/Others/Update_zh_CN.txt:
--------------------------------------------------------------------------------
1 | 您已经更新到新版本的《工作计时器》
2 |
3 | 更新内容如下:
4 |
5 | 1. 添加总工作时长设置,并进行UI调整
6 | 2. 添加Github开源地址
--------------------------------------------------------------------------------
/Work-Timer/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/LargeTile.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/LargeTile.scale-100.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/LargeTile.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/LargeTile.scale-125.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/LargeTile.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/LargeTile.scale-150.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/LargeTile.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/LargeTile.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/LargeTile.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/LargeTile.scale-400.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SmallTile.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SmallTile.scale-100.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SmallTile.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SmallTile.scale-125.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SmallTile.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SmallTile.scale-150.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SmallTile.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SmallTile.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SmallTile.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SmallTile.scale-400.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/StoreLogo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/StoreLogo.scale-100.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/StoreLogo.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/StoreLogo.scale-125.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/StoreLogo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/StoreLogo.scale-150.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/StoreLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/StoreLogo.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/StoreLogo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/StoreLogo.scale-400.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SplashScreen.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SplashScreen.scale-100.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SplashScreen.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SplashScreen.scale-125.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SplashScreen.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SplashScreen.scale-150.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/SplashScreen.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/SplashScreen.scale-400.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.scale-100.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.scale-125.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.scale-150.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.scale-400.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Wide310x150Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Wide310x150Logo.scale-100.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Wide310x150Logo.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Wide310x150Logo.scale-125.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Wide310x150Logo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Wide310x150Logo.scale-150.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Wide310x150Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Wide310x150Logo.scale-400.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square150x150Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square150x150Logo.scale-100.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square150x150Logo.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square150x150Logo.scale-125.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square150x150Logo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square150x150Logo.scale-150.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square150x150Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square150x150Logo.scale-400.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-16.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-24.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-256.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-32.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.targetsize-48.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-16.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-24.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-256.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-32.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-unplated_targetsize-48.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-16.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-24.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-256.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-32.png
--------------------------------------------------------------------------------
/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Richasy/Work-Timer/HEAD/Work-Timer/Assets/Logo/Square44x44Logo.altform-lightunplated_targetsize-48.png
--------------------------------------------------------------------------------
/Work-Timer/Template/Converter.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Work-Timer/Models/Enums/Settings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace WorkTimer.Models.Enums
8 | {
9 | public enum Settings
10 | {
11 | Theme,
12 | AppVersion,
13 | Language,
14 | FontFamily,
15 | LastSelectFolderId,
16 | PresetDuration
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Lib_Share/Models/StaticExtension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Lib.Share.Models
8 | {
9 | public static class StaticExtension
10 | {
11 | public static bool IsNullOrEmpty(this IEnumerable collection)
12 | {
13 | return collection == null || collection.Count() == 0;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Work-Timer/Models/Enums/StyleName.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace WorkTimer.Models.Enums
8 | {
9 | public enum StyleName
10 | {
11 | DefaultActionButtonStyle,
12 | SubtitleTextStyle,
13 | PopupHeaderButtonStyle,
14 | PrimaryActionButtonStyle,
15 | BasicMarkdownTextBlock,
16 | BasicCenterPopupStyle
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Work-Timer/Models/Enums/ColorName.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace WorkTimer.Models.Enums
8 | {
9 | public enum ColorName
10 | {
11 | PageBackground,
12 | PrimaryColor,
13 | PrimaryColorOver,
14 | PrimaryColorOpacity,
15 | SecondaryColor,
16 | SecondaryColorOver,
17 | SecondaryColorOpacity,
18 | ErrorColor,
19 | MaskBackground,
20 | CardBackground
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Work-Timer/Others/Update_en_US.txt:
--------------------------------------------------------------------------------
1 | You have updated to the new version of 《Working Timer》
2 |
3 | The application is a simple timing tool, and only one timer can exist at a time.
4 |
5 | In the new version, you can create a folder on the left side (click the button in the lower left corner to call out) to classify the timer.
6 |
7 | You can check the timer history of the current folder on the right (click the button in the lower right corner to call out).
8 |
9 | There is no *pause* in the timer. Once stopped, it will be recorded under the currently selected folder. You can view the currently selected folder name at the bottom of the interface.
--------------------------------------------------------------------------------
/Work-Timer/Models/Enums/LanguageName.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace WorkTimer.Models.Enums
8 | {
9 | public enum LanguageName
10 | {
11 | Default,
12 | HasAddedHistoryItem,
13 | FolderDialogTitle,
14 | FolderDialogDescription,
15 | Confirm,
16 | Cancel,
17 | Warning,
18 | FieldEmpty,
19 | ConfirmRemoveFolder,
20 | NeedOneFolder,
21 | ConfirmRemoveHistory,
22 | StaticResourceRestart,
23 | RestartNow,
24 | Settings,
25 | UpdateTitle,
26 | Waiting,
27 | MoveHistory
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Work-Timer/Models/UI/DateTimeConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Windows.UI.Xaml.Data;
7 |
8 | namespace WorkTimer.Models.UI
9 | {
10 | public class DateTimeConverter:IValueConverter
11 | {
12 | public object Convert(object value, Type targetType, object parameter, string language)
13 | {
14 | var date = (DateTime)value;
15 | return date.ToString("yyyy/MM/dd");
16 | }
17 |
18 | public object ConvertBack(object value, Type targetType, object parameter, string language)
19 | {
20 | throw new NotImplementedException();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Work-Timer/Models/UI/CustomResourceLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Windows.UI.Xaml.Media;
7 | using Windows.UI.Xaml.Resources;
8 | using WorkTimer.Models.Enums;
9 |
10 | namespace WorkTimer.Models.UI
11 | {
12 | public class CustomResourceLoader : CustomXamlResourceLoader
13 | {
14 | protected override object GetResource(string resourceId, string objectType, string propertyName, string propertyType)
15 | {
16 | if (resourceId == "Basic")
17 | {
18 | return new FontFamily(App._instance.App.GetLocalSetting(Settings.FontFamily, "Microsoft YaHei UI"));
19 | }
20 | return null;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Dialog/ConfirmDialog.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Work-Timer/Models/UI/SelectedColorConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Windows.UI;
3 | using Windows.UI.Xaml.Data;
4 | using Windows.UI.Xaml.Media;
5 | using WorkTimer.Models.Enums;
6 |
7 | namespace WorkTimer.Models.UI
8 | {
9 | public class SelectedColorConverter:IValueConverter
10 | {
11 | public object Convert(object value, Type targetType, object parameter, string language)
12 | {
13 | bool isSelected = System.Convert.ToBoolean(value);
14 | return isSelected ? App._instance.App.GetThemeBrushFromResource(ColorName.PrimaryColor) : new SolidColorBrush(Colors.Transparent);
15 | }
16 |
17 | public object ConvertBack(object value, Type targetType, object parameter, string language)
18 | {
19 | throw new NotImplementedException();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Lib_Share/Models/StaticString.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Windows.UI.Composition.Scenes;
7 |
8 | namespace Lib.Share.Models
9 | {
10 | public static class StaticString
11 | {
12 | public const string AppName = "WorkTimer";
13 |
14 | public const string FolderListFileName = "FolderList.json";
15 | public const string HistoryListFileName = "HistoryList.json";
16 |
17 | public const string ThemeSystem = "System";
18 | public const string ThemeLight = "Light";
19 | public const string ThemeDark = "Dark";
20 |
21 | public const string LanZh = "zh_CN";
22 | public const string LanEn = "en_US";
23 |
24 | public const string FontDefault = "Microsoft YaHei UI";
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Lib_Share/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("Lib_Share")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Lib_Share")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 程序集的版本信息由下列四个值组成:
18 | //
19 | // 主版本
20 | // 次版本
21 | // 生成号
22 | // 修订号
23 | //
24 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
25 | //通过使用 "*",如下所示:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/Lib_Share/Properties/Lib_Share.rd.xml:
--------------------------------------------------------------------------------
1 |
2 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Lib_Share/Models/FolderItem.cs:
--------------------------------------------------------------------------------
1 | using Richasy.Font.UWP.Enums;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace Lib.Share.Models
6 | {
7 | public class FolderItem
8 | {
9 | public string Name { get; set; }
10 | public DateTime CreateTime { get; set; }
11 | public string Id { get; set; }
12 | public FeatherSymbol Icon { get; set; }
13 | public FolderItem()
14 | {
15 |
16 | }
17 | public FolderItem(string name,FeatherSymbol icon)
18 | {
19 | Name = name;
20 | CreateTime = DateTime.Now;
21 | Id = Guid.NewGuid().ToString("N");
22 | Icon = icon;
23 | }
24 |
25 | public override bool Equals(object obj)
26 | {
27 | return obj is FolderItem item &&
28 | Id == item.Id;
29 | }
30 |
31 | public override int GetHashCode()
32 | {
33 | return 2108858624 + EqualityComparer.Default.GetHashCode(Id);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Work-Timer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Work-Timer")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Work-Timer")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/Work-Timer/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Lib_Share/Models/HistoryItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Lib.Share.Models
8 | {
9 | public class HistoryItem
10 | {
11 | public string Name { get; set; }
12 | public string FolderId { get; set; }
13 | public string Id { get; set; }
14 | public int TotalSeconds { get; set; }
15 | public DateTime CreateTime { get; set; }
16 | public HistoryItem()
17 | {
18 |
19 | }
20 | public HistoryItem(string name, string folderId, int totalSeconds = 0)
21 | {
22 | Name = name;
23 | FolderId = folderId;
24 | Id = Guid.NewGuid().ToString("N");
25 | TotalSeconds = totalSeconds;
26 | CreateTime = DateTime.Now;
27 | }
28 | public string GetReadTime()
29 | {
30 | var ts = TimeSpan.FromSeconds(TotalSeconds);
31 | string result = "";
32 | if (ts.Hours > 0)
33 | result += ts.Hours + "h ";
34 | if (ts.Minutes > 0)
35 | result += ts.Minutes + "m ";
36 | else if (ts.Hours > 0)
37 | result += "00m ";
38 | result += ts.Seconds.ToString("00") + "s";
39 | return result;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Work-Timer/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Layout/HistoryPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using Lib.Share.Models;
2 | using System;
3 | using Windows.UI.Xaml.Controls;
4 | using WorkTimer.Components.Dialog;
5 | using WorkTimer.Models.Core;
6 |
7 | // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
8 |
9 | namespace WorkTimer.Components.Layout
10 | {
11 | public sealed partial class HistoryPanel : UserControl
12 | {
13 | AppViewModel vm = App._vm;
14 | public HistoryPanel()
15 | {
16 | this.InitializeComponent();
17 | vm.HistoryPanel = this;
18 | vm.CurrentSelectedFolderChanged += SelectedFolderChanged;
19 | }
20 |
21 | private void SelectedFolderChanged(object sender, FolderItem e)
22 | {
23 | TitleBlock.Text = e.Name;
24 | }
25 |
26 | private void HistoryListView_ItemClick(object sender, ItemClickEventArgs e)
27 | {
28 |
29 | }
30 |
31 | private async void RemoveItem_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
32 | {
33 | var item = (sender as MenuFlyoutItem).Tag as HistoryItem;
34 | await vm.RemoveHistory(item);
35 | }
36 |
37 | private async void TransferItem_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
38 | {
39 | var item = (sender as MenuFlyoutItem).Tag as HistoryItem;
40 | var dialog = new FolderSelectionDialog(item);
41 | await dialog.ShowAsync();
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Widget/WorkDurationBlock.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
26 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Dialog/ConfirmDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 | using WorkTimer.Models.Enums;
16 |
17 | // https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“内容对话框”项模板
18 |
19 | namespace WorkTimer.Components.Dialog
20 | {
21 | public sealed partial class ConfirmDialog : ContentDialog
22 | {
23 | public ConfirmDialog()
24 | {
25 | this.InitializeComponent();
26 | Title = App._instance.App.GetLocalizationTextFromResource(LanguageName.Warning);
27 | PrimaryButtonText = App._instance.App.GetLocalizationTextFromResource(LanguageName.Confirm);
28 | CloseButtonText = App._instance.App.GetLocalizationTextFromResource(LanguageName.Cancel);
29 | }
30 | public ConfirmDialog(string msg):this()
31 | {
32 | DisplayBlock.Text = msg;
33 | }
34 | public ConfirmDialog(LanguageName language):this()
35 | {
36 | DisplayBlock.Text = App._instance.App.GetLocalizationTextFromResource(language);
37 | }
38 | private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
39 | {
40 | }
41 |
42 | private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
43 | {
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Widget/WorkDurationBlock.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 | using WorkTimer.Models.Enums;
16 |
17 | //https://go.microsoft.com/fwlink/?LinkId=234236 上介绍了“用户控件”项模板
18 |
19 | namespace WorkTimer.Components.Widget
20 | {
21 | public sealed partial class WorkDurationBlock : UserControl
22 | {
23 | public WorkDurationBlock()
24 | {
25 | this.InitializeComponent();
26 | UpdatePresetDuration();
27 | App._vm.WorkDurationBlock = this;
28 | App._vm.HistoryChanged += HistoryChanged;
29 | }
30 |
31 | private void HistoryChanged(object sender, EventArgs e)
32 | {
33 | var todayList = App._vm.AllHistoryList.Where(p => p.CreateTime.Date == DateTime.Now.Date).ToList();
34 | if (todayList.Count > 0)
35 | {
36 | int totalSeconds = 0;
37 | todayList.ForEach(p => totalSeconds += p.TotalSeconds);
38 | ActualDurationBlock.Text = (totalSeconds / 60.0).ToString("0") + " m";
39 | }
40 | else
41 | ActualDurationBlock.Text = "0 m";
42 | }
43 | public void UpdatePresetDuration()
44 | {
45 | string presetDuration = App._instance.App.GetLocalSetting(Settings.PresetDuration, "360");
46 | PresetDurationBlock.Text = presetDuration + " m";
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Dialog/FolderSelectionDialog.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Work-Timer/Template/Text.xaml:
--------------------------------------------------------------------------------
1 |
5 |
9 |
14 |
19 |
23 |
26 |
31 |
36 |
37 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Dialog/FolderSelectionDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using Lib.Share.Models;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Runtime.InteropServices.WindowsRuntime;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 | using WorkTimer.Models.Enums;
18 |
19 | // https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“内容对话框”项模板
20 |
21 | namespace WorkTimer.Components.Dialog
22 | {
23 | public sealed partial class FolderSelectionDialog : ContentDialog
24 | {
25 | private ObservableCollection FolderCollection = App._vm.FolderCollection;
26 | private HistoryItem _source = null;
27 | public FolderSelectionDialog()
28 | {
29 | this.InitializeComponent();
30 | Title = App._instance.App.GetLocalizationTextFromResource(LanguageName.MoveHistory);
31 | PrimaryButtonText = App._instance.App.GetLocalizationTextFromResource(LanguageName.Confirm);
32 | CloseButtonText = App._instance.App.GetLocalizationTextFromResource(LanguageName.Cancel);
33 | }
34 |
35 | public FolderSelectionDialog(HistoryItem item):this()
36 | {
37 | _source = item;
38 | FolderComboBox.SelectedItem = FolderCollection.Where(p => p.Id == item.FolderId).FirstOrDefault();
39 | }
40 |
41 | private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
42 | {
43 | args.Cancel = true;
44 | var newFolder = FolderComboBox.SelectedItem as FolderItem;
45 | if (newFolder.Id != _source.Id)
46 | {
47 | App._vm.MoveHistory(_source, newFolder.Id);
48 | }
49 | Hide();
50 | }
51 |
52 | private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
53 | {
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # 工作计时器
4 |
5 | 该应用本为我实际工作需要而做,做出来之后发现并没有我想象中那么趁手,但却因为我没有想到的用途而帮助到了其它人。
6 |
7 | 于是在整理旧项目的时候,重新设计了应用的UI与功能,去掉与我工作绑定的部分,将之变得更为通用,让它作为一个正计时器继续发光发热。
8 |
9 | ## 应用截图
10 |
11 | 
12 |
13 | ## 如何安装
14 |
15 | 应用已在微软应用商店上架,您可以访问 [微软应用商店](https://www.microsoft.com/store/productId/9N71W9G714RK) 进行下载。
16 |
17 | 应用要求您的系统为:**Windows 10 ver.1809** 及以上。
18 |
19 | 您也可以将该仓库克隆到本地并通过 Visual Studio 2019 运行它。
20 |
21 | 在克隆之后,需要先打开项目内的`package.appxmanifest`文件,在打包选项卡下,将证书改为自签名的证书,然后重新生成应用并部署。
22 |
23 | ## 使用说明
24 |
25 | ### 计时器
26 |
27 | 应用功能不多,核心就是一个计时器。
28 |
29 | 计时器是正向计时而非倒计时,意即你可以通过它记录你完成某件事花了多长时间,而不是要在规定时间内完成某件事。
30 |
31 | 计时器在同一时间只能存在一个,它的理想使用场景是一种单线程的工作模式,即只有一件事做完了才去做下一件事。
32 |
33 | 计时器没有暂停的功能 *(你可以观察到时间的流逝,却不能阻挡它的脚步)* ,当你停止计时后,意味着与该计时器对应的工作已经完成。这段计时记录会被保存。
34 |
35 | 你可以点击计时器按钮下方的文本(鼠标移上去会有背景色及光标变化),修改它的内容以记述你当前正在做的事。它将作为计时器的标题被保存。
36 |
37 | 在标题下面还有一个按钮,点击该按钮可以切换应用为小窗模式,即悬浮置顶于屏幕右上角,再次点击则会退出小窗模式。
38 |
39 | ### 分组与历史记录
40 |
41 | 考虑到可能有归纳整理的需求,应用在重制后添加了分组和历史记录的功能。
42 |
43 | **分组**
44 |
45 | 分组用于划分使用场景或者筛选范围。举例而言,你可以为今天创建一个分组,分组的名字就是今天的日期。你也可以给自己要做的事情进行分组,比如分为阅读,休闲等。
46 |
47 | 在应用中,你需要点击左下角的按钮来展示分组信息。当前选中的分组会高亮显示。
48 |
49 | 
50 |
51 | **历史记录**
52 |
53 | 当计时器停止计时时,计时记录会被保存到当前选择的分组下,形成历史记录。
54 |
55 | 
56 |
57 | 历史记录主要包括:`花费时间`、`标题`、`创建时间`这三条信息。如果你想移动该记录到另外的分组,则可以点击卡片的更多按钮(三个点)进行操作。
58 |
59 | ### 工作时长
60 |
61 | 既然名为工作计时器,总要有些和工作有关的内容。
62 |
63 | 您可以预设一个总的工作时长,默认是360分钟,即6个小时,您可以在设置里对其进行修改。
64 |
65 | 在配置之后,您每次添加或删除计时器记录,应用都会自动统计当天总的计时时长,并显示在应用界面下方。
66 |
67 | ### 应用设置
68 |
69 | 应用提供四个基础的设置项:
70 |
71 | 1. 主题设置
72 |
73 | 可选`Light`, `Dark`和`跟随系统`,跟随系统即与当前系统主题设置同步。
74 |
75 | 2. 字体设置
76 |
77 | 应用支持全局调整字体,您可以选择您喜欢的字体进行显示。
78 |
79 | 3. 语言设置
80 |
81 | 应用支持中文、英文两种语言,可按需取用。
82 |
83 | 4. 预设时长
84 |
85 | 用于配置每天要工作的时长,以便进行统计。
86 |
87 | *由于应用已经开源,所以在设置中额外提供了一个导向本仓库的开源地址按钮*
88 |
89 | ## 工具引用
90 |
91 | - [Windows Community Toolkit](https://github.com/windows-toolkit/WindowsCommunityToolkit)
92 | - [Richasy.Helper.UWP](https://github.com/Richasy/Richasy-Helper-UWP)
93 | - [Richasy.Font.UWP](https://github.com/Richasy/Richasy-Font-UWP)
94 | - [Richasy.Controls.UWP](https://github.com/Richasy/Richasy-Controls-UWP)
--------------------------------------------------------------------------------
/Work-Timer/Components/Layout/FolderPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using Lib.Share.Models;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Runtime.InteropServices.WindowsRuntime;
7 | using Windows.Foundation;
8 | using Windows.Foundation.Collections;
9 | using Windows.UI.Xaml;
10 | using Windows.UI.Xaml.Controls;
11 | using Windows.UI.Xaml.Controls.Primitives;
12 | using Windows.UI.Xaml.Data;
13 | using Windows.UI.Xaml.Input;
14 | using Windows.UI.Xaml.Media;
15 | using Windows.UI.Xaml.Navigation;
16 | using WorkTimer.Components.Dialog;
17 | using WorkTimer.Models.Core;
18 | using WorkTimer.Models.Enums;
19 |
20 | //https://go.microsoft.com/fwlink/?LinkId=234236 上介绍了“用户控件”项模板
21 |
22 | namespace WorkTimer.Components.Layout
23 | {
24 | public sealed partial class FolderPanel : UserControl
25 | {
26 | AppViewModel vm = App._vm;
27 | public FolderPanel()
28 | {
29 | this.InitializeComponent();
30 | vm.FolderPanel = this;
31 | vm.CurrentSelectedFolderChanged += SelectedFolder_Changed;
32 | }
33 |
34 | private void SelectedFolder_Changed(object sender, FolderItem e)
35 | {
36 | FolderListView.SelectedItem = e;
37 | }
38 |
39 | private async void AddFolderButton_Click(object sender, RoutedEventArgs e)
40 | {
41 | var dialog = new FolderDialog();
42 | await dialog.ShowAsync();
43 | }
44 |
45 | private void FolderListView_ItemClick(object sender, ItemClickEventArgs e)
46 | {
47 | var folder = e.ClickedItem as FolderItem;
48 | if (!vm.CurrentSelectedFolder.Equals(folder))
49 | {
50 | vm.CurrentSelectedFolder = folder;
51 | }
52 | }
53 |
54 | private async void ModifyItem_Click(object sender, RoutedEventArgs e)
55 | {
56 | var item = (sender as MenuFlyoutItem).Tag as FolderItem;
57 | var dialog = new FolderDialog(item);
58 | await dialog.ShowAsync();
59 | }
60 |
61 | private async void RemoveItem_Click(object sender, RoutedEventArgs e)
62 | {
63 | var item = (sender as MenuFlyoutItem).Tag as FolderItem;
64 | await vm.RemoveFolder(item);
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Work-Timer/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
16 |
17 |
18 | Working Timer
19 | 云之幻
20 | Assets\Logo\StoreLogo.png
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
35 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/Work-Timer/Theme/Light.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | #AAAAAA
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Work-Timer/Theme/Dark.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | #111111
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Dialog/FolderDialog.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
42 |
43 |
44 |
45 |
46 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Dialog/FolderDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using Lib.Share.Models;
2 | using Richasy.Font.UWP.Enums;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Collections.ObjectModel;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Runtime.InteropServices.WindowsRuntime;
9 | using Windows.Foundation;
10 | using Windows.Foundation.Collections;
11 | using Windows.UI.Xaml;
12 | using Windows.UI.Xaml.Controls;
13 | using Windows.UI.Xaml.Controls.Primitives;
14 | using Windows.UI.Xaml.Data;
15 | using Windows.UI.Xaml.Input;
16 | using Windows.UI.Xaml.Media;
17 | using Windows.UI.Xaml.Navigation;
18 | using WorkTimer.Models.Enums;
19 |
20 | // https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“内容对话框”项模板
21 |
22 | namespace WorkTimer.Components.Dialog
23 | {
24 | public sealed partial class FolderDialog : ContentDialog
25 | {
26 | public ObservableCollection SymbolCollection = App._vm.SymbolCollection;
27 | private FolderItem _source = null;
28 | public FolderDialog()
29 | {
30 | this.InitializeComponent();
31 | Title = App._instance.App.GetLocalizationTextFromResource(LanguageName.FolderDialogTitle);
32 | DescriptionBlock.Text = App._instance.App.GetLocalizationTextFromResource(LanguageName.FolderDialogDescription);
33 | PrimaryButtonText= App._instance.App.GetLocalizationTextFromResource(LanguageName.Confirm);
34 | CloseButtonText = App._instance.App.GetLocalizationTextFromResource(LanguageName.Cancel);
35 | }
36 |
37 | public FolderDialog(FolderItem item):this()
38 | {
39 | _source = item;
40 | ShowIcon.Symbol = (FeatherSymbol)item.Icon;
41 | SymbolGridView.SelectedItem = (FeatherSymbol)item.Icon;
42 | NameBox.Text = item.Name;
43 | }
44 |
45 | private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
46 | {
47 | args.Cancel = true;
48 | if (string.IsNullOrEmpty(NameBox.Text))
49 | {
50 | App._vm.ShowPopup(LanguageName.FieldEmpty, true);
51 | return;
52 | }
53 | FolderItem item = null;
54 | if (_source == null)
55 | item = new FolderItem(NameBox.Text, ShowIcon.Symbol);
56 | else
57 | {
58 | item = _source;
59 | item.Name = NameBox.Text;
60 | item.Icon = ShowIcon.Symbol;
61 | }
62 | App._vm.AddOrUpdateFolderItem(item);
63 | Hide();
64 | }
65 |
66 | private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
67 | {
68 | }
69 |
70 | private void SymbolGridView_ItemClick(object sender, ItemClickEventArgs e)
71 | {
72 | var icon = (FeatherSymbol)e.ClickedItem;
73 | ShowIcon.Symbol = icon;
74 | SymbolFlyout.Hide();
75 | }
76 |
77 | private void SymbolFlyout_Opened(object sender, object e)
78 | {
79 | if (SymbolGridView.SelectedItem != null)
80 | {
81 | SymbolGridView.ScrollIntoView(SymbolGridView.SelectedItem);
82 | }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Work-Timer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30225.117
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Work-Timer", "Work-Timer\Work-Timer.csproj", "{B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lib_Share", "Lib_Share\Lib_Share.csproj", "{55CE1B3E-4D23-4566-881B-C4F463671785}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|ARM = Debug|ARM
14 | Debug|ARM64 = Debug|ARM64
15 | Debug|x64 = Debug|x64
16 | Debug|x86 = Debug|x86
17 | Release|Any CPU = Release|Any CPU
18 | Release|ARM = Release|ARM
19 | Release|ARM64 = Release|ARM64
20 | Release|x64 = Release|x64
21 | Release|x86 = Release|x86
22 | EndGlobalSection
23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|Any CPU.ActiveCfg = Debug|x86
25 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|ARM.ActiveCfg = Debug|ARM
26 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|ARM.Build.0 = Debug|ARM
27 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|ARM.Deploy.0 = Debug|ARM
28 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|ARM64.ActiveCfg = Debug|ARM64
29 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|ARM64.Build.0 = Debug|ARM64
30 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|ARM64.Deploy.0 = Debug|ARM64
31 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|x64.ActiveCfg = Debug|x64
32 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|x64.Build.0 = Debug|x64
33 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|x64.Deploy.0 = Debug|x64
34 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|x86.ActiveCfg = Debug|x86
35 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|x86.Build.0 = Debug|x86
36 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Debug|x86.Deploy.0 = Debug|x86
37 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|Any CPU.ActiveCfg = Release|x86
38 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|ARM.ActiveCfg = Release|ARM
39 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|ARM.Build.0 = Release|ARM
40 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|ARM.Deploy.0 = Release|ARM
41 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|ARM64.ActiveCfg = Release|ARM64
42 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|ARM64.Build.0 = Release|ARM64
43 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|ARM64.Deploy.0 = Release|ARM64
44 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|x64.ActiveCfg = Release|x64
45 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|x64.Build.0 = Release|x64
46 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|x64.Deploy.0 = Release|x64
47 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|x86.ActiveCfg = Release|x86
48 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|x86.Build.0 = Release|x86
49 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}.Release|x86.Deploy.0 = Release|x86
50 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|Any CPU.Build.0 = Debug|Any CPU
52 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|ARM.ActiveCfg = Debug|ARM
53 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|ARM.Build.0 = Debug|ARM
54 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|ARM64.ActiveCfg = Debug|ARM64
55 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|ARM64.Build.0 = Debug|ARM64
56 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|x64.ActiveCfg = Debug|x64
57 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|x64.Build.0 = Debug|x64
58 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|x86.ActiveCfg = Debug|x86
59 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Debug|x86.Build.0 = Debug|x86
60 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|Any CPU.ActiveCfg = Release|Any CPU
61 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|Any CPU.Build.0 = Release|Any CPU
62 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|ARM.ActiveCfg = Release|ARM
63 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|ARM.Build.0 = Release|ARM
64 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|ARM64.ActiveCfg = Release|ARM64
65 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|ARM64.Build.0 = Release|ARM64
66 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|x64.ActiveCfg = Release|x64
67 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|x64.Build.0 = Release|x64
68 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|x86.ActiveCfg = Release|x86
69 | {55CE1B3E-4D23-4566-881B-C4F463671785}.Release|x86.Build.0 = Release|x86
70 | EndGlobalSection
71 | GlobalSection(SolutionProperties) = preSolution
72 | HideSolutionNode = FALSE
73 | EndGlobalSection
74 | GlobalSection(ExtensibilityGlobals) = postSolution
75 | SolutionGuid = {FEEFA813-1666-4A7E-850A-1844A4EE0126}
76 | EndGlobalSection
77 | EndGlobal
78 |
--------------------------------------------------------------------------------
/Work-Timer/Models/Core/AppViewModel.Properties.cs:
--------------------------------------------------------------------------------
1 | using Lib.Share.Models;
2 | using Richasy.Controls.UWP.Popups;
3 | using Richasy.Font.UWP;
4 | using Richasy.Font.UWP.Enums;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Collections.ObjectModel;
8 | using System.Linq;
9 | using Windows.UI.Xaml;
10 | using WorkTimer.Components.Layout;
11 | using WorkTimer.Components.Widget;
12 | using WorkTimer.Models.Enums;
13 |
14 | namespace WorkTimer.Models.Core
15 | {
16 | public partial class AppViewModel : DependencyObject
17 | {
18 | public ObservableCollection FolderCollection = new ObservableCollection();
19 | public ObservableCollection DisplayHistoryCollection = new ObservableCollection();
20 | public List AllHistoryList = new List();
21 | private bool IsFolderListChanged = false;
22 | private bool _isHisotryListChanged = false;
23 | private bool IsHistoryListChanged
24 | {
25 | get => _isHisotryListChanged;
26 | set
27 | {
28 | if (value)
29 | HistoryChanged?.Invoke(this, EventArgs.Empty);
30 | _isHisotryListChanged = value;
31 | }
32 | }
33 | private DispatcherTimer _changeTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(10) };
34 | private DispatcherTimer _durationTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(0.5) };
35 |
36 | public event EventHandler CurrentSelectedFolderChanged;
37 | public event EventHandler HistoryChanged;
38 | private FolderItem _currentSelectedFolder = null;
39 |
40 | public FolderPanel FolderPanel;
41 | public HistoryPanel HistoryPanel;
42 | public WorkDurationBlock WorkDurationBlock;
43 |
44 | public CenterPopup SettingPopup;
45 | public FolderItem CurrentSelectedFolder
46 | {
47 | get => _currentSelectedFolder;
48 | set
49 | {
50 | _currentSelectedFolder = value;
51 | var history = AllHistoryList.Where(p => p.FolderId == value.Id).ToList();
52 | DisplayHistoryCollection.Clear();
53 | history.ForEach(p => DisplayHistoryCollection.Add(p));
54 | App._instance.App.WriteLocalSetting(Settings.LastSelectFolderId, value.Id);
55 | CurrentSelectedFolderChanged?.Invoke(this, value);
56 | }
57 | }
58 | public DateTime BeginStamp { get; set; }
59 |
60 | public event EventHandler IsTimingChanged;
61 | private bool _isTiming = false;
62 | public bool IsTiming
63 | {
64 | get => _isTiming;
65 | set
66 | {
67 | _isTiming = value;
68 | IsTimingChanged?.Invoke(this, value);
69 | if (value)
70 | _durationTimer.Start();
71 | else
72 | _durationTimer.Stop();
73 | }
74 | }
75 |
76 | public string DurationText
77 | {
78 | get { return (string)GetValue(DurationTextProperty); }
79 | set { SetValue(DurationTextProperty, value); }
80 | }
81 |
82 | public static readonly DependencyProperty DurationTextProperty =
83 | DependencyProperty.Register("DurationText", typeof(string), typeof(AppViewModel), new PropertyMetadata("00:00:00"));
84 |
85 |
86 | public ObservableCollection SymbolCollection = new ObservableCollection
87 | {
88 | FeatherSymbol.Activity,FeatherSymbol.Airplay,
89 | FeatherSymbol.AlertTriangle,FeatherSymbol.Anchor,
90 | FeatherSymbol.Aperture,FeatherSymbol.Archive,
91 | FeatherSymbol.Award,FeatherSymbol.BarChart,
92 | FeatherSymbol.BarChart2,FeatherSymbol.Battery,
93 | FeatherSymbol.Bluetooth,FeatherSymbol.Book,
94 | FeatherSymbol.Bookmark,FeatherSymbol.Box,
95 | FeatherSymbol.Briefcase,FeatherSymbol.Calendar,
96 | FeatherSymbol.Camera,FeatherSymbol.Cast,
97 | FeatherSymbol.Chrome,FeatherSymbol.Clipboard,
98 | FeatherSymbol.Clock,FeatherSymbol.Cloud,
99 | FeatherSymbol.Code,FeatherSymbol.Coffee,
100 | FeatherSymbol.Cpu,FeatherSymbol.CreditCard,
101 | FeatherSymbol.Disc,FeatherSymbol.Edit,
102 | FeatherSymbol.Eye,FeatherSymbol.Facebook,
103 | FeatherSymbol.Feather,FeatherSymbol.Figma,
104 | FeatherSymbol.File,FeatherSymbol.Folder,
105 | FeatherSymbol.Framer,FeatherSymbol.Gift,
106 | FeatherSymbol.Image,FeatherSymbol.Home,
107 | FeatherSymbol.Inbox,FeatherSymbol.Info
108 | };
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/Work-Timer/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Lib.Share.Models;
2 | using Richasy.Controls.UWP.Models.UI;
3 | using Richasy.Font.UWP;
4 | using Richasy.Font.UWP.Enums;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.IO;
8 | using System.Linq;
9 | using System.Runtime.InteropServices.WindowsRuntime;
10 | using Windows.Foundation;
11 | using Windows.Foundation.Collections;
12 | using Windows.UI.Core.Preview;
13 | using Windows.UI.ViewManagement;
14 | using Windows.UI.Xaml;
15 | using Windows.UI.Xaml.Controls;
16 | using Windows.UI.Xaml.Controls.Primitives;
17 | using Windows.UI.Xaml.Data;
18 | using Windows.UI.Xaml.Input;
19 | using Windows.UI.Xaml.Media;
20 | using Windows.UI.Xaml.Navigation;
21 | using WorkTimer.Models.Core;
22 |
23 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
24 |
25 | namespace WorkTimer
26 | {
27 | ///
28 | /// An empty page that can be used on its own or navigated to within a Frame.
29 | ///
30 | public sealed partial class MainPage : RichasyPage
31 | {
32 | public AppViewModel vm = App._vm;
33 | public MainPage():base()
34 | {
35 | this.InitializeComponent();
36 | TitleBox.Text = "Untitled";
37 | vm.IsTimingChanged += IsTiming_Changed;
38 | vm.CurrentSelectedFolderChanged += CurrentSelectedFolder_Changed;
39 | SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += CloseRequested;
40 | }
41 |
42 | private async void CloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
43 | {
44 | e.Handled = true;
45 | await vm.SaveData();
46 | App.Current.Exit();
47 | }
48 |
49 | private void CurrentSelectedFolder_Changed(object sender, FolderItem e)
50 | {
51 | GroupNameBlock.Text = e.Name;
52 | }
53 |
54 | private void IsTiming_Changed(object sender, bool e)
55 | {
56 | var icon = e ? FeatherSymbol.Pause : FeatherSymbol.Play;
57 | StatusIcon.Symbol = icon;
58 | if (e)
59 | {
60 | vm.BeginStamp = DateTime.Now;
61 | }
62 | else
63 | {
64 | var ts = DateTime.Now - vm.BeginStamp;
65 | var historyItem = new HistoryItem(TitleBox.Text ?? "Untitled", vm.CurrentSelectedFolder.Id, Convert.ToInt32(ts.TotalSeconds));
66 | vm.AddHistoryItem(historyItem);
67 | TitleBox.Text = "Untitled";
68 | }
69 | }
70 |
71 | private void SettingButton_Click(object sender, RoutedEventArgs e)
72 | {
73 | vm.ShowSettingPopup();
74 | }
75 |
76 | private void StatusButton_Click(object sender, RoutedEventArgs e)
77 | {
78 | vm.IsTiming = !vm.IsTiming;
79 | }
80 |
81 | private void FolderButton_Click(object sender, RoutedEventArgs e)
82 | {
83 | MainSplitView.IsPaneOpen = !MainSplitView.IsPaneOpen;
84 | }
85 |
86 | private void HistoryButton_Click(object sender, RoutedEventArgs e)
87 | {
88 | SubSplitView.IsPaneOpen = !SubSplitView.IsPaneOpen;
89 | }
90 |
91 | private async void RichasyPage_Loaded(object sender, RoutedEventArgs e)
92 | {
93 | vm.CheckUpdate();
94 | await App._vm.Init();
95 | }
96 |
97 | private async void CompactButton_Click(object sender, RoutedEventArgs e)
98 | {
99 | var view = ApplicationView.GetForCurrentView();
100 | if (view.ViewMode == ApplicationViewMode.CompactOverlay)
101 | {
102 | await view.TryEnterViewModeAsync(ApplicationViewMode.Default);
103 | VisualStateManager.GoToState(this, "Default",false);
104 | }
105 | else
106 | {
107 | await view.TryEnterViewModeAsync(ApplicationViewMode.CompactOverlay);
108 | VisualStateManager.GoToState(this, "Compact", false);
109 | }
110 |
111 | }
112 |
113 | private void RichasyPage_SizeChanged(object sender, SizeChangedEventArgs e)
114 | {
115 | double width = e.NewSize.Width;
116 | if (width > 1300)
117 | {
118 | MainSplitView.DisplayMode = SplitViewDisplayMode.CompactInline;
119 | SubSplitView.DisplayMode = SplitViewDisplayMode.CompactInline;
120 | }
121 | else if (width > 900)
122 | {
123 | MainSplitView.DisplayMode = SplitViewDisplayMode.CompactOverlay;
124 | SubSplitView.DisplayMode = SplitViewDisplayMode.CompactInline;
125 | }
126 | else
127 | {
128 | MainSplitView.DisplayMode = SplitViewDisplayMode.CompactOverlay;
129 | SubSplitView.DisplayMode = SplitViewDisplayMode.CompactOverlay;
130 | }
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Layout/SettingPanel.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
36 |
42 |
43 |
44 |
45 |
47 |
51 |
52 |
53 |
54 |
55 |
56 |
58 |
59 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
71 |
72 |
73 |
74 |
76 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Layout/HistoryPanel.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
29 |
31 |
33 |
34 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
47 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
68 |
69 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Layout/FolderPanel.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
29 |
31 |
32 |
34 |
35 |
36 |
37 |
38 |
39 |
41 |
42 |
43 |
44 |
45 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
70 |
73 |
74 |
75 |
76 |
77 |
78 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/Work-Timer/Components/Layout/SettingPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using Lib.Share.Models;
2 | using Richasy.Font.UWP;
3 | using System;
4 | using System.Collections.ObjectModel;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using Windows.ApplicationModel.Core;
8 | using Windows.Globalization;
9 | using Windows.System;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using WorkTimer.Components.Dialog;
13 | using WorkTimer.Models.Enums;
14 |
15 | //https://go.microsoft.com/fwlink/?LinkId=234236 上介绍了“用户控件”项模板
16 |
17 | namespace WorkTimer.Components.Layout
18 | {
19 | public sealed partial class SettingPanel : UserControl
20 | {
21 | private ObservableCollection FontCollection = new ObservableCollection();
22 | private bool _isInit = false;
23 | public SettingPanel()
24 | {
25 | this.InitializeComponent();
26 | string lan = ApplicationLanguages.PrimaryLanguageOverride.Equals("zh-CN", StringComparison.OrdinalIgnoreCase) ? "zh-Hans-CN" : "en-US";
27 | var fonts = SystemFont.GetSystemFonts(lan);
28 | fonts.ForEach(p => FontCollection.Add(p));
29 | }
30 |
31 | private async void ThemeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
32 | {
33 | if (!_isInit)
34 | return;
35 | var item = (ThemeComboBox.SelectedItem as ComboBoxItem).Tag.ToString();
36 | string oldTheme = App._instance.App.GetLocalSetting(Settings.Theme, StaticString.ThemeSystem);
37 | if (oldTheme != item)
38 | {
39 | App._instance.App.WriteLocalSetting(Settings.Theme, item);
40 | await ShowRestartDialog();
41 | }
42 | }
43 |
44 | private async void FontComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
45 | {
46 | if (!_isInit)
47 | return;
48 | var item = FontComboBox.SelectedItem as SystemFont;
49 | string oldFont = App._instance.App.GetLocalSetting(Settings.FontFamily, StaticString.FontDefault);
50 | if (item.Name != oldFont)
51 | {
52 | App._instance.App.WriteLocalSetting(Settings.FontFamily, item.Name);
53 | await ShowRestartDialog();
54 | }
55 | }
56 |
57 | private void UserControl_Loaded(object sender, RoutedEventArgs e)
58 | {
59 | string theme = App._instance.App.GetLocalSetting(Settings.Theme, StaticString.ThemeSystem);
60 | switch (theme)
61 | {
62 | case StaticString.ThemeSystem:
63 | ThemeComboBox.SelectedIndex = 0;
64 | break;
65 | case StaticString.ThemeLight:
66 | ThemeComboBox.SelectedIndex = 1;
67 | break;
68 | case StaticString.ThemeDark:
69 | ThemeComboBox.SelectedIndex = 2;
70 | break;
71 | default:
72 | break;
73 | }
74 | FontInit();
75 | string lan = App._instance.App.GetLocalSetting(Settings.Language, StaticString.LanZh);
76 | LanguageComboBox.SelectedIndex = lan == StaticString.LanZh ? 0 : 1;
77 | string presetDuration = App._instance.App.GetLocalSetting(Settings.PresetDuration, "360");
78 | PresetDurationBox.Value = Convert.ToDouble(presetDuration);
79 | _isInit = true;
80 | }
81 | private async Task ShowRestartDialog()
82 | {
83 | var dialog = new ConfirmDialog(LanguageName.StaticResourceRestart) { PrimaryButtonText = App._instance.App.GetLocalizationTextFromResource(LanguageName.RestartNow) };
84 | dialog.PrimaryButtonClick += async (_s, _e) =>
85 | {
86 | await CoreApplication.RequestRestartAsync("restart");
87 | };
88 | await dialog.ShowAsync();
89 | }
90 | private void FontInit()
91 | {
92 | FontComboBox.IsEnabled = false;
93 | if (FontCollection != null && FontCollection.Count > 0)
94 | {
95 | string fontName = App._instance.App.GetLocalSetting(Settings.FontFamily, StaticString.FontDefault);
96 | var font = FontCollection.Where(p => p.Name == fontName).FirstOrDefault();
97 | if (font != null)
98 | {
99 | FontComboBox.SelectedItem = font;
100 | }
101 | }
102 | FontComboBox.IsEnabled = true;
103 | }
104 |
105 | private async void LanguageComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
106 | {
107 | if (!_isInit)
108 | return;
109 | var item = (LanguageComboBox.SelectedItem as ComboBoxItem).Tag.ToString();
110 | string oldLan = App._instance.App.GetLocalSetting(Settings.Language, StaticString.LanZh);
111 | if (oldLan != item)
112 | {
113 | App._instance.App.WriteLocalSetting(Settings.Language, item);
114 | await ShowRestartDialog();
115 | }
116 | }
117 |
118 | private void PresetDurationBox_ValueChanged(object sender, double e)
119 | {
120 | if (!_isInit)
121 | return;
122 | App._instance.App.WriteLocalSetting(Settings.PresetDuration, e.ToString());
123 | App._vm.WorkDurationBlock.UpdatePresetDuration();
124 | }
125 |
126 | private async void OpenSourceButton_Click(object sender, RoutedEventArgs e)
127 | {
128 | await Launcher.LaunchUriAsync(new Uri("https://github.com/Richasy/Work-Timer"));
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/Work-Timer/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Lib.Share.Models;
2 | using Richasy.Helper.UWP;
3 | using System;
4 | using Windows.ApplicationModel;
5 | using Windows.ApplicationModel.Activation;
6 | using Windows.Globalization;
7 | using Windows.UI.Xaml;
8 | using Windows.UI.Xaml.Controls;
9 | using Windows.UI.Xaml.Navigation;
10 | using Windows.UI.Xaml.Resources;
11 | using WorkTimer.Models.Core;
12 | using WorkTimer.Models.Enums;
13 | using WorkTimer.Models.UI;
14 |
15 | namespace WorkTimer
16 | {
17 | ///
18 | /// Provides application-specific behavior to supplement the default Application class.
19 | ///
20 | sealed partial class App : Application
21 | {
22 | ///
23 | /// Initializes the singleton application object. This is the first line of authored code
24 | /// executed, and as such is the logical equivalent of main() or WinMain().
25 | ///
26 | public static Instance _instance = new Instance(StaticString.AppName);
27 | public static AppViewModel _vm = new AppViewModel();
28 | public App()
29 | {
30 | this.InitializeComponent();
31 | ChangeLanguage();
32 | this.Suspending += OnSuspending;
33 | CustomXamlResourceLoader.Current = new CustomResourceLoader();
34 | string theme = _instance.App.GetLocalSetting(Settings.Theme, StaticString.ThemeSystem);
35 | if (theme != StaticString.ThemeSystem)
36 | {
37 | RequestedTheme = theme == StaticString.ThemeLight ? ApplicationTheme.Light : ApplicationTheme.Dark;
38 | }
39 | UnhandledException += UnhandleExceptionHandle;
40 | }
41 |
42 | private void UnhandleExceptionHandle(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
43 | {
44 | e.Handled = true;
45 | _vm.ShowPopup(e.Message, true);
46 | }
47 | ///
48 | /// 更改语言首选项
49 | ///
50 | private void ChangeLanguage()
51 | {
52 | string lan = _instance.App.GetLocalSetting(Settings.Language, "");
53 |
54 | if (lan == "")
55 | {
56 | var Languages = Windows.System.UserProfile.GlobalizationPreferences.Languages;
57 | if (Languages.Count > 0)
58 | {
59 | var language = Languages[0];
60 | if (language.ToLower().IndexOf("zh") != -1)
61 | {
62 | _instance.App.WriteLocalSetting(Settings.Language, StaticString.LanZh);
63 | }
64 | else
65 | {
66 | _instance.App.WriteLocalSetting(Settings.Language, StaticString.LanEn);
67 | }
68 | }
69 | else
70 | {
71 | _instance.App.WriteLocalSetting(Settings.Language, StaticString.LanEn);
72 | }
73 | }
74 | lan = _instance.App.GetLocalSetting(Settings.Language, StaticString.LanEn);
75 | string code = "";
76 | switch (lan)
77 | {
78 | case StaticString.LanZh:
79 | code = "zh-CN";
80 | break;
81 | case StaticString.LanEn:
82 | code = "en-US";
83 | break;
84 | default:
85 | code = "en-US";
86 | break;
87 | }
88 | ApplicationLanguages.PrimaryLanguageOverride = code;
89 | }
90 | protected override void OnActivated(IActivatedEventArgs args)
91 | {
92 | OnLaunchedOrActivated(args);
93 | }
94 | ///
95 | /// Invoked when the application is launched normally by the end user. Other entry points
96 | /// will be used such as when the application is launched to open a specific file.
97 | ///
98 | /// Details about the launch request and process.
99 | protected override void OnLaunched(LaunchActivatedEventArgs e)
100 | {
101 | OnLaunchedOrActivated(e);
102 | }
103 | private void OnLaunchedOrActivated(IActivatedEventArgs e)
104 | {
105 | Frame rootFrame = Window.Current.Content as Frame;
106 | _instance = new Instance(StaticString.AppName);
107 | // Do not repeat app initialization when the Window already has content,
108 | // just ensure that the window is active
109 | if (rootFrame == null)
110 | {
111 | // Create a Frame to act as the navigation context and navigate to the first page
112 | rootFrame = new Frame();
113 |
114 | rootFrame.NavigationFailed += OnNavigationFailed;
115 |
116 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
117 | {
118 | //TODO: Load state from previously suspended application
119 | }
120 |
121 | // Place the frame in the current Window
122 | Window.Current.Content = rootFrame;
123 | }
124 |
125 | if (e is LaunchActivatedEventArgs && (e as LaunchActivatedEventArgs).PrelaunchActivated == false)
126 | {
127 | if (rootFrame.Content == null)
128 | {
129 | rootFrame.Navigate(typeof(MainPage), (e as LaunchActivatedEventArgs).Arguments);
130 | }
131 | }
132 | else if (e is ProtocolActivatedEventArgs protocalArgs)
133 | {
134 | string arg = protocalArgs.Uri.Query.Replace("?", "");
135 | if (rootFrame.Content == null)
136 | {
137 | rootFrame.Navigate(typeof(MainPage), arg);
138 | }
139 | }
140 |
141 | Window.Current.Activate();
142 | _instance.App.SetTitleBarColor();
143 | }
144 | ///
145 | /// Invoked when Navigation to a certain page fails
146 | ///
147 | /// The Frame which failed navigation
148 | /// Details about the navigation failure
149 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
150 | {
151 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
152 | }
153 |
154 | ///
155 | /// Invoked when application execution is being suspended. Application state is saved
156 | /// without knowing whether the application will be terminated or resumed with the contents
157 | /// of memory still intact.
158 | ///
159 | /// The source of the suspend request.
160 | /// Details about the suspend request.
161 | private void OnSuspending(object sender, SuspendingEventArgs e)
162 | {
163 | var deferral = e.SuspendingOperation.GetDeferral();
164 | //TODO: Save application state and stop any background activity
165 | deferral.Complete();
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | [Aa][Rr][Mm]/
24 | [Aa][Rr][Mm]64/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 | [Ll]og/
29 |
30 | # Visual Studio 2015/2017 cache/options directory
31 | .vs/
32 | # Uncomment if you have tasks that create the project's static files in wwwroot
33 | #wwwroot/
34 |
35 | # Visual Studio 2017 auto generated files
36 | Generated\ Files/
37 |
38 | # MSTest test Results
39 | [Tt]est[Rr]esult*/
40 | [Bb]uild[Ll]og.*
41 |
42 | # NUNIT
43 | *.VisualState.xml
44 | TestResult.xml
45 |
46 | # Build Results of an ATL Project
47 | [Dd]ebugPS/
48 | [Rr]eleasePS/
49 | dlldata.c
50 |
51 | # Benchmark Results
52 | BenchmarkDotNet.Artifacts/
53 |
54 | # .NET Core
55 | project.lock.json
56 | project.fragment.lock.json
57 | artifacts/
58 |
59 | # StyleCop
60 | StyleCopReport.xml
61 |
62 | # Files built by Visual Studio
63 | *_i.c
64 | *_p.c
65 | *_h.h
66 | *.ilk
67 | *.meta
68 | *.obj
69 | *.iobj
70 | *.pch
71 | *.pdb
72 | *.ipdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *_wpftmp.csproj
83 | *.log
84 | *.vspscc
85 | *.vssscc
86 | .builds
87 | *.pidb
88 | *.svclog
89 | *.scc
90 |
91 | # Chutzpah Test files
92 | _Chutzpah*
93 |
94 | # Visual C++ cache files
95 | ipch/
96 | *.aps
97 | *.ncb
98 | *.opendb
99 | *.opensdf
100 | *.sdf
101 | *.cachefile
102 | *.VC.db
103 | *.VC.VC.opendb
104 |
105 | # Visual Studio profiler
106 | *.psess
107 | *.vsp
108 | *.vspx
109 | *.sap
110 |
111 | # Visual Studio Trace Files
112 | *.e2e
113 |
114 | # TFS 2012 Local Workspace
115 | $tf/
116 |
117 | # Guidance Automation Toolkit
118 | *.gpState
119 |
120 | # ReSharper is a .NET coding add-in
121 | _ReSharper*/
122 | *.[Rr]e[Ss]harper
123 | *.DotSettings.user
124 |
125 | # JustCode is a .NET coding add-in
126 | .JustCode
127 |
128 | # TeamCity is a build add-in
129 | _TeamCity*
130 |
131 | # DotCover is a Code Coverage Tool
132 | *.dotCover
133 |
134 | # AxoCover is a Code Coverage Tool
135 | .axoCover/*
136 | !.axoCover/settings.json
137 |
138 | # Visual Studio code coverage results
139 | *.coverage
140 | *.coveragexml
141 |
142 | # NCrunch
143 | _NCrunch_*
144 | .*crunch*.local.xml
145 | nCrunchTemp_*
146 |
147 | # MightyMoose
148 | *.mm.*
149 | AutoTest.Net/
150 |
151 | # Web workbench (sass)
152 | .sass-cache/
153 |
154 | # Installshield output folder
155 | [Ee]xpress/
156 |
157 | # DocProject is a documentation generator add-in
158 | DocProject/buildhelp/
159 | DocProject/Help/*.HxT
160 | DocProject/Help/*.HxC
161 | DocProject/Help/*.hhc
162 | DocProject/Help/*.hhk
163 | DocProject/Help/*.hhp
164 | DocProject/Help/Html2
165 | DocProject/Help/html
166 |
167 | # Click-Once directory
168 | publish/
169 |
170 | # Publish Web Output
171 | *.[Pp]ublish.xml
172 | *.azurePubxml
173 | # Note: Comment the next line if you want to checkin your web deploy settings,
174 | # but database connection strings (with potential passwords) will be unencrypted
175 | *.pubxml
176 | *.publishproj
177 |
178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
179 | # checkin your Azure Web App publish settings, but sensitive information contained
180 | # in these scripts will be unencrypted
181 | PublishScripts/
182 |
183 | # NuGet Packages
184 | *.nupkg
185 | # The packages folder can be ignored because of Package Restore
186 | **/[Pp]ackages/*
187 | # except build/, which is used as an MSBuild target.
188 | !**/[Pp]ackages/build/
189 | # Uncomment if necessary however generally it will be regenerated when needed
190 | #!**/[Pp]ackages/repositories.config
191 | # NuGet v3's project.json files produces more ignorable files
192 | *.nuget.props
193 | *.nuget.targets
194 |
195 | # Microsoft Azure Build Output
196 | csx/
197 | *.build.csdef
198 |
199 | # Microsoft Azure Emulator
200 | ecf/
201 | rcf/
202 |
203 | # Windows Store app package directories and files
204 | AppPackages/
205 | BundleArtifacts/
206 | Package.StoreAssociation.xml
207 | _pkginfo.txt
208 | *.appx
209 |
210 | # Visual Studio cache files
211 | # files ending in .cache can be ignored
212 | *.[Cc]ache
213 | # but keep track of directories ending in .cache
214 | !?*.[Cc]ache/
215 |
216 | # Others
217 | ClientBin/
218 | ~$*
219 | *~
220 | *.dbmdl
221 | *.dbproj.schemaview
222 | *.jfm
223 | *.pfx
224 | *.publishsettings
225 | orleans.codegen.cs
226 |
227 | # Including strong name files can present a security risk
228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
229 | #*.snk
230 |
231 | # Since there are multiple workflows, uncomment next line to ignore bower_components
232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
233 | #bower_components/
234 |
235 | # RIA/Silverlight projects
236 | Generated_Code/
237 |
238 | # Backup & report files from converting an old project file
239 | # to a newer Visual Studio version. Backup files are not needed,
240 | # because we have git ;-)
241 | _UpgradeReport_Files/
242 | Backup*/
243 | UpgradeLog*.XML
244 | UpgradeLog*.htm
245 | ServiceFabricBackup/
246 | *.rptproj.bak
247 |
248 | # SQL Server files
249 | *.mdf
250 | *.ldf
251 | *.ndf
252 |
253 | # Business Intelligence projects
254 | *.rdl.data
255 | *.bim.layout
256 | *.bim_*.settings
257 | *.rptproj.rsuser
258 | *- Backup*.rdl
259 |
260 | # Microsoft Fakes
261 | FakesAssemblies/
262 |
263 | # GhostDoc plugin setting file
264 | *.GhostDoc.xml
265 |
266 | # Node.js Tools for Visual Studio
267 | .ntvs_analysis.dat
268 | node_modules/
269 |
270 | # Visual Studio 6 build log
271 | *.plg
272 |
273 | # Visual Studio 6 workspace options file
274 | *.opt
275 |
276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
277 | *.vbw
278 |
279 | # Visual Studio LightSwitch build output
280 | **/*.HTMLClient/GeneratedArtifacts
281 | **/*.DesktopClient/GeneratedArtifacts
282 | **/*.DesktopClient/ModelManifest.xml
283 | **/*.Server/GeneratedArtifacts
284 | **/*.Server/ModelManifest.xml
285 | _Pvt_Extensions
286 |
287 | # Paket dependency manager
288 | .paket/paket.exe
289 | paket-files/
290 |
291 | # FAKE - F# Make
292 | .fake/
293 |
294 | # JetBrains Rider
295 | .idea/
296 | *.sln.iml
297 |
298 | # CodeRush personal settings
299 | .cr/personal
300 |
301 | # Python Tools for Visual Studio (PTVS)
302 | __pycache__/
303 | *.pyc
304 |
305 | # Cake - Uncomment if you are using it
306 | # tools/**
307 | # !tools/packages.config
308 |
309 | # Tabs Studio
310 | *.tss
311 |
312 | # Telerik's JustMock configuration file
313 | *.jmconfig
314 |
315 | # BizTalk build output
316 | *.btp.cs
317 | *.btm.cs
318 | *.odx.cs
319 | *.xsd.cs
320 |
321 | # OpenCover UI analysis results
322 | OpenCover/
323 |
324 | # Azure Stream Analytics local run output
325 | ASALocalRun/
326 |
327 | # MSBuild Binary and Structured Log
328 | *.binlog
329 |
330 | # NVidia Nsight GPU debugger configuration file
331 | *.nvuser
332 |
333 | # MFractors (Xamarin productivity tool) working folder
334 | .mfractor/
335 |
336 | # Local History for Visual Studio
337 | .localhistory/
338 |
339 | # BeatPulse healthcheck temp database
340 | healthchecksdb
--------------------------------------------------------------------------------
/Lib_Share/Lib_Share.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {55CE1B3E-4D23-4566-881B-C4F463671785}
8 | Library
9 | Properties
10 | Lib.Share
11 | Lib_Share
12 | zh-CN
13 | UAP
14 | 10.0.19041.0
15 | 10.0.17763.0
16 | 14
17 | 512
18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 |
20 |
21 | AnyCPU
22 | true
23 | full
24 | false
25 | bin\Debug\
26 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
27 | prompt
28 | 4
29 |
30 |
31 | AnyCPU
32 | pdbonly
33 | true
34 | bin\Release\
35 | TRACE;NETFX_CORE;WINDOWS_UWP
36 | prompt
37 | 4
38 |
39 |
40 | x86
41 | true
42 | bin\x86\Debug\
43 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
44 | ;2008
45 | full
46 | false
47 | prompt
48 |
49 |
50 | x86
51 | bin\x86\Release\
52 | TRACE;NETFX_CORE;WINDOWS_UWP
53 | true
54 | ;2008
55 | pdbonly
56 | false
57 | prompt
58 |
59 |
60 | ARM
61 | true
62 | bin\ARM\Debug\
63 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
64 | ;2008
65 | full
66 | false
67 | prompt
68 |
69 |
70 | ARM
71 | bin\ARM\Release\
72 | TRACE;NETFX_CORE;WINDOWS_UWP
73 | true
74 | ;2008
75 | pdbonly
76 | false
77 | prompt
78 |
79 |
80 | ARM64
81 | true
82 | bin\ARM64\Debug\
83 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
84 | ;2008
85 | full
86 | false
87 | prompt
88 |
89 |
90 | ARM64
91 | bin\ARM64\Release\
92 | TRACE;NETFX_CORE;WINDOWS_UWP
93 | true
94 | ;2008
95 | pdbonly
96 | false
97 | prompt
98 |
99 |
100 | x64
101 | true
102 | bin\x64\Debug\
103 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
104 | ;2008
105 | full
106 | false
107 | prompt
108 |
109 |
110 | x64
111 | bin\x64\Release\
112 | TRACE;NETFX_CORE;WINDOWS_UWP
113 | true
114 | ;2008
115 | pdbonly
116 | false
117 | prompt
118 |
119 |
120 | PackageReference
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | 6.2.10
133 |
134 |
135 | 1.0.7
136 |
137 |
138 |
139 | 14.0
140 |
141 |
142 |
149 |
--------------------------------------------------------------------------------
/Work-Timer/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
56 |
58 |
59 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
81 |
83 |
87 |
88 |
89 |
90 |
91 |
93 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
112 |
113 |
114 |
115 |
116 |
117 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/Work-Timer/Language/zh-CN/Resources.resw:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 工作计时器
122 |
123 |
124 | 工作时长
125 |
126 |
127 | 添加分组
128 |
129 |
130 | 工作计时器
131 |
132 |
133 | 暗色主题
134 |
135 |
136 | 您可以将该计时器历史记录转移至其它分组,在下方的下拉框中选择目标分组
137 |
138 |
139 | 计时器分组
140 |
141 |
142 | 跟随系统
143 |
144 |
145 | 字体设置
146 |
147 |
148 | 语言设置
149 |
150 |
151 | 亮色主题
152 |
153 |
154 | 修改
155 |
156 |
157 | 开源地址
158 |
159 |
160 | 预设时长
161 |
162 |
163 | 移除
164 |
165 |
166 | 主题设置
167 |
168 |
169 | 转移
170 |
171 |
172 | 取消
173 |
174 |
175 | 确认
176 |
177 |
178 | 是否要移除该分组?该分组下的所有计时器记录都将被移除
179 |
180 |
181 | 是否要移除该计时器记录?
182 |
183 |
184 | 默认
185 |
186 |
187 | 请将字段填写完整
188 |
189 |
190 | 您可以创建不同的分组,以便对不同情景下的计时进行分类。只需添加一个图标,并起一个易识别的名字
191 |
192 |
193 | 计时器分组
194 |
195 |
196 | 已将计时添加到历史记录
197 |
198 |
199 | 转移历史记录
200 |
201 |
202 | 至少需要一个计时器分组
203 |
204 |
205 | 立即重启
206 |
207 |
208 | 应用设置
209 |
210 |
211 | 您更改了静态资源设置,请重启应用以生效
212 |
213 |
214 | 更新说明
215 |
216 |
217 | 等待中
218 |
219 |
220 | 提醒
221 |
222 |
--------------------------------------------------------------------------------
/Work-Timer/Models/Core/AppViewModel.cs:
--------------------------------------------------------------------------------
1 | using Lib.Share.Models;
2 | using Newtonsoft.Json;
3 | using Richasy.Controls.UWP.Popups;
4 | using Richasy.Controls.UWP.Widgets;
5 | using Richasy.Font.UWP;
6 | using Richasy.Font.UWP.Enums;
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Linq;
10 | using System.Threading.Tasks;
11 | using Windows.Storage;
12 | using Windows.UI;
13 | using Windows.UI.Xaml;
14 | using WorkTimer.Components.Dialog;
15 | using WorkTimer.Components.Layout;
16 | using WorkTimer.Models.Enums;
17 |
18 | namespace WorkTimer.Models.Core
19 | {
20 | public partial class AppViewModel
21 | {
22 | public AppViewModel()
23 | {
24 | _changeTimer.Tick += ChangeTimer_Tick;
25 | _durationTimer.Tick += DurationTimer_Tick;
26 | _changeTimer.Start();
27 | }
28 |
29 | private void DurationTimer_Tick(object sender, object e)
30 | {
31 | if (BeginStamp == DateTime.MinValue)
32 | return;
33 | var ts = DateTime.Now - BeginStamp;
34 | string display = $"{ts.Hours:00}:{ts.Minutes:00}:{ts.Seconds:00}";
35 | DurationText = display;
36 | }
37 |
38 | public async Task Init()
39 | {
40 | var folderList = await App._instance.IO.GetLocalDataAsync>(StaticString.FolderListFileName);
41 | var historyList = await App._instance.IO.GetLocalDataAsync>(StaticString.HistoryListFileName);
42 | FolderCollection.Clear();
43 | DisplayHistoryCollection.Clear();
44 | if(!folderList.IsNullOrEmpty())
45 | folderList.ForEach(p => FolderCollection.Add(p));
46 | else
47 | {
48 | var folderItem = new FolderItem(App._instance.App.GetLocalizationTextFromResource(LanguageName.Default), FeatherSymbol.Activity);
49 | FolderCollection.Add(folderItem);
50 | await SaveFolderList();
51 | }
52 |
53 | string lastSelectedFolderId = App._instance.App.GetLocalSetting(Settings.LastSelectFolderId, "");
54 | if (!FolderCollection.Any(p=>p.Id==lastSelectedFolderId))
55 | lastSelectedFolderId = FolderCollection.First().Id;
56 |
57 | CurrentSelectedFolder = FolderCollection.Where(p => p.Id == lastSelectedFolderId).First();
58 |
59 | if (!historyList.IsNullOrEmpty())
60 | {
61 | AllHistoryList = historyList;
62 | historyList.Where(p => p.FolderId == lastSelectedFolderId).ToList().ForEach(p=>DisplayHistoryCollection.Add(p));
63 | HistoryChanged?.Invoke(this, EventArgs.Empty);
64 | }
65 | }
66 | public async Task SaveFolderList()
67 | {
68 | IsFolderListChanged = false;
69 | List folderList = new List();
70 | folderList = FolderCollection.ToList();
71 | await App._instance.IO.SetLocalDataAsync(StaticString.FolderListFileName, JsonConvert.SerializeObject(folderList));
72 | }
73 | public async Task SaveHistoryList()
74 | {
75 | IsHistoryListChanged = false;
76 | await App._instance.IO.SetLocalDataAsync(StaticString.HistoryListFileName, JsonConvert.SerializeObject(AllHistoryList));
77 | }
78 | private async void ChangeTimer_Tick(object sender, object e)
79 | {
80 | await SaveData();
81 | }
82 | public void AddHistoryItem(HistoryItem item)
83 | {
84 | AllHistoryList.Add(item);
85 | if (item.FolderId == CurrentSelectedFolder.Id)
86 | DisplayHistoryCollection.Add(item);
87 | DurationText = "00:00:00";
88 | BeginStamp = DateTime.MinValue;
89 | ShowPopup(LanguageName.HasAddedHistoryItem);
90 | IsHistoryListChanged = true;
91 | }
92 | public void AddOrUpdateFolderItem(FolderItem item)
93 | {
94 | if (FolderCollection.Contains(item))
95 | {
96 | int sourceIndex = FolderCollection.IndexOf(item);
97 | FolderCollection.Remove(item);
98 | FolderCollection.Insert(sourceIndex, item);
99 | if (CurrentSelectedFolder != null && CurrentSelectedFolder.Equals(item))
100 | CurrentSelectedFolderChanged?.Invoke(this, item);
101 | IsFolderListChanged = true;
102 | }
103 | else
104 | {
105 | FolderCollection.Add(item);
106 | IsFolderListChanged = true;
107 | }
108 | }
109 | public async Task RemoveFolder(FolderItem item)
110 | {
111 | if (FolderCollection.Count == 1)
112 | {
113 | ShowPopup(LanguageName.NeedOneFolder, true);
114 | return;
115 | }
116 | var confirmDialog = new ConfirmDialog(LanguageName.ConfirmRemoveFolder);
117 | confirmDialog.PrimaryButtonClick += (_s, _e) =>
118 | {
119 | FolderCollection.Remove(item);
120 | AllHistoryList.RemoveAll(p => p.FolderId == item.Id);
121 | if (CurrentSelectedFolder.Equals(item))
122 | {
123 | var first = FolderCollection.First();
124 | CurrentSelectedFolder = first;
125 | }
126 | IsFolderListChanged = true;
127 | IsHistoryListChanged = true;
128 | };
129 | await confirmDialog.ShowAsync();
130 | }
131 | public async Task RemoveHistory(HistoryItem item)
132 | {
133 | var confirmDialog = new ConfirmDialog(LanguageName.ConfirmRemoveHistory);
134 | confirmDialog.PrimaryButtonClick += (_s, _e) =>
135 | {
136 | AllHistoryList.Remove(item);
137 | DisplayHistoryCollection.Remove(item);
138 | IsHistoryListChanged = true;
139 | };
140 | await confirmDialog.ShowAsync();
141 | }
142 | public void MoveHistory(HistoryItem source,string newFolderId)
143 | {
144 | foreach (var item in AllHistoryList)
145 | {
146 | if (item.Id == source.Id)
147 | {
148 | item.FolderId = newFolderId;
149 | break;
150 | }
151 | }
152 | DisplayHistoryCollection.Remove(source);
153 | IsHistoryListChanged = true;
154 | }
155 | public async Task SaveData()
156 | {
157 | if (IsFolderListChanged)
158 | await SaveFolderList();
159 | if (IsHistoryListChanged)
160 | await SaveHistoryList();
161 | }
162 | public void ShowPopup(LanguageName name,bool isError = false)
163 | {
164 | ShowPopup(App._instance.App.GetLocalizationTextFromResource(name), isError);
165 | }
166 | public void ShowPopup(string msg, bool isError = false)
167 | {
168 | var popup = new TipPopup(App._instance, msg);
169 | ColorName color = isError ? ColorName.ErrorColor : ColorName.PrimaryColor;
170 | popup.Show(color);
171 | }
172 |
173 | public void ShowSettingPopup()
174 | {
175 | if (SettingPopup == null)
176 | {
177 | var header = new CenterPopupHeader();
178 | header.Padding = new Thickness(20, 10, 20, 10);
179 | header.Title = App._instance.App.GetLocalizationTextFromResource(LanguageName.Settings);
180 | header.CloseButtonStyle = App._instance.App.GetStyleFromResource(StyleName.PopupHeaderButtonStyle);
181 | header.TitleTextStyle = App._instance.App.GetStyleFromResource(StyleName.SubtitleTextStyle);
182 | header.CloseIcon = new FeatherIcon(FeatherSymbol.X) { FontSize = 13 };
183 | var settingPanel = new SettingPanel();
184 | SettingPopup = CenterPopup.CreatePopup(App._instance, header, settingPanel);
185 | header.CloseButtonClick += (_s, _e) =>
186 | {
187 | SettingPopup.Hide();
188 | };
189 | SettingPopup.Style = App._instance.App.GetStyleFromResource(StyleName.BasicCenterPopupStyle);
190 | }
191 | SettingPopup.Show();
192 | }
193 |
194 | public async void CheckUpdate()
195 | {
196 | string localVersion = App._instance.App.GetLocalSetting(Settings.AppVersion, "");
197 | if (localVersion != VersionBlock.Version)
198 | {
199 | var main = new VersionBlock();
200 | main.Title = App._instance.App.GetLocalizationTextFromResource(LanguageName.UpdateTitle);
201 | string lan = App._instance.App.GetLocalSetting(Settings.Language, "zh_CN");
202 | var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Others/Update_{lan}.txt"));
203 | string content = await FileIO.ReadTextAsync(file);
204 | main.Description = content;
205 | main.LogoUri = "ms-appx:///Assets/AppLogo.png";
206 | main.ActionButtonStyle = App._instance.App.GetStyleFromResource(StyleName.PrimaryActionButtonStyle);
207 | main.ActionIcon = new FeatherIcon(FeatherSymbol.X);
208 | main.TitleTextStyle = App._instance.App.GetStyleFromResource(StyleName.SubtitleTextStyle);
209 | main.DescriptionTextStyle = App._instance.App.GetStyleFromResource(StyleName.BasicMarkdownTextBlock);
210 | var popup = new CenterPopup(App._instance);
211 | popup.Style = App._instance.App.GetStyleFromResource(StyleName.BasicCenterPopupStyle);
212 | popup.Main = main;
213 | main.ActionButtonClick += (_s, _e) =>
214 | {
215 | popup.Hide();
216 | App._instance.App.WriteLocalSetting(Settings.AppVersion, VersionBlock.Version);
217 | };
218 | popup.Show();
219 | }
220 | }
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/Work-Timer/Language/en-US/Resources.resw:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Work Timer
122 |
123 |
124 | Work Duration
125 |
126 |
127 | Add folder
128 |
129 |
130 | Work Timer
131 |
132 |
133 | Dark
134 |
135 |
136 | You can transfer the timer history to other folder, select the target folder in the combo box below
137 |
138 |
139 | Timer Folder
140 |
141 |
142 | System
143 |
144 |
145 | Font
146 |
147 |
148 | Language
149 |
150 |
151 | Light
152 |
153 |
154 | Modify
155 |
156 |
157 | Open source link
158 |
159 |
160 | Preset Duration
161 |
162 |
163 | Remove
164 |
165 |
166 | Theme
167 |
168 |
169 | Transfer
170 |
171 |
172 | Cancel
173 |
174 |
175 | Confirm
176 |
177 |
178 | Do you want to remove the folder? All timer records in this folder will be removed
179 |
180 |
181 | Do you want to remove the timer record?
182 |
183 |
184 | Default
185 |
186 |
187 | Please complete the fields
188 |
189 |
190 | You can create different folders to categorize the timing in different scenarios. Just add an icon and give it an easily recognizable name
191 |
192 |
193 | Timer Folder
194 |
195 |
196 | Added timing to history
197 |
198 |
199 | Transfer History
200 |
201 |
202 | At least one timer folder is required
203 |
204 |
205 | Restart
206 |
207 |
208 | App Settings
209 |
210 |
211 | You changed the static resource settings, please restart the application to take effect
212 |
213 |
214 | Update Information
215 |
216 |
217 | Waiting
218 |
219 |
220 | Warning
221 |
222 |
--------------------------------------------------------------------------------
/Work-Timer/Template/Button.xaml:
--------------------------------------------------------------------------------
1 |
6 |
17 |
29 |
42 |
45 |
55 |
65 |
78 |
79 |
141 |
215 |
216 |
--------------------------------------------------------------------------------
/Work-Timer/Work-Timer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x86
7 | {B91BF1A1-0D7A-40B8-AA3E-C1F7D7F2DE88}
8 | AppContainerExe
9 | Properties
10 | WorkTimer
11 | Work-Timer
12 | en-US
13 | UAP
14 | 10.0.19041.0
15 | 10.0.17763.0
16 | 14
17 | 512
18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 | true
20 | false
21 | False
22 | False
23 | D:\Package\Work-Timer\
24 | False
25 | Always
26 | x86|x64|arm|arm64
27 | 0
28 |
29 |
30 | true
31 | bin\x86\Debug\
32 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
33 | ;2008
34 | full
35 | x86
36 | false
37 | prompt
38 | true
39 |
40 |
41 | bin\x86\Release\
42 | TRACE;NETFX_CORE;WINDOWS_UWP
43 | true
44 | ;2008
45 | pdbonly
46 | x86
47 | false
48 | prompt
49 | true
50 | true
51 |
52 |
53 | true
54 | bin\ARM\Debug\
55 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
56 | ;2008
57 | full
58 | ARM
59 | false
60 | prompt
61 | true
62 |
63 |
64 | bin\ARM\Release\
65 | TRACE;NETFX_CORE;WINDOWS_UWP
66 | true
67 | ;2008
68 | pdbonly
69 | ARM
70 | false
71 | prompt
72 | true
73 | true
74 |
75 |
76 | true
77 | bin\ARM64\Debug\
78 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
79 | ;2008
80 | full
81 | ARM64
82 | false
83 | prompt
84 | true
85 | true
86 |
87 |
88 | bin\ARM64\Release\
89 | TRACE;NETFX_CORE;WINDOWS_UWP
90 | true
91 | ;2008
92 | pdbonly
93 | ARM64
94 | false
95 | prompt
96 | true
97 | true
98 |
99 |
100 | true
101 | bin\x64\Debug\
102 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
103 | ;2008
104 | full
105 | x64
106 | false
107 | prompt
108 | true
109 |
110 |
111 | bin\x64\Release\
112 | TRACE;NETFX_CORE;WINDOWS_UWP
113 | true
114 | ;2008
115 | pdbonly
116 | x64
117 | false
118 | prompt
119 | true
120 | true
121 |
122 |
123 | PackageReference
124 |
125 |
126 |
127 | App.xaml
128 |
129 |
130 | ConfirmDialog.xaml
131 |
132 |
133 | FolderDialog.xaml
134 |
135 |
136 | FolderSelectionDialog.xaml
137 |
138 |
139 | FolderPanel.xaml
140 |
141 |
142 | HistoryPanel.xaml
143 |
144 |
145 | SettingPanel.xaml
146 |
147 |
148 | WorkDurationBlock.xaml
149 |
150 |
151 | MainPage.xaml
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 | Designer
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 | MSBuild:Compile
236 | Designer
237 |
238 |
239 | Designer
240 | MSBuild:Compile
241 |
242 |
243 | Designer
244 | MSBuild:Compile
245 |
246 |
247 | Designer
248 | MSBuild:Compile
249 |
250 |
251 | Designer
252 | MSBuild:Compile
253 |
254 |
255 | Designer
256 | MSBuild:Compile
257 |
258 |
259 | Designer
260 | MSBuild:Compile
261 |
262 |
263 | Designer
264 | MSBuild:Compile
265 |
266 |
267 | MSBuild:Compile
268 | Designer
269 |
270 |
271 | Designer
272 | MSBuild:Compile
273 |
274 |
275 | Designer
276 | MSBuild:Compile
277 |
278 |
279 | Designer
280 | MSBuild:Compile
281 |
282 |
283 | Designer
284 | MSBuild:Compile
285 |
286 |
287 | Designer
288 | MSBuild:Compile
289 |
290 |
291 | Designer
292 | MSBuild:Compile
293 |
294 |
295 | Designer
296 | MSBuild:Compile
297 |
298 |
299 |
300 |
301 | 6.2.10
302 |
303 |
304 | 6.1.0
305 |
306 |
307 | 12.0.3
308 |
309 |
310 | 1.0.9
311 |
312 |
313 | 1.0.7
314 |
315 |
316 | 1.0.5
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 | {55CE1B3E-4D23-4566-881B-C4F463671785}
328 | Lib_Share
329 |
330 |
331 |
332 | 14.0
333 |
334 |
335 |
342 |
--------------------------------------------------------------------------------