mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-18 10:10:45 +08:00
* refactor: 重构公告 * chore: 公告可数 * chore: TrimEnd - * fix: 多余删除的 \n * chore: 修改返回类型 * style: unused using * chore: 标题支持多行显示 * chore: add english version of noskland * feat: Switch image based on language * chore: 点击 Listbox 时 ScrollViewer 滚动到最顶端 * chore: 加个预览图 * chore: 设计时预览 * fix: ---- 没移掉) * chore: Content 也显示标题内容 * chore: 隐藏按钮 * perf: 优化分隔符删除 * chore: 压缩下图片 * feat: 调整公告关闭按钮布局 --------- Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com> Co-authored-by: SherkeyXD <57581480+SherkeyXD@users.noreply.github.com>
215 lines
6.7 KiB
C#
215 lines
6.7 KiB
C#
// <copyright file="AnnouncementViewModel.cs" company="MaaAssistantArknights">
|
|
// MaaWpfGui - A part of the MaaCoreArknights project
|
|
// Copyright (C) 2021 MistEO and Contributors
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License v3.0 only as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY
|
|
// </copyright>
|
|
|
|
using System;
|
|
using System.Collections.ObjectModel;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Input;
|
|
using HandyControl.Controls;
|
|
using HandyControl.Tools.Command;
|
|
using MaaWpfGui.Configuration;
|
|
using MaaWpfGui.Constants;
|
|
using MaaWpfGui.Helper;
|
|
using Stylet;
|
|
|
|
namespace MaaWpfGui.ViewModels.UI
|
|
{
|
|
/// <summary>
|
|
/// The view model of version update.
|
|
/// </summary>
|
|
// 通过 container.Get<AnnouncementViewModel>(); 实例化或获取实例
|
|
// ReSharper disable once ClassNeverInstantiated.Global
|
|
public class AnnouncementViewModel : Screen
|
|
{
|
|
public string ImageSource { get; set; }
|
|
|
|
public class AnnouncementSection
|
|
{
|
|
public string Title { get; set; }
|
|
|
|
public string Content { get; set; }
|
|
}
|
|
|
|
public AnnouncementViewModel()
|
|
{
|
|
UpdateImageSource();
|
|
|
|
UpdateScrollStateCommand = new RelayCommand<ScrollViewer>(scrollViewer =>
|
|
{
|
|
if (scrollViewer == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 计算是否滚动到底部
|
|
IsScrolledToBottom |= scrollViewer.VerticalOffset >= scrollViewer.ScrollableHeight - 10;
|
|
});
|
|
|
|
ScrollToTopCommand = new RelayCommand<ScrollViewer>(scrollViewer =>
|
|
{
|
|
if (scrollViewer == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
scrollViewer.ScrollToTop();
|
|
});
|
|
AnnouncementSections = new(
|
|
ParseAnnouncementInfo(AnnouncementInfo));
|
|
SelectedAnnouncementSection = AnnouncementSections.FirstOrDefault();
|
|
}
|
|
|
|
private void UpdateImageSource()
|
|
{
|
|
ImageSource = SettingsViewModel.GuiSettings.Language switch
|
|
{
|
|
"zh-cn" or "zh-tw" => "/Res/Img/NoSkland.jpg",
|
|
_ => "/Res/Img/NoSkLandEn.jpg",
|
|
};
|
|
}
|
|
|
|
private static ObservableCollection<AnnouncementSection> ParseAnnouncementInfo(string markdown)
|
|
{
|
|
var sections = markdown.Split(["### "], StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(section =>
|
|
{
|
|
var lines = section.Split('\n');
|
|
return new AnnouncementSection
|
|
{
|
|
Title = lines.FirstOrDefault(),
|
|
Content = "### " + string.Join("\n", lines).Trim([' ', '\n', '-']),
|
|
};
|
|
}).ToList();
|
|
|
|
sections.Insert(0, new()
|
|
{
|
|
Title = "ALL~ the Announcements",
|
|
Content = markdown,
|
|
});
|
|
|
|
return new(sections);
|
|
}
|
|
|
|
public ICommand UpdateScrollStateCommand { get; }
|
|
|
|
public ICommand ScrollToTopCommand { get; }
|
|
|
|
private bool _isScrolledToBottom;
|
|
|
|
public bool IsScrolledToBottom
|
|
{
|
|
get => _isScrolledToBottom;
|
|
set => SetAndNotify(ref _isScrolledToBottom, value);
|
|
}
|
|
|
|
private ObservableCollection<AnnouncementSection> _announcementSections;
|
|
|
|
public ObservableCollection<AnnouncementSection> AnnouncementSections
|
|
{
|
|
get => _announcementSections;
|
|
set => SetAndNotify(ref _announcementSections, value);
|
|
}
|
|
|
|
private AnnouncementSection _selectedAnnouncementSection;
|
|
|
|
public AnnouncementSection SelectedAnnouncementSection
|
|
{
|
|
get => _selectedAnnouncementSection;
|
|
set => SetAndNotify(ref _selectedAnnouncementSection, value);
|
|
}
|
|
|
|
private string _announcementInfo = ConfigFactory.Root.AnnouncementInfo.Info;
|
|
|
|
/// <summary>
|
|
/// Gets the announcement info.
|
|
/// </summary>
|
|
// ReSharper disable once MemberCanBePrivate.Global
|
|
public string AnnouncementInfo
|
|
{
|
|
get => _announcementInfo;
|
|
private set
|
|
{
|
|
SetAndNotify(ref _announcementInfo, value);
|
|
ConfigFactory.Root.AnnouncementInfo.Info = value;
|
|
}
|
|
}
|
|
|
|
private bool _doNotRemindThisAnnouncementAgain = ConfigFactory.Root.AnnouncementInfo.DoNotShowAgain;
|
|
|
|
public bool DoNotRemindThisAnnouncementAgain
|
|
{
|
|
get => _doNotRemindThisAnnouncementAgain;
|
|
set
|
|
{
|
|
SetAndNotify(ref _doNotRemindThisAnnouncementAgain, value);
|
|
ConfigFactory.Root.AnnouncementInfo.DoNotShowAgain = value;
|
|
}
|
|
}
|
|
|
|
private bool _doNotShowAnnouncement = ConfigFactory.Root.AnnouncementInfo.DoNotShow;
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether to show the update.
|
|
/// </summary>
|
|
public bool DoNotShowAnnouncement
|
|
{
|
|
get => _doNotShowAnnouncement;
|
|
set
|
|
{
|
|
SetAndNotify(ref _doNotShowAnnouncement, value);
|
|
ConfigFactory.Root.AnnouncementInfo.DoNotShow = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查更新
|
|
/// </summary>
|
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
|
public async Task CheckAndDownloadAnnouncement()
|
|
{
|
|
string path = "announcements/wpf";
|
|
if (SettingsViewModel.GuiSettings.Language is not ("zh-cn" or "zh-tw"))
|
|
{
|
|
path += "_en";
|
|
}
|
|
|
|
string url = MaaUrls.MaaApi + path + ".md";
|
|
|
|
using var response = await ETagCache.FetchResponseWithEtag(url, string.IsNullOrEmpty(AnnouncementInfo));
|
|
|
|
if (response == null ||
|
|
response.StatusCode == System.Net.HttpStatusCode.NotModified ||
|
|
response.StatusCode != System.Net.HttpStatusCode.OK)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var body = await HttpResponseHelper.GetStringAsync(response);
|
|
if (!string.IsNullOrEmpty(body))
|
|
{
|
|
AnnouncementInfo = body;
|
|
DoNotRemindThisAnnouncementAgain = false;
|
|
}
|
|
|
|
ETagCache.Set(response);
|
|
ETagCache.Save();
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
RequestClose();
|
|
}
|
|
}
|
|
}
|