diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Theme/Uri.xaml b/src/Snap.Hutao/Snap.Hutao/Control/Theme/Uri.xaml
index 090e6817..2d8cbaa4 100644
--- a/src/Snap.Hutao/Snap.Hutao/Control/Theme/Uri.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/Control/Theme/Uri.xaml
@@ -17,8 +17,13 @@
https://api.snapgenshin.com/static/raw/Bg/UI_Icon_Intee_Explore_1.png
https://api.snapgenshin.com/static/raw/Bg/UI_ImgSign_ItemIcon.png
https://api.snapgenshin.com/static/raw/Bg/UI_ItemIcon_None.png
- https://api.snapgenshin.com/static/raw/Bg/UI_MarkQuest_Events_Proce.png
- https://api.snapgenshin.com/static/raw/Bg/UI_MarkTower.png
+
+
+ https://api.snapgenshin.com/static/raw/Mark/UI_MarkQuest_Events_Proce.png
+ https://api.snapgenshin.com/static/raw/Mark/UI_MarkQuest_Events_Start.png
+ https://api.snapgenshin.com/static/raw/Mark/UI_MarkQuest_Main_Proce.png
+ https://api.snapgenshin.com/static/raw/Mark/UI_MarkQuest_Main_Start.png
+ https://api.snapgenshin.com/static/raw/Mark/UI_MarkTower.png
https://api.snapgenshin.com/static/raw/ItemIcon/UI_ItemIcon_201.png
diff --git a/src/Snap.Hutao/Snap.Hutao/IdentityStructs.json b/src/Snap.Hutao/Snap.Hutao/IdentityStructs.json
index cd8c0019..9a59b452 100644
--- a/src/Snap.Hutao/Snap.Hutao/IdentityStructs.json
+++ b/src/Snap.Hutao/Snap.Hutao/IdentityStructs.json
@@ -23,6 +23,18 @@
"Equatable": true,
"EqualityOperators": true
},
+ {
+ "Name": "ChapterId",
+ "Documentation": "章节 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
+ {
+ "Name": "ChapterGroupId",
+ "Documentation": "章节分组 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
{
"Name": "EquipAffixId",
"Documentation": "装备属性 Id",
@@ -113,6 +125,12 @@
"Equatable": true,
"EqualityOperators": true
},
+ {
+ "Name": "QuestId",
+ "Documentation": "任务 Id",
+ "Equatable": true,
+ "EqualityOperators": true
+ },
{
"Name": "ReliquaryLevel",
"Documentation": "圣遗物等级 1 - 21",
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/DailyNoteEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/DailyNoteEntry.cs
index 2707e75d..f4d0f945 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/DailyNoteEntry.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/DailyNoteEntry.cs
@@ -4,6 +4,8 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Core.Abstraction;
using Snap.Hutao.Model.Entity.Abstraction;
+using Snap.Hutao.Model.Primitive;
+using Snap.Hutao.ViewModel.DailyNote;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote;
@@ -53,6 +55,9 @@ internal sealed class DailyNoteEntry : ObservableObject, IMappingFrom
public DailyNote? DailyNote { get; set; }
+ [NotMapped]
+ public DailyNoteArchonQuestView ArchonQuestView { get; set; } = default!;
+
///
/// 刷新时间
///
@@ -128,4 +133,4 @@ internal sealed class DailyNoteEntry : ObservableObject, IMappingFrom
+ /// Archon Quest 魔神任务
+ ///
AQ,
+
+ ///
+ /// Fractions Quest 帮派任务
+ ///
FQ,
+
+ ///
+ /// Legend Quest 传说任务
+ ///
LQ,
+
+ ///
+ /// Event Quest 活动任务
+ ///
EQ,
+
+ ///
+ /// Daily Quest 日常任务
+ ///
DQ,
+
+ ///
+ /// Indescribable Quest 不可描述的任务?
+ ///
IQ,
+
VQ,
+
+ ///
+ /// World Quest 世界任务
+ ///
WQ,
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Chapter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Chapter.cs
new file mode 100644
index 00000000..01434f40
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Chapter.cs
@@ -0,0 +1,34 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Model.Intrinsic;
+using Snap.Hutao.Model.Primitive;
+
+namespace Snap.Hutao.Model.Metadata;
+
+internal sealed class Chapter
+{
+ public ChapterId Id { get; set; }
+
+ public ChapterGroupId GroupId { get; set; }
+
+ public QuestId BeginQuestId { get; set; }
+
+ public QuestId EndQuestId { get; set; }
+
+ public uint NeedPlayerLevel { get; set; }
+
+ public string Number { get; set; } = default!;
+
+ public string Title { get; set; } = default!;
+
+ public string Icon { get; set; } = default!;
+
+ public string ImageTitle { get; set; } = default!;
+
+ public string SerialNumberIcon { get; set; } = default!;
+
+ public City CityId { get; set; }
+
+ public QuestType QuestType { get; set; }
+}
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/City.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/City.cs
index 799fbb51..2cbb5ed1 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/City.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/City.cs
@@ -6,6 +6,7 @@ namespace Snap.Hutao.Model.Metadata;
// CityTaskOpenExcelConfig
internal enum City : uint
{
+ None = 0,
Mondstadt = 1,
Liyue = 2,
Inazuma = 3,
diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx
index 8dde5516..73dee2ef 100644
--- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx
+++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx
@@ -3044,6 +3044,9 @@
已复制到剪贴板
+
+ 所有魔神任务已完成
+
全部完成
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteMetadataContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteMetadataContext.cs
new file mode 100644
index 00000000..c2636753
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteMetadataContext.cs
@@ -0,0 +1,13 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Snap.Hutao.Model.Metadata;
+using Snap.Hutao.Service.Metadata.ContextAbstraction;
+
+namespace Snap.Hutao.Service.DailyNote;
+
+internal class DailyNoteMetadataContext : IMetadataContext,
+ IMetadataListChapterSource
+{
+ public List Chapters { get; set; } = default!;
+}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteService.cs b/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteService.cs
index 68897c1f..eb3fe322 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteService.cs
@@ -5,7 +5,11 @@ using CommunityToolkit.Mvvm.Messaging;
using Snap.Hutao.Core.DependencyInjection.Abstraction;
using Snap.Hutao.Message;
using Snap.Hutao.Model.Entity;
+using Snap.Hutao.Service.Abstraction;
+using Snap.Hutao.Service.Metadata;
+using Snap.Hutao.Service.Metadata.ContextAbstraction;
using Snap.Hutao.Service.User;
+using Snap.Hutao.ViewModel.DailyNote;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Hoyolab;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
@@ -83,9 +87,18 @@ internal sealed partial class DailyNoteService : IDailyNoteService, IRecipient entryList = await dailyNoteDbService.GetDailyNoteEntryListIncludingUserAsync(token).ConfigureAwait(false);
- entryList.ForEach(entry => { entry.UserGameRole = userService.GetUserGameRoleByUid(entry.Uid); });
- entries = entryList.ToObservableCollection();
+ using (IServiceScope scope = serviceProvider.CreateScope())
+ {
+ DailyNoteMetadataContext context = await scope.GetRequiredService().GetContextAsync(token).ConfigureAwait(false);
+
+ List entryList = await dailyNoteDbService.GetDailyNoteEntryListIncludingUserAsync(token).ConfigureAwait(false);
+ entryList.ForEach(entry =>
+ {
+ entry.UserGameRole = userService.GetUserGameRoleByUid(entry.Uid);
+ entry.ArchonQuestView = DailyNoteArchonQuestView.Create(entry.DailyNote, context.Chapters);
+ });
+ entries = entryList.ToObservableCollection();
+ }
}
return entries;
@@ -159,4 +172,4 @@ internal sealed partial class DailyNoteService : IDailyNoteService, IRecipient Chapters { get; set; }
+}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs
index 7cd18212..fd17f81d 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs
@@ -23,6 +23,11 @@ internal static class MetadataServiceContextExtension
listAchievementSource.Achievements = await metadataService.GetAchievementListAsync(token).ConfigureAwait(false);
}
+ if (context is IMetadataListChapterSource listChapterSource)
+ {
+ listChapterSource.Chapters = await metadataService.GetChapterListAsync(token).ConfigureAwait(false);
+ }
+
if (context is IMetadataListGachaEventSource listGachaEventSource)
{
listGachaEventSource.GachaEvents = await metadataService.GetGachaEventListAsync(token).ConfigureAwait(false);
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataFileNames.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataFileNames.cs
index f668c965..6a2e2b5c 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataFileNames.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataFileNames.cs
@@ -10,6 +10,7 @@ internal static class MetadataFileNames
public const string FileNameAvatar = "Avatar";
public const string FileNameAvatarCurve = "AvatarCurve";
public const string FileNameAvatarPromote = "AvatarPromote";
+ public const string FileNameChapter = "Chapter";
public const string FileNameDisplayItem = "DisplayItem";
public const string FileNameGachaEvent = "GachaEvent";
public const string FileNameMaterial = "Material";
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataServiceListExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataServiceListExtension.cs
index 4377b0e3..1532e245 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataServiceListExtension.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataServiceListExtension.cs
@@ -20,6 +20,11 @@ internal static class MetadataServiceListExtension
return metadataService.FromCacheOrFileAsync>(FileNameAchievement, token);
}
+ public static ValueTask> GetChapterListAsync(this IMetadataService metadataService, CancellationToken token = default)
+ {
+ return metadataService.FromCacheOrFileAsync>(FileNameChapter, token);
+ }
+
public static ValueTask> GetAchievementGoalListAsync(this IMetadataService metadataService, CancellationToken token = default)
{
return metadataService.FromCacheOrFileAsync>(FileNameAchievementGoal, token);
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/DailyNotePage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/DailyNotePage.xaml
index 62875649..d695ac9f 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Page/DailyNotePage.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/View/Page/DailyNotePage.xaml
@@ -3,7 +3,8 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cw="using:CommunityToolkit.WinUI"
- xmlns:cwc="using:CommunityToolkit.WinUI.Controls"
+ xmlns:cwcont="using:CommunityToolkit.WinUI.Controls"
+ xmlns:cwconv="using:CommunityToolkit.WinUI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
@@ -12,6 +13,7 @@
xmlns:shch="using:Snap.Hutao.Control.Helper"
xmlns:shci="using:Snap.Hutao.Control.Image"
xmlns:shcm="using:Snap.Hutao.Control.Markup"
+ xmlns:shme="using:Snap.Hutao.Model.Entity"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:shvcp="using:Snap.Hutao.View.Card.Primitive"
xmlns:shvd="using:Snap.Hutao.ViewModel.DailyNote"
@@ -26,6 +28,16 @@
+
+
+
+
@@ -43,7 +55,7 @@
-
+
@@ -108,6 +120,43 @@
Grid.Row="1"
Margin="0,8,0,0"
Spacing="6">
+
+
+
+
+
+
+
+
+
+
+
+
@@ -202,7 +251,7 @@
Margin="4"
VerticalAlignment="Center"
shch:FrameworkElementHelper.SquareLength="32"
- Source="{StaticResource UI_MarkQuest_Events_Proce}"/>
+ Source="{Binding DailyNote.DailyTask.IsExtraTaskRewardReceived, Converter={StaticResource DailyTaskIconConverter}}"/>
-
@@ -450,16 +499,16 @@
0
-
-
+
-
+
-
-
+
-
+
-
-
+
-
+
-
-
-
+
-
+
-
+
- chapters)
+ {
+ this.dailyNote = dailyNote;
+ Ids = chapters
+ .Where(chapter => chapter.QuestType is QuestType.AQ)
+ .Select(chapter => chapter.Id)
+ .ToList();
+ }
+
+ public List Ids { get; set; } = default!;
+
+ public int ProgressValue
+ {
+ get
+ {
+ if (TryGetFirstArchonQuest(out ArchonQuest? quest))
+ {
+ return Ids.IndexOf(quest.Id);
+ }
+
+ return Ids.Count;
+ }
+ }
+
+ public string ProgressFormatted
+ {
+ get
+ {
+ if (TryGetFirstArchonQuest(out ArchonQuest? quest))
+ {
+ return quest.Status.GetLocalizedDescription();
+ }
+
+ return SH.WebDailyNoteArchonQuestStatusFinished;
+ }
+ }
+
+ public string ChapterFormatted
+ {
+ get
+ {
+ if (TryGetFirstArchonQuest(out ArchonQuest? quest))
+ {
+ return $"{quest.ChapterNum} {quest.ChapterTitle}";
+ }
+
+ return SH.WebDailyNoteArchonQuestChapterFinished;
+ }
+ }
+
+ public static DailyNoteArchonQuestView Create(WebDailyNote? dailyNote, List chapters)
+ {
+ return new(dailyNote, chapters);
+ }
+
+ private bool TryGetFirstArchonQuest([NotNullWhen(true)] out ArchonQuest? archonQuest)
+ {
+ if (dailyNote is { ArchonQuestProgress.List: [{ } target, ..] })
+ {
+ archonQuest = target;
+ return true;
+ }
+
+ archonQuest = default;
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNote/DailyNoteViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNote/DailyNoteViewModel.cs
index 0a08086e..bb0e89b0 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNote/DailyNoteViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNote/DailyNoteViewModel.cs
@@ -7,6 +7,7 @@ using Snap.Hutao.Core;
using Snap.Hutao.Factory.ContentDialog;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Service.DailyNote;
+using Snap.Hutao.Service.Metadata;
using Snap.Hutao.Service.Notification;
using Snap.Hutao.Service.User;
using Snap.Hutao.View.Control;
@@ -27,6 +28,7 @@ internal sealed partial class DailyNoteViewModel : Abstraction.ViewModel
private readonly IContentDialogFactory contentDialogFactory;
private readonly IDailyNoteService dailyNoteService;
private readonly DailyNoteOptions dailyNoteOptions;
+ private readonly IMetadataService metadataService;
private readonly IInfoBarService infoBarService;
private readonly RuntimeOptions runtimeOptions;
private readonly ITaskContext taskContext;
@@ -53,22 +55,26 @@ internal sealed partial class DailyNoteViewModel : Abstraction.ViewModel
protected override async ValueTask InitializeUIAsync()
{
- try
+ if (await metadataService.InitializeAsync().ConfigureAwait(false))
{
- await taskContext.SwitchToBackgroundAsync();
- ObservableCollection roles = await userService.GetRoleCollectionAsync().ConfigureAwait(false);
- ObservableCollection entries = await dailyNoteService.GetDailyNoteEntryCollectionAsync().ConfigureAwait(false);
+ try
+ {
+ await taskContext.SwitchToBackgroundAsync();
+ ObservableCollection roles = await userService.GetRoleCollectionAsync().ConfigureAwait(false);
+ ObservableCollection entries = await dailyNoteService.GetDailyNoteEntryCollectionAsync().ConfigureAwait(false);
- await taskContext.SwitchToMainThreadAsync();
- UserAndUids = roles;
- DailyNoteEntries = entries;
- return true;
- }
- catch (Core.ExceptionService.UserdataCorruptedException ex)
- {
- infoBarService.Error(ex);
- return false;
+ await taskContext.SwitchToMainThreadAsync();
+ UserAndUids = roles;
+ DailyNoteEntries = entries;
+ return true;
+ }
+ catch (Core.ExceptionService.UserdataCorruptedException ex)
+ {
+ infoBarService.Error(ex);
+ }
}
+
+ return false;
}
[Command("TrackRoleCommand")]
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResource.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResource.cs
index d51c1de4..dec258d7 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResource.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResource.cs
@@ -33,6 +33,7 @@ internal static class StaticResource
{ "IconElement", 0 },
{ "ItemIcon", 0 },
{ "LoadingPic", 0 },
+ { "Mark", 0 },
{ "MonsterIcon", 0 },
{ "MonsterSmallIcon", 0 },
{ "NameCardIcon", 0 },
@@ -62,6 +63,7 @@ internal static class StaticResource
{ "IconElement", 3 },
{ "ItemIcon", 4 },
{ "LoadingPic", 2 },
+ { "Mark", 0 },
{ "MonsterIcon", 3 },
{ "MonsterSmallIcon", 2 },
{ "NameCardIcon", 3 },
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs
index a88b0459..9ed8402c 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs
@@ -132,4 +132,10 @@ internal sealed class DailyNote : DailyNoteCommon
[JsonPropertyName("archon_quest_progress")]
public ArchonQuestProgress ArchonQuestProgress { get; set; } = default!;
+
+ [JsonIgnore]
+ public bool IsArchonQuestFinished
+ {
+ get => ArchonQuestProgress.List.Count == 0;
+ }
}
\ No newline at end of file