diff --git a/.github/workflows/choco.yml b/.github/workflows/choco.yml new file mode 100644 index 000000000..8c8c1e9df --- /dev/null +++ b/.github/workflows/choco.yml @@ -0,0 +1,40 @@ +name: Pack and Push Chocolatey Package + +on: + workflow_dispatch: + inputs: + version: + description: "The version of the package" + required: true + type: string + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CHOCO_TOKEN: ${{ secrets.CHOCO_TOKEN }} + +jobs: + pack-and-push: + runs-on: windows-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.9" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install requests + + - name: Check choco + run: | + choco -v + + - name: Run packChoco.py script + run: | + $env:PYTHONUNBUFFERED = "1" + python scripts/packChoco.py --version ${{ github.event.inputs.version }} --githubtoken ${{ env.GITHUB_TOKEN }} --chocotoken ${{ env.CHOCO_TOKEN }} diff --git a/scripts/chocolaty-templates/BiliLite-uwp.nuspec b/scripts/chocolaty-templates/BiliLite-uwp.nuspec new file mode 100644 index 000000000..405de7347 --- /dev/null +++ b/scripts/chocolaty-templates/BiliLite-uwp.nuspec @@ -0,0 +1,19 @@ + + + + BiliLite-uwp-{arch} + {version}-beta + BiliLite-uwp + ruamuyan + ruamuyan + https://github.com/ywmoyue/biliuwp-lite + https://github.com/ywmoyue/biliuwp-lite/discussions + https://github.com/ywmoyue/biliuwp-lite/discussions + https://github.com/ywmoyue/biliuwp-lite + https://github.com/ywmoyue/biliuwp-lite + Bilibili third-party UWP client third-party release version. Fork from https://github.com/xiaoyaocz/biliuwp-lite. + Bilibili third-party UWP client third-party release version. + https://raw.githubusercontent.com/ywmoyue/biliuwp-lite/refs/heads/master/src/BiliLite.Packages/Images/StoreLogo.scale-400.png + UWP BiliBili + + \ No newline at end of file diff --git a/scripts/chocolaty-templates/tools/chocolateyInstall.ps1 b/scripts/chocolaty-templates/tools/chocolateyInstall.ps1 new file mode 100644 index 000000000..6ebce107a --- /dev/null +++ b/scripts/chocolaty-templates/tools/chocolateyInstall.ps1 @@ -0,0 +1,98 @@ +# Due to Powershell limitations, this script can only be opened with GBK encoding +$AppName = "BiliLite.Packages" +$Version = "{version}" +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +Write-Output "scriptDir: $scriptDir" + +# 获取系统架构 +$arch = $env:PROCESSOR_ARCHITECTURE +# 判断架构并赋值 +if ($arch -eq "AMD64") { + $systemArch = "x64" +} elseif ($arch -eq "x86") { + $systemArch = "x86" +} elseif ($arch -eq "ARM64") { + $systemArch = "ARM64" +} else { + $systemArch = "Unknown" +} + +$Package = "{0}_{1}_{2}" -f $AppName, $Version, $systemArch +Write-Output "Package: $Package" + +# 找到对应的安装包并解压到unpack路径 +$PackageZipRelativePath = "..\resources\{0}.zip" -f $Package +$PackageZipPath = Join-Path $scriptDir $PackageZipRelativePath +$UnpackPath = Join-Path $scriptDir "..\unpack" + +# 检查文件是否存在并解压 +if (Test-Path $PackageZipPath) { + # 确保解压路径存在 + if (-not (Test-Path $UnpackPath)) { + New-Item -ItemType Directory -Path $UnpackPath | Out-Null + } + + # 解压文件 + Expand-Archive -Path $PackageZipPath -DestinationPath $UnpackPath -Force + Write-Host "文件已解压到 $UnpackPath" +} else { + Write-Host "文件 $PackageZipPath 不存在,即将从 GitHub 下载当前平台适配的安装包" + + # 从 GitHub 下载软件包并解压 + $downloadUrl = "https://github.com/ywmoyue/biliuwp-lite/releases/download/v{0}/{1}.zip" -f $Version, $Package + Write-Host "下载地址: $downloadUrl" + + try { + # 下载文件 + Invoke-WebRequest -Uri $downloadUrl -OutFile $PackageZipPath + Write-Host "文件下载完成: $PackageZipPath" + + # 确保解压路径存在 + if (-not (Test-Path $UnpackPath)) { + New-Item -ItemType Directory -Path $UnpackPath | Out-Null + } + + # 解压文件 + Expand-Archive -Path $PackageZipPath -DestinationPath $UnpackPath -Force + Write-Host "文件已解压到 $UnpackPath" + } catch { + Write-Host "下载或解压失败: $_" + exit 1 + } +} + +# 设置开发者模式允许安装未知来源包 +Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" -Name "AllowDevelopmentWithoutDevLicense" -Value 1 +Write-Host "已允许安装未知来源包" + +# 证书路径 +$certRelativePath = "..\unpack\{0}_Test\{0}.cer" -f $Package +$certPath = Resolve-Path (Join-Path $scriptDir $certRelativePath) + +# 安装脚本路径 +$installScriptPath = "$scriptDir\..\unpack\{0}_Test\install.ps1" -f $Package +Write-Host "安装路径 $installScriptPath" + +# 安装证书 +try { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 + $cert.Import($certPath.Path) + + $store = New-Object System.Security.Cryptography.X509Certificates.X509Store("Root", "LocalMachine") + $store.Open("ReadWrite") + $store.Add($cert) + $store.Close() + Write-Host "证书安装完成" +} catch { + Write-Host "证书安装失败: $_" + exit 1 +} + +# 执行安装脚本 +try { + . "$installScriptPath" + Write-Host "安装脚本执行成功" +} catch { + Write-Host "安装脚本执行失败: $_" + exit 1 +} \ No newline at end of file diff --git a/scripts/chocolaty-templates/tools/chocolateyUninstall.ps1 b/scripts/chocolaty-templates/tools/chocolateyUninstall.ps1 new file mode 100644 index 000000000..798fcaf6d --- /dev/null +++ b/scripts/chocolaty-templates/tools/chocolateyUninstall.ps1 @@ -0,0 +1,18 @@ +# Due to Powershell limitations, this script can only be opened with GBK encoding +$PackageId = "5422.502643927C6AD" + +$PackageNamePrefix = "{0}_" -f $PackageId +Write-Host "PackageNamePrefix: $PackageNamePrefix" + +# 获取UWP包完整名称 +$PackageFullName = (Get-AppxPackage | Where-Object { $_.PackageFullName -like "$PackageNamePrefix*" }).PackageFullName +Write-Host "PackageFullName: $PackageFullName" + +if ($PackageFullName) { + Write-Host "找到 UWP 包: $PackageFullName" + # 卸载 UWP 包 + Remove-AppxPackage -Package $PackageFullName + Write-Host "UWP 包已卸载" +} else { + Write-Host "未找到匹配的 UWP 包" +} \ No newline at end of file diff --git a/scripts/packChoco.py b/scripts/packChoco.py new file mode 100644 index 000000000..d0a8108d4 --- /dev/null +++ b/scripts/packChoco.py @@ -0,0 +1,159 @@ +import os +import requests +import shutil +import subprocess + +# python choco_pack.py --version 4.7.13.1403 --githubtoken YOUR_GITHUB_TOKEN --chocotoken YOUR_CHOCO_TOKEN + +def replace_string_in_file(file_path, target_string, replacement_string): + try: + # 鏍规嵁鏂囦欢鎵╁睍鍚嶉夋嫨缂栫爜 + if file_path.endswith('.ps1'): + encoding = 'gbk' # 瀵逛簬 .ps1 鏂囦欢锛屼娇鐢 GBK 缂栫爜 + else: + encoding = 'utf-8' # 瀵逛簬鍏朵粬鏂囦欢锛屼娇鐢 UTF-8 缂栫爜 + + # 璇诲彇鏂囦欢鍐呭 + with open(file_path, 'r', encoding=encoding) as file: + file_contents = file.read() + + # 鏇挎崲鏂囦欢鍐呭涓殑鐩爣瀛楃涓 + updated_contents = file_contents.replace(target_string, replacement_string) + + # 灏嗘洿鏂板悗鐨勫唴瀹瑰啓鍥炴枃浠 + with open(file_path, 'w', encoding=encoding) as file: + file.write(updated_contents) + + print(f"Successfully replaced '{target_string}' with '{replacement_string}' in {file_path}") + except FileNotFoundError: + print(f"The file at {file_path} was not found.") + except IOError as e: + print(f"An IOError occurred: {e.strerror}.") + except UnicodeDecodeError: + print(f"Failed to decode the file {file_path} with {encoding} encoding.") + except UnicodeEncodeError: + print(f"Failed to encode the file {file_path} with {encoding} encoding.") + +def download_github_release_asset(tag, github_token, arch, output_dir): + # 鑾峰彇鎵鏈 releases + url = "https://api.github.com/repos/ywmoyue/biliuwp-lite/releases" + headers = { + "Authorization": f"token {github_token}", + "Accept": "application/vnd.github.v3+json" + } + + response = requests.get(url, headers=headers) + if response.status_code != 200: + print(f"Failed to fetch releases. Status code: {response.status_code}") + return False + + releases = response.json() + + # 鏍规嵁 tag 鏌ユ壘瀵瑰簲鐨 release + release_item = None + for release in releases: + if release["tag_name"] == tag: + release_item = release + break + + if not release_item: + print(f"Release with tag {tag} not found.") + return False + + # 鏌ユ壘鍖归厤鐨 asset + zip_filename = f"BiliLite.Packages_{tag[1:]}_{arch}.zip" + asset_url = None + + for asset in release_item["assets"]: + if asset["name"] == zip_filename: + asset_url = asset["url"] + break + + if not asset_url: + print(f"Asset {zip_filename} not found in release {tag}.") + return False + + # 涓嬭浇 asset + headers["Accept"] = "application/octet-stream" + response = requests.get(asset_url, headers=headers, stream=True) + if response.status_code != 200: + print(f"Failed to download asset {zip_filename}. Status code: {response.status_code}") + return False + + os.makedirs(output_dir, exist_ok=True) + zip_path = os.path.join(output_dir, zip_filename) + with open(zip_path, 'wb') as f: + for chunk in response.iter_content(chunk_size=8192): + f.write(chunk) + + print(f"Downloaded {zip_filename} to {output_dir}") + return True + +def process_architecture(arch, version, github_token, chocotoken): + # 瀹氫箟璺緞 + template_dir = "scripts/chocolaty-templates" + pack_parent_dir = "C:/choco/pack" + pack_dir = f"{pack_parent_dir}/{arch}" + nuspec_file = f"{pack_dir}/BiliLite-uwp.nuspec" + install_script = f"{pack_dir}/tools/chocolateyInstall.ps1" + resources_dir = f"{pack_dir}/resources" + + # 澶嶅埗妯℃澘鏂囦欢澶瑰埌鐩爣鐩綍 + if not os.path.exists(template_dir): + print(f"Template directory {template_dir} not found.") + return + + os.makedirs(pack_parent_dir, exist_ok=True) + shutil.copytree(template_dir, pack_dir, dirs_exist_ok=True) + + # 鏇挎崲 nuspec 鏂囦欢涓殑 {version} 鍜 {arch} + replace_string_in_file(nuspec_file, "{version}", version) + replace_string_in_file(nuspec_file, "{arch}", arch) + + # 鏇挎崲 chocolateyInstall.ps1 鏂囦欢涓殑 {version} + replace_string_in_file(install_script, "{version}", version) + + # 鍒涘缓 resources 鏂囦欢澶 + os.makedirs(resources_dir, exist_ok=True) + + # 涓嬭浇 GitHub Release 鐨 zip 鍖 + tag = f"v{version}" + if not download_github_release_asset(tag, github_token, arch, resources_dir): + print(f"Skipping architecture {arch} due to missing asset.") + return + + # 鍦ㄧ洰鏍囩洰褰曚笅鎵ц choco pack 鍛戒护 + try: + subprocess.run(["choco", "pack"], cwd=pack_dir, check=True) + except subprocess.CalledProcessError as e: + print(f"Failed to pack for architecture {arch}. Error: {e}") + return + + # 鎷兼帴鍖呭悕 + package_name = f"BiliLite-uwp-{arch}.{version}-beta.nupkg" + package_path = os.path.join(pack_dir, package_name) + + # 鎵ц choco push 鍛戒护 + try: + subprocess.run(["choco", "push", package_path, "--source", "https://push.chocolatey.org/", "--api-key", chocotoken], check=True) + except subprocess.CalledProcessError as e: + print(f"Failed to push package for architecture {arch}. Error: {e}") + +def main(version, github_token, chocotoken): + architectures = ["x64", "x86", "ARM64"] + + for arch in architectures: + print(f"Processing architecture: {arch}") + process_architecture(arch, version, github_token, chocotoken) + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser(description="Process Chocolatey packages for different architectures.") + parser.add_argument("--version", required=True, help="The version of the package.") + parser.add_argument("--githubtoken", required=True, help="GitHub token for accessing the release assets.") + parser.add_argument("--chocotoken", required=True, help="Chocolatey API key for pushing the package.") + + args = parser.parse_args() + + main(args.version, args.githubtoken, args.chocotoken) \ No newline at end of file diff --git a/src/BiliLite.UWP/BiliLite.UWP.csproj b/src/BiliLite.UWP/BiliLite.UWP.csproj index 70cd125ed..0d9df496d 100644 --- a/src/BiliLite.UWP/BiliLite.UWP.csproj +++ b/src/BiliLite.UWP/BiliLite.UWP.csproj @@ -168,6 +168,9 @@ LiveSettingsControl.xaml + + PerformanceSettingsControl.xaml + PlaySettingsControl.xaml @@ -191,6 +194,12 @@ + + + + + + EditPlaySpeedMenuDialog.xaml @@ -213,6 +222,7 @@ + @@ -233,6 +243,7 @@ + @@ -324,6 +335,7 @@ MessagesPage.xaml + @@ -333,6 +345,7 @@ + @@ -1258,6 +1271,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/src/BiliLite.UWP/Controls/PlayerControl.xaml b/src/BiliLite.UWP/Controls/PlayerControl.xaml index e6acef6f6..d393f23aa 100644 --- a/src/BiliLite.UWP/Controls/PlayerControl.xaml +++ b/src/BiliLite.UWP/Controls/PlayerControl.xaml @@ -20,266 +20,6 @@ - @@ -800,9 +540,9 @@ --> - - - - + + - - - - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/BiliLite.UWP/Controls/Settings/PerformanceSettingsControl.xaml.cs b/src/BiliLite.UWP/Controls/Settings/PerformanceSettingsControl.xaml.cs new file mode 100644 index 000000000..b6fa3fb16 --- /dev/null +++ b/src/BiliLite.UWP/Controls/Settings/PerformanceSettingsControl.xaml.cs @@ -0,0 +1,81 @@ +锘縰sing BiliLite.Extensions; +using BiliLite.Models.Common; +using BiliLite.Services; +using Microsoft.Toolkit.Uwp.UI; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +//https://go.microsoft.com/fwlink/?LinkId=234236 涓婁粙缁嶄簡鈥滅敤鎴锋帶浠垛濋」妯℃澘 + +namespace BiliLite.Controls.Settings +{ + public sealed partial class PerformanceSettingsControl : UserControl + { + public PerformanceSettingsControl() + { + InitializeComponent(); + LoadPerformance(); + } + + private void LoadPerformance() + { + //鍔犺浇鍘熷浘 + swPictureQuality.IsOn = SettingService.GetValue(SettingConstants.UI.ORTGINAL_IMAGE, false); + swPictureQuality.Loaded += new RoutedEventHandler((sender, e) => + { + swPictureQuality.Toggled += new RoutedEventHandler((obj, args) => + { + SettingService.SetValue(SettingConstants.UI.ORTGINAL_IMAGE, swPictureQuality.IsOn); + SettingService.UI.LoadOriginalImage = null; + }); + }); + //缂撳瓨椤甸潰 + swHomeCache.IsOn = SettingService.GetValue(SettingConstants.UI.CACHE_HOME, true); + swHomeCache.Loaded += new RoutedEventHandler((sender, e) => + { + swHomeCache.Toggled += new RoutedEventHandler((obj, args) => + { + SettingService.SetValue(SettingConstants.UI.CACHE_HOME, swHomeCache.IsOn); + + }); + }); + + //鏂扮獥鍙f祻瑙堝浘鐗 + swPreviewImageNavigateToPage.IsOn = SettingService.GetValue(SettingConstants.UI.NEW_WINDOW_PREVIEW_IMAGE, false); + swPreviewImageNavigateToPage.Loaded += new RoutedEventHandler((sender, e) => + { + swPreviewImageNavigateToPage.Toggled += new RoutedEventHandler((obj, args) => + { + SettingService.SetValue(SettingConstants.UI.NEW_WINDOW_PREVIEW_IMAGE, swPreviewImageNavigateToPage.IsOn); + }); + }); + + //鍚姩搴旂敤鏃舵墦寮涓婃娴忚鐨勬爣绛鹃〉 + SwitchOpenLastPage.IsOn = SettingService.GetValue(SettingConstants.UI.ENABLE_OPEN_LAST_PAGE, SettingConstants.UI.DEFAULT_ENABLE_OPEN_LAST_PAGE); + SwitchOpenLastPage.Loaded += (sender, e) => + { + SwitchOpenLastPage.Toggled += (obj, args) => + { + SettingService.SetValue(SettingConstants.UI.ENABLE_OPEN_LAST_PAGE, SwitchOpenLastPage.IsOn); + }; + }; + + //娴忚鍣ㄦ墦寮鏃犳硶澶勭悊鐨勯摼鎺 + swOpenUrlWithBrowser.IsOn = SettingService.GetValue(SettingConstants.UI.OPEN_URL_BROWSER, false); + swOpenUrlWithBrowser.Loaded += new RoutedEventHandler((sender, e) => + { + swOpenUrlWithBrowser.Toggled += new RoutedEventHandler((obj, args) => + { + SettingService.SetValue(SettingConstants.UI.OPEN_URL_BROWSER, swOpenUrlWithBrowser.IsOn); + }); + }); + + } + + private async void btnCleanImageCache_Click(object sender, RoutedEventArgs e) + { + await ImageCache.Instance.ClearAsync(); + Notify.ShowMessageToast("宸叉竻闄ゅ浘鐗囩紦瀛"); + } + } +} diff --git a/src/BiliLite.UWP/Controls/Settings/PlaySettingsControl.xaml b/src/BiliLite.UWP/Controls/Settings/PlaySettingsControl.xaml index 40544ef23..9c8a0d99a 100644 --- a/src/BiliLite.UWP/Controls/Settings/PlaySettingsControl.xaml +++ b/src/BiliLite.UWP/Controls/Settings/PlaySettingsControl.xaml @@ -67,18 +67,39 @@ 浣跨敤FFmpeg鎾斁鏃剁‖瑙h棰 --> + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - @@ -176,19 +197,6 @@ - - - - - - - - - - - - @@ -221,14 +229,6 @@ - - - - - - - diff --git a/src/BiliLite.UWP/Controls/Settings/PlaySettingsControl.xaml.cs b/src/BiliLite.UWP/Controls/Settings/PlaySettingsControl.xaml.cs index fa4ccc714..64beed545 100644 --- a/src/BiliLite.UWP/Controls/Settings/PlaySettingsControl.xaml.cs +++ b/src/BiliLite.UWP/Controls/Settings/PlaySettingsControl.xaml.cs @@ -1,14 +1,14 @@ 锘縰sing BiliLite.Dialogs; -using Microsoft.Extensions.DependencyInjection; -using System; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; using BiliLite.Models.Common; +using BiliLite.Models.Common.Player; using BiliLite.Services; using BiliLite.ViewModels.Settings; +using Microsoft.Extensions.DependencyInjection; +using System; using System.Linq; using System.Threading.Tasks; -using BiliLite.Models.Common.Player; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; //https://go.microsoft.com/fwlink/?LinkId=234236 涓婁粙缁嶄簡鈥滅敤鎴锋帶浠垛濋」妯℃澘 @@ -55,6 +55,16 @@ private void LoadPlayer() { cbVideoSpeed.SelectionChanged += (obj, args) => { + if (cbVideoSpeed.SelectedIndex == -1) // 绌哄煎垵濮嬪寲 + { + speeds = m_playSpeedMenuService.MenuItems + .Select(x => x.Value) + .ToList(); + SettingService.SetValue(SettingConstants.Player.DEFAULT_VIDEO_SPEED, 0); + cbVideoSpeed.SelectedIndex = 0; + return; + } + SettingService.SetValue(SettingConstants.Player.DEFAULT_VIDEO_SPEED, speeds[cbVideoSpeed.SelectedIndex]); }; }; diff --git a/src/BiliLite.UWP/Controls/Settings/ShortcutKeySettingsControl.xaml b/src/BiliLite.UWP/Controls/Settings/ShortcutKeySettingsControl.xaml index b1f2598a6..a1c45fe42 100644 --- a/src/BiliLite.UWP/Controls/Settings/ShortcutKeySettingsControl.xaml +++ b/src/BiliLite.UWP/Controls/Settings/ShortcutKeySettingsControl.xaml @@ -2,47 +2,67 @@ x:Class="BiliLite.Controls.Settings.ShortcutKeySettingsControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:local="using:BiliLite.Controls.Settings" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:controls1="using:Microsoft.UI.Xaml.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:font="using:FontAwesome5" xmlns:functions="using:BiliLite.Models.Functions" - xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:local="using:BiliLite.Controls.Settings" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:settings="using:BiliLite.ViewModels.Settings" - xmlns:controls1="using:Microsoft.UI.Xaml.Controls" - mc:Ignorable="d" d:DesignHeight="300" - d:DesignWidth="400"> + d:DesignWidth="400" + mc:Ignorable="d"> + + + + + + + + + 鍏抽棴椤甸潰 + 鏂版爣绛鹃〉鎵撳紑瑙嗛浣嗕笉杩涘叆 + 鏃犳搷浣 + + + - - + 蹇嵎閿嚜瀹氫箟 - - + + - + - + + + + - + - + @@ -53,45 +73,39 @@ - 鍏朵粬璁剧疆 - - - - + 鍏朵粬璁剧疆 + + - - + + - - - + - + - - + + diff --git a/src/BiliLite.UWP/Controls/Settings/ShortcutKeySettingsControl.xaml.cs b/src/BiliLite.UWP/Controls/Settings/ShortcutKeySettingsControl.xaml.cs index f04c1a680..04957afa9 100644 --- a/src/BiliLite.UWP/Controls/Settings/ShortcutKeySettingsControl.xaml.cs +++ b/src/BiliLite.UWP/Controls/Settings/ShortcutKeySettingsControl.xaml.cs @@ -1,15 +1,16 @@ -锘縰sing System; -using System.Collections.ObjectModel; -using System.Linq; -using System.Threading.Tasks; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using AutoMapper; +锘縰sing AutoMapper; +using BiliLite.Models.Common; using BiliLite.Models.Functions; using BiliLite.Services; using BiliLite.ViewModels.Settings; using Microsoft.Extensions.DependencyInjection; using Microsoft.UI.Xaml.Controls; +using System; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading.Tasks; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; //https://go.microsoft.com/fwlink/?LinkId=234236 涓婁粙缁嶄簡鈥滅敤鎴锋帶浠垛濋」妯℃澘 @@ -34,7 +35,17 @@ public ShortcutKeySettingsControl() InitializeComponent(); m_shortcutKeyService.OnRecordKeyDown += ShortcutKeyService_OnRecordKeyDown; - m_shortcutKeyService.OnRecordStoped += ShortcutKeyService_OnRecordStoped; ; + m_shortcutKeyService.OnRecordStoped += ShortcutKeyService_OnRecordStoped; + + // 榧犳爣涓敭/渚ч敭琛屼负 + cbMouseMiddleAction.SelectedIndex = SettingService.GetValue(SettingConstants.UI.MOUSE_MIDDLE_ACTION, (int)MouseMiddleActions.Back); + cbMouseMiddleAction.Loaded += new RoutedEventHandler((sender, e) => + { + cbMouseMiddleAction.SelectionChanged += new SelectionChangedEventHandler((obj, args) => + { + SettingService.SetValue(SettingConstants.UI.MOUSE_MIDDLE_ACTION, cbMouseMiddleAction.SelectedIndex); + }); + }); } private async void ShortcutKeyService_OnRecordStoped(object sender, System.EventArgs e) diff --git a/src/BiliLite.UWP/Controls/Settings/UISettingsControl.xaml b/src/BiliLite.UWP/Controls/Settings/UISettingsControl.xaml index 8434590e0..53a632942 100644 --- a/src/BiliLite.UWP/Controls/Settings/UISettingsControl.xaml +++ b/src/BiliLite.UWP/Controls/Settings/UISettingsControl.xaml @@ -43,31 +43,6 @@ - - - - - - - - - - - - - - - - - - - - - - - @@ -251,14 +226,6 @@ - - - - - - - @@ -285,28 +252,6 @@ - - - - - - - - - - - - - - 鍏抽棴椤甸潰 - 鏂版爣绛鹃〉鎵撳紑瑙嗛浣嗕笉杩涘叆 - 鏃犳搷浣 - - - - @@ -322,14 +267,6 @@ - - - - - - - diff --git a/src/BiliLite.UWP/Controls/Settings/UISettingsControl.xaml.cs b/src/BiliLite.UWP/Controls/Settings/UISettingsControl.xaml.cs index 7f039465b..3565d20bb 100644 --- a/src/BiliLite.UWP/Controls/Settings/UISettingsControl.xaml.cs +++ b/src/BiliLite.UWP/Controls/Settings/UISettingsControl.xaml.cs @@ -1,17 +1,16 @@ -锘縰sing System.Collections.ObjectModel; -using System.Linq; -using Windows.Foundation; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using BiliLite.Extensions; +锘縰sing BiliLite.Extensions; +using BiliLite.Extensions.Notifications; using BiliLite.Models.Common; using BiliLite.Models.Common.Home; using BiliLite.Services; using Microsoft.Extensions.DependencyInjection; using Microsoft.UI.Xaml.Controls; -using Microsoft.Toolkit.Uwp.UI; -using BiliLite.Extensions.Notifications; +using System.Collections.ObjectModel; +using System.Linq; using Windows.ApplicationModel.Background; +using Windows.Foundation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; //https://go.microsoft.com/fwlink/?LinkId=234236 涓婁粙缁嶄簡鈥滅敤鎴锋帶浠垛濋」妯℃澘 @@ -24,7 +23,7 @@ public sealed partial class UISettingsControl : UserControl public UISettingsControl() { m_themeService = App.ServiceProvider.GetRequiredService(); - InitializeComponent(); + InitializeComponent(); LoadUI(); } private void LoadUI() @@ -61,26 +60,6 @@ private void LoadUI() }); }); - //鍔犺浇鍘熷浘 - swPictureQuality.IsOn = SettingService.GetValue(SettingConstants.UI.ORTGINAL_IMAGE, false); - swPictureQuality.Loaded += new RoutedEventHandler((sender, e) => - { - swPictureQuality.Toggled += new RoutedEventHandler((obj, args) => - { - SettingService.SetValue(SettingConstants.UI.ORTGINAL_IMAGE, swPictureQuality.IsOn); - SettingService.UI.LoadOriginalImage = null; - }); - }); - //缂撳瓨椤甸潰 - swHomeCache.IsOn = SettingService.GetValue(SettingConstants.UI.CACHE_HOME, true); - swHomeCache.Loaded += new RoutedEventHandler((sender, e) => - { - swHomeCache.Toggled += new RoutedEventHandler((obj, args) => - { - SettingService.SetValue(SettingConstants.UI.CACHE_HOME, swHomeCache.IsOn); - - }); - }); // 鏄剧ず鎺ㄨ崘椤垫í骞 SwitchDisplayRecommendBanner.IsOn = SettingService.GetValue(SettingConstants.UI.DISPLAY_RECOMMEND_BANNER, SettingConstants.UI.DEFAULT_DISPLAY_RECOMMEND_BANNER); @@ -174,36 +153,6 @@ private void LoadUI() }); }); - //鏂扮獥鍙f祻瑙堝浘鐗 - swPreviewImageNavigateToPage.IsOn = SettingService.GetValue(SettingConstants.UI.NEW_WINDOW_PREVIEW_IMAGE, false); - swPreviewImageNavigateToPage.Loaded += new RoutedEventHandler((sender, e) => - { - swPreviewImageNavigateToPage.Toggled += new RoutedEventHandler((obj, args) => - { - SettingService.SetValue(SettingConstants.UI.NEW_WINDOW_PREVIEW_IMAGE, swPreviewImageNavigateToPage.IsOn); - }); - }); - - //鍚姩搴旂敤鏃舵墦寮涓婃娴忚鐨勬爣绛鹃〉 - SwitchOpenLastPage.IsOn = SettingService.GetValue(SettingConstants.UI.ENABLE_OPEN_LAST_PAGE, SettingConstants.UI.DEFAULT_ENABLE_OPEN_LAST_PAGE); - SwitchOpenLastPage.Loaded += (sender, e) => - { - SwitchOpenLastPage.Toggled += (obj, args) => - { - SettingService.SetValue(SettingConstants.UI.ENABLE_OPEN_LAST_PAGE, SwitchOpenLastPage.IsOn); - }; - }; - - // 榧犳爣涓敭/渚ч敭琛屼负 - cbMouseMiddleAction.SelectedIndex = SettingService.GetValue(SettingConstants.UI.MOUSE_MIDDLE_ACTION, (int)MouseMiddleActions.Back); - cbMouseMiddleAction.Loaded += new RoutedEventHandler((sender, e) => - { - cbMouseMiddleAction.SelectionChanged += new SelectionChangedEventHandler((obj, args) => - { - SettingService.SetValue(SettingConstants.UI.MOUSE_MIDDLE_ACTION, cbMouseMiddleAction.SelectedIndex); - }); - }); - // 蹇熸敹钘 SwitchQuickDoFav.IsOn = SettingService.GetValue(SettingConstants.UI.QUICK_DO_FAV, SettingConstants.UI.DEFAULT_QUICK_DO_FAV); SwitchQuickDoFav.Loaded += (sender, e) => @@ -284,16 +233,6 @@ private void LoadUI() }); }); - //娴忚鍣ㄦ墦寮鏃犳硶澶勭悊鐨勯摼鎺 - swOpenUrlWithBrowser.IsOn = SettingService.GetValue(SettingConstants.UI.OPEN_URL_BROWSER, false); - swOpenUrlWithBrowser.Loaded += new RoutedEventHandler((sender, e) => - { - swOpenUrlWithBrowser.Toggled += new RoutedEventHandler((obj, args) => - { - SettingService.SetValue(SettingConstants.UI.OPEN_URL_BROWSER, swOpenUrlWithBrowser.IsOn); - }); - }); - //鍥哄畾鏍囩瀹藉害 SwitchTabItemFixedWidth.IsOn = SettingService.GetValue(SettingConstants.UI.ENABLE_TAB_ITEM_FIXED_WIDTH, @@ -402,12 +341,6 @@ private void gridHomeNavItem_ItemClick(object sender, ItemClickEventArgs e) Notify.ShowMessageToast("鏇存敼鎴愬姛,閲嶅惎鐢熸晥"); } - private async void btnCleanImageCache_Click(object sender, RoutedEventArgs e) - { - await ImageCache.Instance.ClearAsync(); - Notify.ShowMessageToast("宸叉竻闄ゅ浘鐗囩紦瀛"); - } - private void menuRemoveHomeItem_Click(object sender, RoutedEventArgs e) { var item = (sender as MenuFlyoutItem).DataContext as HomeNavItem; diff --git a/src/BiliLite.UWP/Converters/LiveLineSliderTooltipConverter.cs b/src/BiliLite.UWP/Converters/LiveLineSliderTooltipConverter.cs new file mode 100644 index 000000000..70150a491 --- /dev/null +++ b/src/BiliLite.UWP/Converters/LiveLineSliderTooltipConverter.cs @@ -0,0 +1,27 @@ +锘縰sing System; +using System.Collections.Generic; +using Windows.UI.Xaml.Data; +using BiliLite.Models.Common.Player; + +namespace BiliLite.Converters; + +public class LiveLineSliderTooltipConverter : IValueConverter +{ + public List Lines { get; set; } + + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is double sliderValue) + { + return sliderValue >= 0 && sliderValue < Lines.Count + ? Lines[(int)sliderValue].Name + : sliderValue.ToString(); + } + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + return value; + } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/Converters/LiveQualitySliderTooltipConverter.cs b/src/BiliLite.UWP/Converters/LiveQualitySliderTooltipConverter.cs new file mode 100644 index 000000000..057084576 --- /dev/null +++ b/src/BiliLite.UWP/Converters/LiveQualitySliderTooltipConverter.cs @@ -0,0 +1,27 @@ +锘縰sing System; +using System.Collections.Generic; +using Windows.UI.Xaml.Data; +using BiliLite.Models.Common.Live; + +namespace BiliLite.Converters; + +public class LiveQualitySliderTooltipConverter : IValueConverter +{ + public List Qualites { get; set; } + + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is double sliderValue) + { + return sliderValue >= 0 && sliderValue < Qualites.Count + ? Qualites[(int)sliderValue].Desc + : sliderValue.ToString(); + } + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + return value; + } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/Converters/PlaySpeedSliderTooltipConverter.cs b/src/BiliLite.UWP/Converters/PlaySpeedSliderTooltipConverter.cs new file mode 100644 index 000000000..512c96386 --- /dev/null +++ b/src/BiliLite.UWP/Converters/PlaySpeedSliderTooltipConverter.cs @@ -0,0 +1,31 @@ +锘縰sing System; +using BiliLite.Services; +using Windows.UI.Xaml.Data; + +namespace BiliLite.Converters; + +public class PlaySpeedSliderTooltipConverter : IValueConverter +{ + private readonly PlaySpeedMenuService m_playSpeedMenuService; + + public PlaySpeedSliderTooltipConverter(PlaySpeedMenuService playSpeedMenuService) + { + m_playSpeedMenuService = playSpeedMenuService; + } + + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is double sliderValue) + { + return sliderValue >= 0 && sliderValue < m_playSpeedMenuService.MenuItems.Count + ? m_playSpeedMenuService.MenuItems[(int)sliderValue].Content + : sliderValue.ToString(); + } + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + return value; + } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/Converters/QualitySliderTooltipConverter.cs b/src/BiliLite.UWP/Converters/QualitySliderTooltipConverter.cs new file mode 100644 index 000000000..9410f8cb3 --- /dev/null +++ b/src/BiliLite.UWP/Converters/QualitySliderTooltipConverter.cs @@ -0,0 +1,27 @@ +锘縰sing System; +using BiliLite.Models.Common.Video.PlayUrlInfos; +using System.Collections.Generic; +using Windows.UI.Xaml.Data; + +namespace BiliLite.Converters; + +public class QualitySliderTooltipConverter : IValueConverter +{ + public List Qualites { get; set; } + + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is double sliderValue) + { + return sliderValue >= 0 && sliderValue < Qualites.Count + ? Qualites[(int)sliderValue].QualityName + : sliderValue.ToString(); + } + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + return value; + } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/Converters/SoundQualitySliderTooltipConverter.cs b/src/BiliLite.UWP/Converters/SoundQualitySliderTooltipConverter.cs new file mode 100644 index 000000000..43d3d74a8 --- /dev/null +++ b/src/BiliLite.UWP/Converters/SoundQualitySliderTooltipConverter.cs @@ -0,0 +1,27 @@ +锘縰sing BiliLite.Models.Common.Video.PlayUrlInfos; +using System; +using System.Collections.Generic; +using Windows.UI.Xaml.Data; + +namespace BiliLite.Converters; + +public class SoundQualitySliderTooltipConverter : IValueConverter +{ + public List AudioQualites { get; set; } + + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is double sliderValue) + { + return sliderValue >= 0 && sliderValue < AudioQualites.Count + ? AudioQualites[(int)sliderValue].QualityName + : sliderValue.ToString(); + } + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + return value; + } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/Converters/TimeSpanStrFormatConverter.cs b/src/BiliLite.UWP/Converters/TimeSpanStrFormatConverter.cs new file mode 100644 index 000000000..cc118cf56 --- /dev/null +++ b/src/BiliLite.UWP/Converters/TimeSpanStrFormatConverter.cs @@ -0,0 +1,41 @@ +锘縰sing System; + +namespace BiliLite.Converters; + +public static class TimeSpanStrFormatConverter +{ + public static string Convert(string timeSpanStr) + { + // 瑙f瀽杈撳叆瀛楃涓 + var parts = timeSpanStr.Split(':'); + + // 鏍规嵁鍒嗛儴鐨勬暟閲忚В鏋愭椂闂 + int hours = 0, minutes = 0, seconds = 0; + + switch (parts.Length) + { + case 1: // 鍙湁绉掓暟 + seconds = int.Parse(parts[0]); + break; + case 2: // 鍒嗛挓鍜岀鏁 + minutes = int.Parse(parts[0]); + seconds = int.Parse(parts[1]); + break; + case 3: // 灏忔椂銆佸垎閽熷拰绉掓暟 + hours = int.Parse(parts[0]); + minutes = int.Parse(parts[1]); + seconds = int.Parse(parts[2]); + break; + default: + throw new ArgumentException("杈撳叆瀛楃涓叉牸寮忎笉姝g‘锛屽簲涓 '绉'銆'鍒嗛挓:绉' 鎴 '灏忔椂:鍒嗛挓:绉'銆"); + } + + // 鍒涘缓 TimeSpan 瀵硅薄 + var timeSpan = new TimeSpan(hours, minutes, seconds); + + // 鏍规嵁灏忔椂鏄惁涓0鏉ュ姩鎬佽皟鏁存牸寮忓瓧绗︿覆 + var format = timeSpan.Hours == 0 ? @"mm\:ss" : @"hh\:mm\:ss"; + // 鏍规嵁鎸囧畾鏍煎紡鏍煎紡鍖 TimeSpan + return timeSpan.ToString(format); + } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/Dialogs/EditPlaySpeedMenuDialog.xaml b/src/BiliLite.UWP/Dialogs/EditPlaySpeedMenuDialog.xaml index bbeb2c6cc..21485cf28 100644 --- a/src/BiliLite.UWP/Dialogs/EditPlaySpeedMenuDialog.xaml +++ b/src/BiliLite.UWP/Dialogs/EditPlaySpeedMenuDialog.xaml @@ -2,41 +2,70 @@ x:Class="BiliLite.Dialogs.EditPlaySpeedMenuDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:local="using:BiliLite.Dialogs" + xmlns:controls="using:Microsoft.UI.Xaml.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:BiliLite.Dialogs" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:player="using:BiliLite.Models.Common.Player" - xmlns:controls="using:Microsoft.UI.Xaml.Controls" - mc:Ignorable="d" - Title="缂栬緫鎾斁閫熷害鑿滃崟" - PrimaryButtonText="纭畾" + Title="鑷畾涔夋挱鏀惧嶉" CloseButtonText="鍙栨秷" - PrimaryButtonClick="ContentDialog_PrimaryButtonClick"> + PrimaryButtonClick="ContentDialog_PrimaryButtonClick" + PrimaryButtonText="纭畾" + mc:Ignorable="d"> - - + + - - - - - - + + + + - + - - + + - - + + - + diff --git a/src/BiliLite.UWP/Dialogs/EditPlaySpeedMenuDialog.xaml.cs b/src/BiliLite.UWP/Dialogs/EditPlaySpeedMenuDialog.xaml.cs index c093c7787..23f68aa9d 100644 --- a/src/BiliLite.UWP/Dialogs/EditPlaySpeedMenuDialog.xaml.cs +++ b/src/BiliLite.UWP/Dialogs/EditPlaySpeedMenuDialog.xaml.cs @@ -1,10 +1,12 @@ -锘縰sing System.Collections.ObjectModel; -using System.Linq; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Input; +锘縰sing BiliLite.Extensions; using BiliLite.Models.Common.Player; using BiliLite.Services; using BiliLite.ViewModels.Settings; +using System.Collections.ObjectModel; +using System.Linq; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Input; // https://go.microsoft.com/fwlink/?LinkId=234238 涓婁粙缁嶄簡鈥滃唴瀹瑰璇濇鈥濋」妯℃澘 @@ -12,6 +14,8 @@ namespace BiliLite.Dialogs { public sealed partial class EditPlaySpeedMenuDialog : ContentDialog { + public double DialogHeight => Window.Current.Bounds.Height * 0.7; + private readonly EditPlaySpeedMenuViewModel m_viewModel; private readonly PlaySpeedMenuService m_playSpeedMenuService; @@ -38,9 +42,23 @@ private void BtnRemovePlaySpeed_OnTapped(object sender, TappedRoutedEventArgs e) private void BtnAddPlaySpeed_OnTapped(object sender, TappedRoutedEventArgs e) { + foreach (PlaySpeedMenuItem item in m_viewModel.PlaySpeedMenuItems) + { + if (item.Value == m_viewModel.AddPlaySpeedValue) + { + Notify.ShowMessageToast("宸查噸澶嶆坊鍔"); + return; + } + } + if (m_viewModel.AddPlaySpeedValue == 0) + { + Notify.ShowMessageToast("闈炴硶鍙傛暟"); + return; + } + m_viewModel.PlaySpeedMenuItems.Add(new PlaySpeedMenuItem(m_viewModel.AddPlaySpeedValue)); - m_viewModel.PlaySpeedMenuItems = - new ObservableCollection(m_viewModel.PlaySpeedMenuItems.OrderByDescending(x => x.Value)); + m_viewModel.PlaySpeedMenuItems = + new ObservableCollection(m_viewModel.PlaySpeedMenuItems.OrderBy(x => x.Value)); } } } diff --git a/src/BiliLite.UWP/Models/Common/Live/LiveRoomInfoOldModel.cs b/src/BiliLite.UWP/Models/Common/Live/LiveRoomInfoOldModel.cs new file mode 100644 index 000000000..0d8991a8d --- /dev/null +++ b/src/BiliLite.UWP/Models/Common/Live/LiveRoomInfoOldModel.cs @@ -0,0 +1,74 @@ +锘縰sing Newtonsoft.Json; + +namespace BiliLite.Models.Common.Live; + +public class LiveRoomInfoOldModel +{ + /// + /// 鐩存挱闂寸姸鎬 + /// 0锛氭棤鎴块棿锛1锛氭湁鎴块棿 + /// + [JsonProperty("roomStatus")] + public int RoomStatus { get; set; } + + /// + /// 杞挱鐘舵 + /// 0锛氭湭杞挱锛1锛氳疆鎾 + /// + [JsonProperty("roundStatus")] + public int RoundStatus { get; set; } + + /// + /// 鐩存挱鐘舵 + /// 0锛氭湭寮鎾紝1锛氱洿鎾腑 + /// + [JsonProperty("live_status")] + public int LiveStatus { get; set; } + + /// + /// 鐩存挱闂寸綉椤礥RL + /// + [JsonProperty("url")] + public string Url { get; set; } + + /// + /// 鐩存挱闂存爣棰 + /// + [JsonProperty("title")] + public string Title { get; set; } + + /// + /// 鐩存挱闂村皝闈RL + /// + [JsonProperty("cover")] + public string Cover { get; set; } + + /// + /// 鐩存挱闂翠汉姘 + /// 鍊间负涓婃鐩存挱鏃跺埛鏂 + /// + [JsonProperty("online")] + public int Online { get; set; } + + /// + /// 鐩存挱闂碔D锛堢煭鍙凤級 + /// + [JsonProperty("roomid")] + public int RoomId { get; set; } + + /// + /// 骞挎挱绫诲瀷 + /// + [JsonProperty("broadcast_type")] + public int BroadcastType { get; set; } + + /// + /// 鍦ㄧ嚎闅愯棌鐘舵 + /// + [JsonProperty("online_hidden")] + public int OnlineHidden { get; set; } + + public string UserName { get; set; } + + public string UserId { get; set; } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/Models/Common/Player/PlaySpeedMenu.cs b/src/BiliLite.UWP/Models/Common/Player/PlaySpeedMenu.cs index bad6e73f7..104134337 100644 --- a/src/BiliLite.UWP/Models/Common/Player/PlaySpeedMenu.cs +++ b/src/BiliLite.UWP/Models/Common/Player/PlaySpeedMenu.cs @@ -1,14 +1,8 @@ -锘縰sing System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BiliLite.Models.Common.Player +锘縩amespace BiliLite.Models.Common.Player { public class PlaySpeedMenuItem { - public PlaySpeedMenuItem(){} + public PlaySpeedMenuItem() { } public PlaySpeedMenuItem(double value) { @@ -18,5 +12,7 @@ public PlaySpeedMenuItem(double value) public string Content => Value + "x"; public double Value { get; set; } + + public bool IsDeletable => Value != 1; } } diff --git a/src/BiliLite.UWP/Models/Common/Search/SearchVideoItem.cs b/src/BiliLite.UWP/Models/Common/Search/SearchVideoItem.cs index 366f8431b..103c86937 100644 --- a/src/BiliLite.UWP/Models/Common/Search/SearchVideoItem.cs +++ b/src/BiliLite.UWP/Models/Common/Search/SearchVideoItem.cs @@ -1,4 +1,7 @@ -锘縩amespace BiliLite.Models.Common.Search +锘縰sing BiliLite.Converters; +using System; + +namespace BiliLite.Models.Common.Search { public class SearchVideoItem { @@ -24,6 +27,22 @@ public string title public int review { get; set; } public int favorites { get; set; } public string duration { get; set; } + + public string DurationShow + { + get + { + try + { + return TimeSpanStrFormatConverter.Convert(duration); + } + catch (Exception ex) + { + return duration; + } + } + } + private string _pic; public string pic { diff --git a/src/BiliLite.UWP/Models/Common/SettingConstants.cs b/src/BiliLite.UWP/Models/Common/SettingConstants.cs index b539aa4f8..cfb2d1cc2 100644 --- a/src/BiliLite.UWP/Models/Common/SettingConstants.cs +++ b/src/BiliLite.UWP/Models/Common/SettingConstants.cs @@ -258,6 +258,9 @@ public class UI /// [SettingDefaultValue] public const bool DEFAULT_ENABLE_OPEN_LAST_PAGE = false; + + [SettingKey] + public const string LOCAL_ATTENTION_USER = "LocalAttentionUser"; } public class Account diff --git a/src/BiliLite.UWP/Models/Common/User/LocalAttentionUser.cs b/src/BiliLite.UWP/Models/Common/User/LocalAttentionUser.cs new file mode 100644 index 000000000..bc53ef8b1 --- /dev/null +++ b/src/BiliLite.UWP/Models/Common/User/LocalAttentionUser.cs @@ -0,0 +1,8 @@ +锘縩amespace BiliLite.Models.Common.User; + +public class LocalAttentionUser +{ + public string Name { get; set; } + + public string Id { get; set; } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs b/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs index 6e57918e0..2a54a7ac0 100644 --- a/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs +++ b/src/BiliLite.UWP/Models/Requests/Api/Live/LiveRoomAPI.cs @@ -447,5 +447,21 @@ public ApiModel GetLiveRoomEmoticon(int room_id) api.parameter += ApiHelper.GetSign(api.parameter, AppKey); return api; } + + /// + /// 鑾峰彇鐢ㄦ埛瀵瑰簲鐨勭洿鎾棿鐘舵 + /// + /// + /// + public ApiModel GetRoomInfoOld(string userId) + { + var api = new ApiModel() + { + method = HttpMethods.Get, + baseUrl = $"https://api.live.bilibili.com/room/v1/Room/getRoomInfoOld", + parameter = $"mid={userId}", + }; + return api; + } } } diff --git a/src/BiliLite.UWP/Modules/Live/LiveCenter/LiveAttentionVM.cs b/src/BiliLite.UWP/Modules/Live/LiveCenter/LiveAttentionVM.cs index aba177a42..34931a018 100644 --- a/src/BiliLite.UWP/Modules/Live/LiveCenter/LiveAttentionVM.cs +++ b/src/BiliLite.UWP/Modules/Live/LiveCenter/LiveAttentionVM.cs @@ -7,17 +7,25 @@ using System.Windows.Input; using Windows.UI.Xaml.Media.Imaging; using BiliLite.Extensions; +using BiliLite.Services; +using BiliLite.Models.Common.Live; +using BiliLite.Services.Biz; +using Microsoft.Extensions.DependencyInjection; namespace BiliLite.Modules.Live.LiveCenter { public class LiveAttentionVM : IModules { readonly LiveCenterAPI liveCenterAPI; + private static readonly ILogger _logger = GlobalLogger.FromCurrentType(); public LiveAttentionVM() { liveCenterAPI = new LiveCenterAPI(); RefreshCommand = new RelayCommand(Refresh); } + + public ObservableCollection LocalFollows { get; set; } + private ObservableCollection _Follow; public ObservableCollection Follow @@ -70,6 +78,15 @@ public async Task GetFollows() Loading = false; } } + + public async Task GetLocalFollows() + { + var localAttentionUserService = App.ServiceProvider.GetRequiredService(); + var roomList = await localAttentionUserService.GetLiveRooms(); + if (roomList == null) return; + LocalFollows = new ObservableCollection(roomList); + } + public async void Refresh() { if (Loading) @@ -78,6 +95,7 @@ public async void Refresh() } Follow = null; await GetFollows(); + await GetLocalFollows(); } } public class LiveFollowAnchorModel diff --git a/src/BiliLite.UWP/Modules/Player/Playurl/BiliPlayUrlRequest.cs b/src/BiliLite.UWP/Modules/Player/Playurl/BiliPlayUrlRequest.cs index af285ba0e..26ff77ce4 100644 --- a/src/BiliLite.UWP/Modules/Player/Playurl/BiliPlayUrlRequest.cs +++ b/src/BiliLite.UWP/Modules/Player/Playurl/BiliPlayUrlRequest.cs @@ -1,21 +1,21 @@ -锘縰sing Newtonsoft.Json.Linq; +锘縰sing Bilibili.App.Playurl.V1; +using BiliLite.Extensions; +using BiliLite.gRPC.Api; +using BiliLite.Models.Common; +using BiliLite.Models.Common.Video; +using BiliLite.Models.Common.Video.PlayUrlInfos; +using BiliLite.Models.Requests.Api; +using BiliLite.Services; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; -using System.Net.Http; -using Bilibili.App.Playurl.V1; -using BiliLite.Extensions; -using BiliLite.Models.Requests.Api; -using BiliLite.Services; -using BiliLite.Models.Common; -using BiliLite.Models.Common.Video; -using BiliLite.Models.Common.Video.PlayUrlInfos; using PlayURL = BiliLite.gRPC.Api.PlayURL; -using BiliLite.gRPC.Api; namespace BiliLite.Modules.Player.Playurl { @@ -124,6 +124,7 @@ private void ParseBiliPlayUrlInfoSupportFormats(BiliPlayUrlQualitesInfo info, JO HasPlayUrl = false, }); } + info.Qualites = [.. info.Qualites.OrderBy(x => x.QualityID)]; } private async Task ParseBiliPlayUrlInfoAudioDash(BiliPlayUrlQualitesInfo info, JObject playUrlInfoResult, @@ -178,6 +179,9 @@ private async Task ParseBiliPlayUrlInfoAudioDash(BiliPlayUrlQualit Audio = audio.ToBiliDashItem(), }); } + + info.AudioQualites = [.. info.AudioQualites.OrderBy(x => x.QualityID)]; + // 澶勭悊鏃犳崯闊宠川 if (flacAudio is { Display: true, Audio: { } }) { diff --git a/src/BiliLite.UWP/NoTabMainPage.xaml b/src/BiliLite.UWP/NoTabMainPage.xaml index f55a5d615..db857140e 100644 --- a/src/BiliLite.UWP/NoTabMainPage.xaml +++ b/src/BiliLite.UWP/NoTabMainPage.xaml @@ -45,6 +45,8 @@ Height="40" Margin="0,-4" Click="btnBack_Click" + Background="Transparent" + BorderThickness="0" Visibility="Visible"> @@ -56,6 +57,71 @@ + + + 鏈湴鍏虫敞鐨勭洿鎾 + + + + + + + + + + + + + + + + + + + + + + 鍙栨秷鏈湴鍏虫敞 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 鍏虫敞鐨勭洿鎾 diff --git a/src/BiliLite.UWP/Pages/Home/LivePage.xaml.cs b/src/BiliLite.UWP/Pages/Home/LivePage.xaml.cs index 423a9750d..cd6097861 100644 --- a/src/BiliLite.UWP/Pages/Home/LivePage.xaml.cs +++ b/src/BiliLite.UWP/Pages/Home/LivePage.xaml.cs @@ -11,7 +11,10 @@ using Windows.UI.Xaml.Navigation; using BiliLite.Models.Common.Home; using BiliLite.ViewModels.Home; +using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.DependencyInjection; +using BiliLite.Services.Biz; +using BiliLite.Models.Common.Live; // https://go.microsoft.com/fwlink/?LinkId=234238 涓婁粙缁嶄簡鈥滅┖鐧介〉鈥濋」妯℃澘 @@ -52,6 +55,11 @@ private async Task LoadData() { m_viewModel.ShowFollows = true; await m_viewModel.LiveAttentionVm.GetFollows(); + await m_viewModel.LiveAttentionVm.GetLocalFollows(); + if (m_viewModel.LiveAttentionVm.LocalFollows != null && m_viewModel.LiveAttentionVm.LocalFollows.Any()) + { + m_viewModel.ShowLocalFollows = true; + } } } @@ -81,14 +89,26 @@ private async void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls. private void FollowLive_ItemClick(object sender, ItemClickEventArgs e) { - var data = e.ClickedItem as LiveFollowAnchorModel; - MessageCenter.NavigateToPage(this, new NavigationInfo() + if (e.ClickedItem is LiveFollowAnchorModel data) { - icon = Symbol.Video, - page = typeof(LiveDetailPage), - title = data.uname + "鐨勭洿鎾棿", - parameters = data.roomid - }); + MessageCenter.NavigateToPage(this, new NavigationInfo() + { + icon = Symbol.Video, + page = typeof(LiveDetailPage), + title = data.uname + "鐨勭洿鎾棿", + parameters = data.roomid + }); + } + else if(e.ClickedItem is LiveRoomInfoOldModel info) + { + MessageCenter.NavigateToPage(this, new NavigationInfo() + { + icon = Symbol.Video, + page = typeof(LiveDetailPage), + title = info.UserName + "鐨勭洿鎾棿", + parameters = info.RoomId + }); + } } private void LiveItems_ItemClick(object sender, ItemClickEventArgs e) @@ -186,5 +206,17 @@ private async void btnOpenLiveCenter_Click(object sender, RoutedEventArgs e) }); } + + private void CancelLocalAttention_OnClick(object sender, RoutedEventArgs e) + { + if (sender is not FrameworkElement { DataContext: LiveRoomInfoOldModel roomInfo }) + { + return; + } + + var localAttentionUserService = App.ServiceProvider.GetRequiredService(); + localAttentionUserService.CancelAttention(roomInfo.UserId); + m_viewModel.LiveAttentionVm.LocalFollows.Remove(roomInfo); + } } } diff --git a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml index 5ca4fa14f..d64edd73e 100644 --- a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml +++ b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml @@ -24,267 +24,6 @@ - @@ -728,36 +467,51 @@ - - - - - - - + + + diff --git a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs index 714ed45bc..9da8e1d5a 100644 --- a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs +++ b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs @@ -1,4 +1,5 @@ 锘縰sing BiliLite.Controls; +using BiliLite.Converters; using BiliLite.Extensions; using BiliLite.Models.Common; using BiliLite.Models.Common.Live; @@ -33,6 +34,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media.Imaging; using Windows.UI.Xaml.Navigation; @@ -56,9 +58,12 @@ public sealed partial class LiveDetailPage : BasePage, IPlayPage, IUpdatePivotLa private readonly bool m_useNsDanmaku = true; private readonly IDanmakuController m_danmakuController; private readonly LiveSettingsControlViewModel m_liveSettingsControlViewModel; + private readonly LiveQualitySliderTooltipConverter m_liveQualitySliderTooltipConverter; + private readonly LiveLineSliderTooltipConverter m_liveLineSliderTooltipConverter; DisplayRequest dispRequest; LiveRoomViewModel m_liveRoomViewModel; + List basePlayUrls; DispatcherTimer timer_focus; DispatcherTimer controlTimer; DispatcherTimer chatScrollTimer; @@ -129,6 +134,9 @@ public LiveDetailPage() this.Loaded += LiveDetailPage_Loaded; this.Unloaded += LiveDetailPage_Unloaded; + m_liveQualitySliderTooltipConverter = new LiveQualitySliderTooltipConverter(); + m_liveLineSliderTooltipConverter = new LiveLineSliderTooltipConverter(); + m_useNsDanmaku = (DanmakuEngineType)SettingService.GetValue(SettingConstants.Live.DANMAKU_ENGINE, (int)SettingConstants.Live.DEFAULT_DANMAKU_ENGINE) == DanmakuEngineType.NSDanmaku; if (m_useNsDanmaku) @@ -432,33 +440,88 @@ private void SetMediaInfo() #endregion + #region Slider private void LiveRoomViewModelChangedPlayUrl(object sender, EventArgs e) { changePlayUrlFlag = true; + InitSliderQuality(); + InitSliderLine(); + changePlayUrlFlag = false; + } + + private void InitSliderQuality() + { + if (m_liveRoomViewModel.Qualites.IndexOf(m_liveRoomViewModel.CurrentQn) == -1) + { + return; // 绌哄兼鏌 + } + + MinQuality.Text = m_liveRoomViewModel.Qualites[0].Desc; + MaxQuality.Text = m_liveRoomViewModel.Qualites[m_liveRoomViewModel.Qualites.Count - 1].Desc; + + BottomBtnQuality.IsEnabled = m_liveRoomViewModel.Qualites.Count > 1; + BottomBtnQuality.Content = m_liveRoomViewModel.CurrentQn.Desc; + SliderQuality.Maximum = m_liveRoomViewModel.Qualites.Count - 1; + SliderQuality.Value = m_liveRoomViewModel.Qualites.IndexOf(m_liveRoomViewModel.CurrentQn); + m_liveQualitySliderTooltipConverter.Qualites = m_liveRoomViewModel.Qualites; + SliderQuality.ThumbToolTipValueConverter = m_liveQualitySliderTooltipConverter; + } + private async void SliderQuality_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) + { + if (changePlayUrlFlag) + { + return; + } + + var item = m_liveRoomViewModel.Qualites[(int)SliderQuality.Value]; + SettingService.SetValue(SettingConstants.Live.DEFAULT_QUALITY, item.Qn); + await m_liveRoomViewModel.GetPlayUrls(m_liveRoomViewModel.RoomID, item.Qn); + BottomBtnQuality.Content = item.Desc; + } + + private void InitSliderLine() + { m_realPlayInfo.PlayUrls.HlsUrls = m_liveRoomViewModel.HlsUrls; m_realPlayInfo.PlayUrls.FlvUrls = m_liveRoomViewModel.FlvUrls; - var urls = m_liveRoomViewModel.HlsUrls ?? m_liveRoomViewModel.FlvUrls; - BottomCBLine.ItemsSource = urls; + basePlayUrls = m_liveRoomViewModel.HlsUrls ?? m_liveRoomViewModel.FlvUrls; + + BottomBtnLine.IsEnabled = basePlayUrls.Count > 1; + + MinLine.Text = basePlayUrls[0].Name; + MaxLine.Text = basePlayUrls[basePlayUrls.Count - 1].Name; + SliderLine.Maximum = basePlayUrls.Count - 1; + m_liveLineSliderTooltipConverter.Lines = basePlayUrls; + SliderLine.ThumbToolTipValueConverter = m_liveLineSliderTooltipConverter; var flag = false; - for (var i = 0; i < urls.Count; i++) + for (var i = 0; i < basePlayUrls.Count; i++) { - var domain = new Uri(urls[i].Url).Host; + var domain = new Uri(basePlayUrls[i].Url).Host; if (domain.Contains(m_viewModel.LivePlayUrlSource) && !flag) { - BottomCBLine.SelectedIndex = i; + BottomBtnLine.Content = basePlayUrls[i].Name; + SliderLine.Value = i + 1; // 寮哄埗瑙﹀彂 SliderLine_ValueChanged 浜嬩欢 + SliderLine.Value = i; + flag = true; } } if (!flag) { - BottomCBLine.SelectedIndex = 0; + BottomBtnLine.Content = basePlayUrls[0].Name; + SliderLine.Value = 0 + 1; + SliderLine.Value = 0; } + } - BottomCBQuality.SelectedItem = m_liveRoomViewModel.CurrentQn; - changePlayUrlFlag = false; + private async void SliderLine_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) + { + BottomBtnLine.Content = basePlayUrls[(int)SliderLine.Value].Name; + + m_playerConfig.SelectedRouteLine = (int)SliderLine.Value; + await LoadPlayer(); } private async Task StopPlay() @@ -474,6 +537,7 @@ private async Task StopPlay() SetFullScreen(false); MiniWidnows(false); } + #endregion string roomid; @@ -701,29 +765,6 @@ private async Task LoadPlayer() } } - private async void BottomCBQuality_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - if (BottomCBQuality.SelectedItem == null || changePlayUrlFlag) - { - return; - } - var item = BottomCBQuality.SelectedItem as LiveRoomWebUrlQualityDescriptionItemModel; - SettingService.SetValue(SettingConstants.Live.DEFAULT_QUALITY, item.Qn); - await m_liveRoomViewModel.GetPlayUrls(m_liveRoomViewModel.RoomID, item.Qn); - } - - private async void BottomCBLine_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - if (BottomCBLine.SelectedIndex == -1) - { - return; - } - - m_playerConfig.SelectedRouteLine = BottomCBLine.SelectedIndex; - - await LoadPlayer(); - } - private async void BottomBtnPause_Click(object sender, RoutedEventArgs e) { await m_playerController.PauseState.Pause(); diff --git a/src/BiliLite.UWP/Pages/SearchPage.xaml b/src/BiliLite.UWP/Pages/SearchPage.xaml index 3567d82a2..23054e0c7 100644 --- a/src/BiliLite.UWP/Pages/SearchPage.xaml +++ b/src/BiliLite.UWP/Pages/SearchPage.xaml @@ -17,7 +17,7 @@ SizeChanged="SearchPage_OnSizeChanged" mc:Ignorable="d"> - + @@ -96,7 +96,7 @@ + Text="{x:Bind DurationShow}" /> @@ -228,7 +228,7 @@ Margin="0,0,0,4" FontSize="14" Foreground="Gray"> - 寮鎾椂闂达細 + 寮鎾椂闂达細 @@ -684,7 +684,7 @@ Margin="0,4" FontSize="14" Foreground="Gray"> - 鏃堕棿: + 鏃堕棿: diff --git a/src/BiliLite.UWP/Pages/SettingPage.xaml b/src/BiliLite.UWP/Pages/SettingPage.xaml index 5d969be4a..24da08a75 100644 --- a/src/BiliLite.UWP/Pages/SettingPage.xaml +++ b/src/BiliLite.UWP/Pages/SettingPage.xaml @@ -30,7 +30,6 @@ - @@ -42,6 +41,16 @@ + + + 鎬ц兘 + + + + + + + 浠g悊 diff --git a/src/BiliLite.UWP/Pages/UserInfoPage.xaml b/src/BiliLite.UWP/Pages/UserInfoPage.xaml index ce265afb7..5df53fc21 100644 --- a/src/BiliLite.UWP/Pages/UserInfoPage.xaml +++ b/src/BiliLite.UWP/Pages/UserInfoPage.xaml @@ -61,7 +61,11 @@ - + + + 璁剧疆鏈湴鍏虫敞 + 鍙栨秷鏈湴鍏虫敞 + @@ -596,7 +600,8 @@ + Visibility="{x:Bind Path=m_viewModel.IsFollowed,Mode=OneWay,Converter={StaticResource display}}" + ContextFlyout="{StaticResource AttentionContextManu}"> @@ -608,7 +613,8 @@ + Visibility="{x:Bind Path=m_viewModel.IsFollowed,Mode=OneWay}" + ContextFlyout="{StaticResource AttentionContextManu}"> diff --git a/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs b/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs index 3228a12c4..24fd6c2eb 100644 --- a/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs +++ b/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs @@ -499,5 +499,17 @@ public void UpdatePivotLayout() pivot.UseLayoutRounding = !pivot.UseLayoutRounding; pivot.UseLayoutRounding = !pivot.UseLayoutRounding; } + + private void BtnSetLocalAttention_OnClick(object sender, RoutedEventArgs e) + { + var localAttentionUserService = App.ServiceProvider.GetRequiredService(); + localAttentionUserService.AttentionUp(m_viewModel.Mid, m_viewModel.UserSpaceInfo.Name); + } + + private void BtnCancelLocalAttention_OnClick(object sender, RoutedEventArgs e) + { + var localAttentionUserService = App.ServiceProvider.GetRequiredService(); + localAttentionUserService.CancelAttention(m_viewModel.Mid); + } } } diff --git a/src/BiliLite.UWP/Pages/WebPage.xaml b/src/BiliLite.UWP/Pages/WebPage.xaml index 51c1c7abe..db386ce59 100644 --- a/src/BiliLite.UWP/Pages/WebPage.xaml +++ b/src/BiliLite.UWP/Pages/WebPage.xaml @@ -23,12 +23,14 @@ - + - + diff --git a/src/BiliLite.UWP/Pages/WebPage.xaml.cs b/src/BiliLite.UWP/Pages/WebPage.xaml.cs index c8a174e48..2813c14fd 100644 --- a/src/BiliLite.UWP/Pages/WebPage.xaml.cs +++ b/src/BiliLite.UWP/Pages/WebPage.xaml.cs @@ -1,17 +1,19 @@ 锘縰sing BiliLite.Controls; using BiliLite.Extensions; +using BiliLite.Models.Common; using BiliLite.Services; +using Microsoft.Extensions.DependencyInjection; using Microsoft.UI.Xaml.Controls; +using Microsoft.Web.WebView2.Core; using System; using System.Threading.Tasks; +using Windows.ApplicationModel.DataTransfer; +using Windows.Storage; using Windows.UI.Popups; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; -using BiliLite.Models.Common; -using Microsoft.Web.WebView2.Core; -using Microsoft.Extensions.DependencyInjection; -using Windows.Storage; +using BiliLite.ViewModels.Common; // https://go.microsoft.com/fwlink/?LinkId=234238 涓婁粙缁嶄簡鈥滅┖鐧介〉鈥濋」妯℃澘 @@ -24,9 +26,11 @@ public sealed partial class WebPage : BasePage { private readonly CookieService m_cookieService; private static readonly ILogger _logger = GlobalLogger.FromCurrentType(); + private readonly WebPageViewModel m_viewModel; public WebPage() { + m_viewModel = App.ServiceProvider.GetRequiredService(); m_cookieService = App.ServiceProvider.GetRequiredService(); this.InitializeComponent(); Title = "缃戦〉娴忚"; @@ -143,7 +147,17 @@ private void btnBack_Click(object sender, RoutedEventArgs e) private void btnShare_Click(object sender, RoutedEventArgs e) { - webView.Source.ToString().SetClipboard(); + DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView(); + dataTransferManager.DataRequested -= DataTransferManager_DataRequested; + dataTransferManager.DataRequested += DataTransferManager_DataRequested; + DataTransferManager.ShowShareUI(); + } + + private void DataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs e) + { + DataPackage dataPackage = e.Request.Data; + dataPackage.Properties.Title = "鍏变韩閾炬帴"; + dataPackage.SetWebLink(webView.Source); } private async void btnOpenBrowser_Click(object sender, RoutedEventArgs e) @@ -232,6 +246,9 @@ private async void WebView_OnNavigationCompleted(WebView2 sender, CoreWebView2Na { if (webView != null) webView.Visibility = Visibility.Visible; } + + m_viewModel.IsEnableGoBack = webView.CanGoBack; + m_viewModel.IsEnableGoForward = webView.CanGoForward; } } } diff --git a/src/BiliLite.UWP/Services/Biz/LocalAttentionUserService.cs b/src/BiliLite.UWP/Services/Biz/LocalAttentionUserService.cs new file mode 100644 index 000000000..bbdd6fd16 --- /dev/null +++ b/src/BiliLite.UWP/Services/Biz/LocalAttentionUserService.cs @@ -0,0 +1,106 @@ +锘縰sing BiliLite.Models.Attributes; +using BiliLite.Models.Common.User; +using BiliLite.Models.Common; +using BiliLite.ViewModels.User.SendDynamic; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using BiliLite.Extensions; +using BiliLite.Models.Common.Live; +using BiliLite.Models.Requests.Api.Live; + +namespace BiliLite.Services.Biz; + +[RegisterTransientService] +public class LocalAttentionUserService : BaseBizService +{ + private static readonly ILogger _logger = GlobalLogger.FromCurrentType(); + + public void AttentionUp(string id, string name) + { + var user = new LocalAttentionUser() + { + Id = id, + Name = name, + }; + var localAttentionUsers = SettingService.GetValue>(SettingConstants.UI.LOCAL_ATTENTION_USER, null); + if (localAttentionUsers == null) + { + localAttentionUsers = new List(); + } + + if (localAttentionUsers.Count > 5) + { + Notify.ShowMessageToast("鏈湴鍏虫敞浜烘暟瓒呭嚭闄愬埗"); + return; + } + + if (localAttentionUsers.Any(x => x.Id == user.Id)) + { + Notify.ShowMessageToast("宸茬粡鍏虫敞浜"); + return; + } + localAttentionUsers.Add(user); + SettingService.SetValue>(SettingConstants.UI.LOCAL_ATTENTION_USER, localAttentionUsers); + Notify.ShowMessageToast("宸插叧娉"); + } + + public void CancelAttention(string id) + { + var localAttentionUsers = SettingService.GetValue>(SettingConstants.UI.LOCAL_ATTENTION_USER, null); + if (localAttentionUsers == null) + { + return; + } + + var user = localAttentionUsers.FirstOrDefault(x => x.Id == id); + if (user == null) + { + return; + } + + localAttentionUsers.Remove(user); + SettingService.SetValue>(SettingConstants.UI.LOCAL_ATTENTION_USER, localAttentionUsers); + + Notify.ShowMessageToast("宸插彇娑堝叧娉"); + } + + public async Task> GetLiveRooms() + { + + var localAttentionUsers = SettingService.GetValue>(SettingConstants.UI.LOCAL_ATTENTION_USER, null); + if (localAttentionUsers == null || !localAttentionUsers.Any()) + { + return null; + } + + var roomList = new List(); + + foreach (var user in localAttentionUsers) + { + var api = new LiveRoomAPI().GetRoomInfoOld(user.Id); + var results = await api.Request(); + if (!results.status) + { + _logger.Warn(results.message); + continue; + } + + var data = await results.GetData(); + if (!data.success) + { + _logger.Warn(data.message); + continue; + } + + if (data.data.RoomStatus == 0) continue; + + data.data.UserName = user.Name; + data.data.UserId = user.Id; + + roomList.Add(data.data); + } + + return roomList; + } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/Services/PlaySpeedMenuService.cs b/src/BiliLite.UWP/Services/PlaySpeedMenuService.cs index 24e1433bb..68c2ff6c0 100644 --- a/src/BiliLite.UWP/Services/PlaySpeedMenuService.cs +++ b/src/BiliLite.UWP/Services/PlaySpeedMenuService.cs @@ -1,17 +1,19 @@ -锘縰sing BiliLite.Models.Common.Player; -using System.Collections.Generic; -using System.Linq; +锘縰sing System.Collections.Generic; using BiliLite.Models.Common; +using BiliLite.Models.Common.Player; +using System.Collections.ObjectModel; +using System.Linq; namespace BiliLite.Services { public class PlaySpeedMenuService { + public List MenuItems { get; private set; } + public PlaySpeedMenuService() { MenuItems = SettingService.GetValue(SettingConstants.Player.PLAY_SPEED_MENU, GetDefaultPlaySpeedMenu()); } - public List MenuItems { get; private set; } public void SetMenuItems(List menuItems) { @@ -19,17 +21,24 @@ public void SetMenuItems(List menuItems) SettingService.SetValue(SettingConstants.Player.PLAY_SPEED_MENU, menuItems); } + public int SpeedIndexOf(double speed) + { + return MenuItems.FindIndex(x => x.Value == speed); + } + private List GetDefaultPlaySpeedMenu() { - return new List() + return [.. new ObservableCollection() { - new PlaySpeedMenuItem(0.5), - new PlaySpeedMenuItem(0.75), - new PlaySpeedMenuItem(1.0), - new PlaySpeedMenuItem(1.25), - new PlaySpeedMenuItem(1.5), - new PlaySpeedMenuItem(2.0), - }.OrderByDescending(x => x.Value).ToList(); + new(0.25), + new(0.5), + new(0.75), + new(1.0), + new(1.25), + new(1.5), + new(1.75), + new(2.0), + }]; } } } diff --git a/src/BiliLite.UWP/ViewModels/Common/BaseViewModel.cs b/src/BiliLite.UWP/ViewModels/Common/BaseViewModel.cs index 22bccb6e7..026939eee 100644 --- a/src/BiliLite.UWP/ViewModels/Common/BaseViewModel.cs +++ b/src/BiliLite.UWP/ViewModels/Common/BaseViewModel.cs @@ -1,12 +1,12 @@ -锘縰sing System; +锘縰sing BiliLite.Extensions; +using BiliLite.Models; +using BiliLite.Models.Common; +using BiliLite.Services; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Runtime.CompilerServices; -using BiliLite.Extensions; -using BiliLite.Models; -using BiliLite.Models.Common; -using BiliLite.Services; namespace BiliLite.ViewModels.Common { @@ -15,19 +15,9 @@ public class BaseViewModel : INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; private static readonly ILogger _logger = GlobalLogger.FromCurrentType(); - protected void OnPropertyChanged(string propertyName) + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { - if (PropertyChanged != null) - { - try - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - catch (Exception ex) - { - - } - } + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected void OnLocalPropertyChanged(string propertyName) diff --git a/src/BiliLite.UWP/ViewModels/Common/WebPageViewModel.cs b/src/BiliLite.UWP/ViewModels/Common/WebPageViewModel.cs new file mode 100644 index 000000000..9b1d5a211 --- /dev/null +++ b/src/BiliLite.UWP/ViewModels/Common/WebPageViewModel.cs @@ -0,0 +1,11 @@ +锘縰sing BiliLite.Models.Attributes; + +namespace BiliLite.ViewModels.Common; + +[RegisterTransientViewModel] +public class WebPageViewModel : BaseViewModel +{ + public bool IsEnableGoBack { get; set; } + + public bool IsEnableGoForward { get; set; } +} \ No newline at end of file diff --git a/src/BiliLite.UWP/ViewModels/Home/LiveViewModel.cs b/src/BiliLite.UWP/ViewModels/Home/LiveViewModel.cs index 5f5b5523b..c322a8b99 100644 --- a/src/BiliLite.UWP/ViewModels/Home/LiveViewModel.cs +++ b/src/BiliLite.UWP/ViewModels/Home/LiveViewModel.cs @@ -42,6 +42,8 @@ public LiveViewModel() public bool ShowFollows { get; set; } + public bool ShowLocalFollows { get; set; } + public bool Loading { get; set; } public bool LoadingFollow { get; set; } = true; diff --git a/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs b/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs index 9b541b84a..3398f57a1 100644 --- a/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs +++ b/src/BiliLite.UWP/ViewModels/Live/LiveRoomViewModel.cs @@ -1,12 +1,4 @@ -锘縰sing System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Timers; -using System.Windows.Input; -using BiliLite.Extensions; +锘縰sing BiliLite.Extensions; using BiliLite.Models; using BiliLite.Models.Common; using BiliLite.Models.Common.Live; @@ -21,6 +13,14 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PropertyChanged; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Timers; +using System.Windows.Input; using DateTime = System.DateTime; namespace BiliLite.ViewModels.Live @@ -161,7 +161,7 @@ public LiveRoomViewModel() public bool ShowBag { get; set; } public List Ranks { get; set; } - + public LiveRoomRankViewModel SelectRank { get; set; } [DoNotNotify] @@ -228,7 +228,7 @@ public LiveRoomViewModel() public string ManualPlayUrl { get; set; } = ""; [DoNotNotify] - public Dictionary LotteryDanmu = new Dictionary { { "AnchorLottery", "" }, {"RedPocketLottery", ""} }; + public Dictionary LotteryDanmu = new Dictionary { { "AnchorLottery", "" }, { "RedPocketLottery", "" } }; /// /// 鏈夌殑鐗规畩鐩存挱闂存病鏈変竴浜涘ū涔愬唴瀹. 渚嬪澶鏂伴椈鐩存挱闂. @@ -269,7 +269,7 @@ private LiveMessageHandleActionsMap InitLiveMessageHandleActionMap() actionMap.AddNewDanmu += (_, e) => { AddNewDanmu?.Invoke(this, e); - }; + }; actionMap.AnchorLotteryEnd += (_, e) => { AnchorLotteryEnd?.Invoke(this, e); @@ -364,7 +364,7 @@ private async void Timer_SuperChats_Elapsed(object sender, ElapsedEventArgs e) { await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { - for(int i = 0; i < SuperChats.Count; i++) + for (int i = 0; i < SuperChats.Count; i++) { if (SuperChats.ElementAt(i).Time <= 0) SuperChats.RemoveAt(i); else SuperChats.ElementAt(i).Time -= 1; @@ -480,15 +480,16 @@ private List GetSpecialPlayUrls(LiveRoomPlayUrlModel liveRoomPl var acceptQnList = codec.AcceptQn; Qualites ??= liveRoomPlayUrlModel.PlayUrlInfo.PlayUrl.GQnDesc.Where(item => acceptQnList.Contains(item.Qn)).ToList(); + Qualites = [.. Qualites.OrderBy(x => x.Qn)]; CurrentQn = liveRoomPlayUrlModel.PlayUrlInfo.PlayUrl.GQnDesc.FirstOrDefault(x => x.Qn == codec.CurrentQn); var urlList = codec.UrlInfo.Select(urlInfo => new BasePlayUrlInfo - { Url = urlInfo.Host + codec.BaseUrl + urlInfo.Extra, Name = urlInfo.Name }).ToList(); + { Url = urlInfo.Host + codec.BaseUrl + urlInfo.Extra, Name = urlInfo.Name }).ToList(); var regex = new Regex(@"live_\d+_\d+\.flv"); foreach (var item in urlList) { - if (regex.IsMatch(item.Url)) + if (regex.IsMatch(item.Url)) { SetManualPlayUrl?.Invoke(this, item.Url); break; @@ -1347,7 +1348,7 @@ public async Task JoinRedPocketLottery() return false; } // 鍙備笌绾㈠寘鎶藉浼氳嚜鍔ㄥ彂閫佸脊骞, 涓嶇敤鑷繁鍙 - return await JoinRedPocketLotteryRequest(SettingService.Account.UserID, + return await JoinRedPocketLotteryRequest(SettingService.Account.UserID, RoomID, AnchorUid, LotteryViewModel.RedPocketLotteryInfo.LotteryId.ToInt32()); diff --git a/src/BiliLite.UWP/ViewModels/Settings/EditPlaySpeedMenuViewModel.cs b/src/BiliLite.UWP/ViewModels/Settings/EditPlaySpeedMenuViewModel.cs index c4a6a835c..abb1a6725 100644 --- a/src/BiliLite.UWP/ViewModels/Settings/EditPlaySpeedMenuViewModel.cs +++ b/src/BiliLite.UWP/ViewModels/Settings/EditPlaySpeedMenuViewModel.cs @@ -1,6 +1,6 @@ -锘縰sing System.Collections.ObjectModel; -using BiliLite.Models.Common.Player; +锘縰sing BiliLite.Models.Common.Player; using BiliLite.ViewModels.Common; +using System.Collections.ObjectModel; namespace BiliLite.ViewModels.Settings { @@ -8,6 +8,6 @@ public class EditPlaySpeedMenuViewModel : BaseViewModel { public ObservableCollection PlaySpeedMenuItems { get; set; } - public double AddPlaySpeedValue { get; set; } = 1; + public double AddPlaySpeedValue { get; set; } = 3; } } diff --git a/src/BiliLite.UWP/ViewModels/Settings/ShortcutFunctionViewModel.cs b/src/BiliLite.UWP/ViewModels/Settings/ShortcutFunctionViewModel.cs index 416db53b1..1382c9282 100644 --- a/src/BiliLite.UWP/ViewModels/Settings/ShortcutFunctionViewModel.cs +++ b/src/BiliLite.UWP/ViewModels/Settings/ShortcutFunctionViewModel.cs @@ -1,8 +1,8 @@ -锘縰sing System.Collections.ObjectModel; -using System.Linq; +锘縰sing BiliLite.Models.Functions; using BiliLite.ViewModels.Common; -using BiliLite.Models.Functions; using PropertyChanged; +using System.Collections.ObjectModel; +using System.Linq; namespace BiliLite.ViewModels.Settings { @@ -18,7 +18,7 @@ public class ShortcutFunctionViewModel : BaseViewModel public bool IsPressAction { get; set; } - public string Description => IsPressAction ? "鎸変綇琛屼负" : "鐐瑰嚮琛屼负"; + public string Description => IsPressAction ? "闀挎寜鎵ц" : "鐐瑰嚮鎵ц"; public bool Enable { get; set; } diff --git a/src/BiliLite.WebApi/Controllers/AnimeController.cs b/src/BiliLite.WebApi/Controllers/AnimeController.cs index d71a3d24f..82c251009 100644 --- a/src/BiliLite.WebApi/Controllers/AnimeController.cs +++ b/src/BiliLite.WebApi/Controllers/AnimeController.cs @@ -135,8 +135,8 @@ public async Task Timeline(int type = 1) var getCacheSuccess = m_memoryCache.TryGetValue(cacheKey, out var value); if (getCacheSuccess == true && value != null) { - var cacheResult = value as BangumiTimeline; - return new JsonResult(new ApiModel() + var cacheResult = value as List; + return new JsonResult(new ApiModel>() { code = 0, message = "",