├── .editorconfig ├── .gitattributes ├── .gitignore ├── LICENSE ├── NicoNicoViewer2ndGen.sln ├── Packaging ├── Images │ ├── LargeTile.scale-100.png │ ├── LargeTile.scale-125.png │ ├── LargeTile.scale-150.png │ ├── LargeTile.scale-200.png │ ├── LargeTile.scale-400.png │ ├── LockScreenLogo.scale-200.png │ ├── SmallTile.scale-100.png │ ├── SmallTile.scale-125.png │ ├── SmallTile.scale-150.png │ ├── SmallTile.scale-200.png │ ├── SmallTile.scale-400.png │ ├── SplashScreen.scale-100.png │ ├── SplashScreen.scale-125.png │ ├── SplashScreen.scale-150.png │ ├── SplashScreen.scale-200.png │ ├── SplashScreen.scale-400.png │ ├── Square150x150Logo.scale-100.png │ ├── Square150x150Logo.scale-125.png │ ├── Square150x150Logo.scale-150.png │ ├── Square150x150Logo.scale-200.png │ ├── Square150x150Logo.scale-400.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-16.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-24.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-256.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-32.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-48.png │ ├── Square44x44Logo.altform-unplated_targetsize-16.png │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ ├── Square44x44Logo.altform-unplated_targetsize-32.png │ ├── Square44x44Logo.altform-unplated_targetsize-48.png │ ├── Square44x44Logo.scale-100.png │ ├── Square44x44Logo.scale-125.png │ ├── Square44x44Logo.scale-150.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.scale-400.png │ ├── Square44x44Logo.targetsize-16.png │ ├── Square44x44Logo.targetsize-24.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── Square44x44Logo.targetsize-256.png │ ├── Square44x44Logo.targetsize-32.png │ ├── Square44x44Logo.targetsize-48.png │ ├── StoreLogo.backup.png │ ├── StoreLogo.scale-100.png │ ├── StoreLogo.scale-125.png │ ├── StoreLogo.scale-150.png │ ├── StoreLogo.scale-200.png │ ├── StoreLogo.scale-400.png │ ├── Wide310x150Logo.scale-100.png │ ├── Wide310x150Logo.scale-125.png │ ├── Wide310x150Logo.scale-150.png │ ├── Wide310x150Logo.scale-200.png │ ├── Wide310x150Logo.scale-400.png │ └── production.png ├── Package.appxmanifest └── Packaging.wapproj ├── README.md ├── SRNicoNico.Tests ├── SRNicoNico.Tests.csproj └── Tests │ ├── Constants.cs.example │ ├── HistoryServiceUnitTest.cs │ ├── LiveServiceUnitTest.cs │ ├── MylistServiceUnitTest.cs │ ├── NicoRepoServiceUnitTest.cs │ ├── RankingServiceUnitTest.cs │ ├── SearchServiceUnitTest.cs │ ├── SeriesServiceUnitTest.cs │ ├── TestingAccountService.cs │ ├── TestingHistoryService.cs │ ├── TestingNicoNicoViewer.cs │ ├── UserServiceUnitTest.cs │ └── VideoServiceUnitTest.cs └── SRNicoNico ├── App.xaml ├── App.xaml.cs ├── AssemblyInfo.cs ├── Entities ├── ABRepeatPosition.cs ├── LocalHistory.cs ├── MutedAccount.cs ├── RankingVisibility.cs └── SearchHistory.cs ├── Html ├── commentlayer.ts ├── player.html ├── style.scss ├── videolayer.ts ├── webpack.config.ts └── webview.d.ts ├── Icons ├── Category.png └── production.ico ├── Migrations ├── 20210228172733_InitialDbContextMigration.Designer.cs ├── 20210228172733_InitialDbContextMigration.cs ├── 20210605161628_AddABRepeatPositionTable.Designer.cs ├── 20210605161628_AddABRepeatPositionTable.cs ├── 20211127145716_AddRankingVisibilityMigration.Designer.cs ├── 20211127145716_AddRankingVisibilityMigration.cs ├── 20211209175716_AddMutedAccountMigration.Designer.cs ├── 20211209175716_AddMutedAccountMigration.cs ├── 20211215130038_AddSearchHistoryMigration.Designer.cs ├── 20211215130038_AddSearchHistoryMigration.cs └── ViewerDbContextModelSnapshot.cs ├── Models ├── CommentParser.cs ├── GetRequestQueryBuilder.cs ├── INicoNicoViewer.cs ├── ISettings.cs ├── JsonObjectExtension.cs ├── NicoNicoViewer.cs ├── NicoNicoWrapper │ ├── History │ │ └── HistoryVideoItem.cs │ ├── Live │ │ └── OngoingLive.cs │ ├── Mylist │ │ ├── Mylist.cs │ │ ├── MylistItem.cs │ │ └── MylistVideoItem.cs │ ├── NicoRepo │ │ ├── NicoRepoEntry.cs │ │ └── NicoRepoList.cs │ ├── Ranking │ │ ├── CustomRankingDetails.cs │ │ ├── HotTopics.cs │ │ ├── PopularTags.cs │ │ ├── RankingDetails.cs │ │ ├── RankingSetting.cs │ │ └── RankingSettings.cs │ ├── Search │ │ ├── SearchGenreFacet.cs │ │ └── SearchResult.cs │ ├── Series │ │ ├── Series.cs │ │ └── SeriesList.cs │ ├── User │ │ ├── ChannelEntry.cs │ │ ├── CommunityEntry.cs │ │ ├── CommunityList.cs │ │ ├── MylistEntry.cs │ │ ├── TagEntry.cs │ │ ├── UserDetails.cs │ │ ├── UserEntry.cs │ │ ├── UserFollowList.cs │ │ ├── UserList.cs │ │ └── VideoList.cs │ ├── Video │ │ ├── DmcSession.cs │ │ ├── VideoComment.cs │ │ ├── VideoStoryBoard.cs │ │ └── WatchApiData.cs │ ├── VideoItem.cs │ └── WatchLater │ │ └── WatchLaterList.cs ├── Settings.cs ├── StatusErrorException.cs └── ViewerDbContext.cs ├── SRNicoNico.csproj ├── Services ├── IAccountService.cs ├── IChannelCommunityService.cs ├── IHistoryService.cs ├── ILiveService.cs ├── IMylistService.cs ├── INicoRepoService.cs ├── IRankingService.cs ├── ISearchService.cs ├── ISeriesService.cs ├── ISessionService.cs ├── IUserService.cs ├── IVideoService.cs ├── NicoNicoHistoryService.cs ├── NicoNicoLiveService.cs ├── NicoNicoMylistService.cs ├── NicoNicoNicoRepoService.cs ├── NicoNicoRankingService.cs ├── NicoNicoSearchService.cs ├── NicoNicoSeriesService.cs ├── NicoNicoSessionService.cs ├── NicoNicoUserService.cs ├── NicoNicoVideoService.cs └── NicoNicoViewerAccountService.cs ├── Themes ├── Accent │ ├── Blue.xaml │ ├── Orange.xaml │ └── Purple.xaml ├── Generic.DisabledScrollViewerFlowDocumentScrollViewer.xaml ├── Generic.HtmlRenderer.xaml ├── Generic.PageSpinner.xaml ├── Generic.RoundButton.xaml ├── Generic.SeekBar.xaml ├── Generic.ToggleSwitch.xaml ├── Generic.VolumeBar.xaml ├── Generic.xaml ├── Theme.Button.xaml ├── Theme.ComboBox.xaml ├── Theme.ContextMenu.xaml ├── Theme.GridSplitter.xaml ├── Theme.ListBox.xaml ├── Theme.MenuItem.xaml ├── Theme.ProgressRing.xaml ├── Theme.ScrollViewer.xaml ├── Theme.Slider.xaml ├── Theme.TabView.xaml ├── Theme.TextBox.xaml ├── Theme.ToolTip.xaml ├── Theme.xaml └── Theme │ └── Dark.xaml ├── ViewModels ├── Follow │ ├── ChannelFollowViewModel.cs │ ├── CommunityFollowViewModel.cs │ ├── FollowViewModel.cs │ ├── MylistFollowViewModel.cs │ ├── TagFollowViewModel.cs │ └── UserFollowViewModel.cs ├── History │ ├── AccountHistoryViewModel.cs │ ├── HistoryViewModel.cs │ └── LocalHistoryViewModel.cs ├── Live │ └── LiveNotifyViewModel.cs ├── MainContentViewModel.cs ├── MainWindowViewModel.cs ├── Misc │ ├── CrashReportViewModel.cs │ └── StartViewModel.cs ├── Mylist │ ├── CreateMylistViewModel.cs │ ├── MylistListViewModel.cs │ ├── MylistViewModel.cs │ └── PublicMylistViewModel.cs ├── NicoRepo │ ├── NicoRepoListAllViewModel.cs │ ├── NicoRepoListChannelViewModel.cs │ ├── NicoRepoListCommunityViewModel.cs │ ├── NicoRepoListMylistViewModel.cs │ ├── NicoRepoListSelfViewModel.cs │ ├── NicoRepoListUserViewModel.cs │ ├── NicoRepoListViewModel.cs │ └── NicoRepoViewModel.cs ├── Other │ ├── OpenSourceViewModel.cs │ ├── OtherViewModel.cs │ ├── OverviewViewModel.cs │ └── PrivacyPolicyViewModel.cs ├── PageSpinnerViewModel.cs ├── Ranking │ ├── CustomRankingEditorViewModel.cs │ ├── CustomRankingItemViewModel.cs │ ├── HotTopicRankingItemViewModel.cs │ ├── RankingItemViewModel.cs │ └── RankingViewModel.cs ├── Search │ ├── SearchResultViewModel.cs │ └── SearchViewModel.cs ├── Series │ └── SeriesViewModel.cs ├── Settings │ ├── SettingsCommentViewModel.cs │ ├── SettingsGeneralViewModel.cs │ ├── SettingsLiveViewModel.cs │ ├── SettingsMutedAccountViewModel.cs │ ├── SettingsRankingViewModel.cs │ ├── SettingsVideoViewModel.cs │ └── SettingsViewModel.cs ├── SignInViewModel.cs ├── TabItemViewModel.cs ├── User │ ├── UserFolloweeViewModel.cs │ ├── UserFollowerViewModel.cs │ ├── UserMylistViewModel.cs │ ├── UserNicoRepoViewModel.cs │ ├── UserSeriesViewModel.cs │ ├── UserVideoViewModel.cs │ └── UserViewModel.cs ├── Video │ ├── VideoCommentViewModel.cs │ ├── VideoHtml5Handler.cs │ ├── VideoTabViewModel.cs │ └── VideoViewModel.cs ├── WatchLater │ └── WatchLaterViewModel.cs └── WebView │ ├── WebViewContentViewModel.cs │ └── WebViewViewModel.cs ├── Views ├── Actions │ ├── AddWatchLaterAction.cs │ ├── CopyToClipBoardAction.cs │ ├── MouseMiddleClickTrigger.cs │ ├── MuteAccountAction.cs │ ├── NicoNicoOpenAction.cs │ └── WebViewOpenAction.cs ├── Behaviors │ ├── CommentAutoScrollBehavior.cs │ ├── ListBoxInfiniteScrollBehavior.cs │ ├── ParagraphHtmlRenderingBehavior.cs │ ├── SearchRadioButtonBehavior.cs │ ├── TextBlockHtmlRenderingBehavior.cs │ ├── TextBlockHyperlinkBehavior.cs │ ├── TextBoxEnterKeyBehavior.cs │ ├── TextBoxNumericOnlyBehavior.cs │ ├── TextBoxPageSpinnerEnterKeyBehavior.cs │ ├── WebViewNavigationBehavior.cs │ └── WindowInputEventBehavior.cs ├── Contents │ ├── Follow │ │ ├── ChannelEntryView.xaml │ │ ├── ChannelEntryView.xaml.cs │ │ ├── ChannelFollow.xaml │ │ ├── ChannelFollow.xaml.cs │ │ ├── CommunityEntryView.xaml │ │ ├── CommunityEntryView.xaml.cs │ │ ├── CommunityFollow.xaml │ │ ├── CommunityFollow.xaml.cs │ │ ├── Follow.xaml │ │ ├── Follow.xaml.cs │ │ ├── MylistEntryView.xaml │ │ ├── MylistEntryView.xaml.cs │ │ ├── MylistFollow.xaml │ │ ├── MylistFollow.xaml.cs │ │ ├── TagEntryView.xaml │ │ ├── TagEntryView.xaml.cs │ │ ├── TagFollow.xaml │ │ ├── TagFollow.xaml.cs │ │ ├── UserEntryView.xaml │ │ ├── UserEntryView.xaml.cs │ │ ├── UserFollow.xaml │ │ └── UserFollow.xaml.cs │ ├── History │ │ ├── AccountHistory.xaml │ │ ├── AccountHistory.xaml.cs │ │ ├── History.xaml │ │ ├── History.xaml.cs │ │ ├── HistoryEntryView.xaml │ │ ├── HistoryEntryView.xaml.cs │ │ ├── LocalHistory.xaml │ │ ├── LocalHistory.xaml.cs │ │ ├── LocalHistoryEntryView.xaml │ │ └── LocalHistoryEntryView.xaml.cs │ ├── Live │ │ ├── LiveNotify.xaml │ │ └── LiveNotify.xaml.cs │ ├── MainContent.xaml │ ├── MainContent.xaml.cs │ ├── Misc │ │ ├── CrashReportWindow.xaml │ │ ├── CrashReportWindow.xaml.cs │ │ ├── ExitConfirmWindow.xaml │ │ ├── ExitConfirmWindow.xaml.cs │ │ ├── Start.xaml │ │ ├── Start.xaml.cs │ │ ├── WebViewInstallWindow.xaml │ │ └── WebViewInstallWindow.xaml.cs │ ├── Mylist │ │ ├── CreateMylistWindow.xaml │ │ ├── CreateMylistWindow.xaml.cs │ │ ├── Mylist.xaml │ │ ├── Mylist.xaml.cs │ │ ├── MylistResult.xaml │ │ ├── MylistResult.xaml.cs │ │ ├── PublicMylist.xaml │ │ └── PublicMylist.xaml.cs │ ├── NicoRepo │ │ ├── NicoRepo.xaml │ │ ├── NicoRepo.xaml.cs │ │ ├── NicoRepoEntryView.xaml │ │ ├── NicoRepoEntryView.xaml.cs │ │ ├── NicoRepoResult.xaml │ │ └── NicoRepoResult.xaml.cs │ ├── Other │ │ ├── OpenSource.xaml │ │ ├── OpenSource.xaml.cs │ │ ├── Other.xaml │ │ ├── Other.xaml.cs │ │ ├── Overview.xaml │ │ ├── Overview.xaml.cs │ │ ├── PrivacyPolicy.xaml │ │ └── PrivacyPolicy.xaml.cs │ ├── Ranking │ │ ├── CustomRankingEditor.xaml │ │ ├── CustomRankingEditor.xaml.cs │ │ ├── CustomRankingResult.xaml │ │ ├── CustomRankingResult.xaml.cs │ │ ├── HotTopicRankingResult.xaml │ │ ├── HotTopicRankingResult.xaml.cs │ │ ├── Ranking.xaml │ │ ├── Ranking.xaml.cs │ │ ├── RankingResult.xaml │ │ ├── RankingResult.xaml.cs │ │ ├── RankingVideoItemView.xaml │ │ └── RankingVideoItemView.xaml.cs │ ├── Search │ │ ├── Search.xaml │ │ ├── Search.xaml.cs │ │ ├── SearchResult.xaml │ │ └── SearchResult.xaml.cs │ ├── Series │ │ ├── Series.xaml │ │ └── Series.xaml.cs │ ├── Settings │ │ ├── Settings.xaml │ │ ├── Settings.xaml.cs │ │ ├── SettingsComment.xaml │ │ ├── SettingsComment.xaml.cs │ │ ├── SettingsGeneral.xaml │ │ ├── SettingsGeneral.xaml.cs │ │ ├── SettingsLive.xaml │ │ ├── SettingsLive.xaml.cs │ │ ├── SettingsMutedAccount.xaml │ │ ├── SettingsMutedAccount.xaml.cs │ │ ├── SettingsRanking.xaml │ │ ├── SettingsRanking.xaml.cs │ │ ├── SettingsVideo.xaml │ │ └── SettingsVideo.xaml.cs │ ├── SignIn │ │ ├── SignInView.xaml │ │ └── SignInView.xaml.cs │ ├── User │ │ ├── User.xaml │ │ ├── User.xaml.cs │ │ ├── UserFollowView.xaml │ │ ├── UserFollowView.xaml.cs │ │ ├── UserFollower.xaml │ │ ├── UserFollower.xaml.cs │ │ ├── UserFollowing.xaml │ │ ├── UserFollowing.xaml.cs │ │ ├── UserMylist.xaml │ │ ├── UserMylist.xaml.cs │ │ ├── UserMylistView.xaml │ │ ├── UserMylistView.xaml.cs │ │ ├── UserNicoRepo.xaml │ │ ├── UserNicoRepo.xaml.cs │ │ ├── UserSeries.xaml │ │ ├── UserSeries.xaml.cs │ │ ├── UserSeriesView.xaml │ │ ├── UserSeriesView.xaml.cs │ │ ├── UserVideo.xaml │ │ ├── UserVideo.xaml.cs │ │ ├── UserVideoView.xaml │ │ └── UserVideoView.xaml.cs │ ├── Video │ │ ├── Video.xaml │ │ ├── Video.xaml.cs │ │ ├── VideoComment.xaml │ │ ├── VideoComment.xaml.cs │ │ ├── VideoController.xaml │ │ ├── VideoController.xaml.cs │ │ ├── VideoDescription.xaml │ │ ├── VideoDescription.xaml.cs │ │ ├── VideoFullScreen.xaml │ │ ├── VideoFullScreen.xaml.cs │ │ ├── VideoFullScreenDescription.xaml │ │ ├── VideoFullScreenDescription.xaml.cs │ │ ├── VideoInformation.xaml │ │ ├── VideoInformation.xaml.cs │ │ ├── VideoTabView.xaml │ │ ├── VideoTabView.xaml.cs │ │ ├── VideoToolTip.xaml │ │ └── VideoToolTip.xaml.cs │ ├── VideoItemView.xaml │ ├── VideoItemView.xaml.cs │ ├── WatchLater │ │ ├── WatchLater.xaml │ │ ├── WatchLater.xaml.cs │ │ ├── WatchLaterEntryView.xaml │ │ └── WatchLaterEntryView.xaml.cs │ └── WebView │ │ ├── WebView.xaml │ │ ├── WebView.xaml.cs │ │ ├── WebViewContent.xaml │ │ └── WebViewContent.xaml.cs ├── Controls │ ├── DisabledScrollViewerFlowDocumentScrollViewer.cs │ ├── FullScreenVideoPopup.cs │ ├── HtmlRenderer.cs │ ├── ManagedPopup.cs │ ├── PageSpinner.cs │ ├── RoundButton.cs │ ├── SeekBar.cs │ ├── ToggleSwitch.cs │ └── VolumeBar.cs ├── Converters │ ├── CommentLabelConverter.cs │ ├── DoubleToPacentageConverter.cs │ ├── DurationConverter.cs │ ├── EnumDisplayConverter.cs │ ├── FontFamilyToLocalizedNameConverter.cs │ ├── HtmlToXamlConverter.cs │ ├── InvertBoolConverter.cs │ └── VposDurationConverter.cs ├── MainWindow.xaml └── MainWindow.xaml.cs ├── package-lock.json ├── package.json └── tsconfig.json /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2020 mrtska 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Packaging/Images/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/LargeTile.scale-100.png -------------------------------------------------------------------------------- /Packaging/Images/LargeTile.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/LargeTile.scale-125.png -------------------------------------------------------------------------------- /Packaging/Images/LargeTile.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/LargeTile.scale-150.png -------------------------------------------------------------------------------- /Packaging/Images/LargeTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/LargeTile.scale-200.png -------------------------------------------------------------------------------- /Packaging/Images/LargeTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/LargeTile.scale-400.png -------------------------------------------------------------------------------- /Packaging/Images/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /Packaging/Images/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SmallTile.scale-100.png -------------------------------------------------------------------------------- /Packaging/Images/SmallTile.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SmallTile.scale-125.png -------------------------------------------------------------------------------- /Packaging/Images/SmallTile.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SmallTile.scale-150.png -------------------------------------------------------------------------------- /Packaging/Images/SmallTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SmallTile.scale-200.png -------------------------------------------------------------------------------- /Packaging/Images/SmallTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SmallTile.scale-400.png -------------------------------------------------------------------------------- /Packaging/Images/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /Packaging/Images/SplashScreen.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SplashScreen.scale-125.png -------------------------------------------------------------------------------- /Packaging/Images/SplashScreen.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SplashScreen.scale-150.png -------------------------------------------------------------------------------- /Packaging/Images/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /Packaging/Images/SplashScreen.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/SplashScreen.scale-400.png -------------------------------------------------------------------------------- /Packaging/Images/Square150x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square150x150Logo.scale-100.png -------------------------------------------------------------------------------- /Packaging/Images/Square150x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square150x150Logo.scale-125.png -------------------------------------------------------------------------------- /Packaging/Images/Square150x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square150x150Logo.scale-150.png -------------------------------------------------------------------------------- /Packaging/Images/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /Packaging/Images/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-24.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.altform-lightunplated_targetsize-48.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.altform-unplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.altform-unplated_targetsize-16.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.altform-unplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.altform-unplated_targetsize-32.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.altform-unplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.altform-unplated_targetsize-48.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.scale-100.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.scale-125.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.scale-150.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.targetsize-16.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.targetsize-24.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.targetsize-256.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.targetsize-32.png -------------------------------------------------------------------------------- /Packaging/Images/Square44x44Logo.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Square44x44Logo.targetsize-48.png -------------------------------------------------------------------------------- /Packaging/Images/StoreLogo.backup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/StoreLogo.backup.png -------------------------------------------------------------------------------- /Packaging/Images/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /Packaging/Images/StoreLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/StoreLogo.scale-125.png -------------------------------------------------------------------------------- /Packaging/Images/StoreLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/StoreLogo.scale-150.png -------------------------------------------------------------------------------- /Packaging/Images/StoreLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/StoreLogo.scale-200.png -------------------------------------------------------------------------------- /Packaging/Images/StoreLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/StoreLogo.scale-400.png -------------------------------------------------------------------------------- /Packaging/Images/Wide310x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Wide310x150Logo.scale-100.png -------------------------------------------------------------------------------- /Packaging/Images/Wide310x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Wide310x150Logo.scale-125.png -------------------------------------------------------------------------------- /Packaging/Images/Wide310x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Wide310x150Logo.scale-150.png -------------------------------------------------------------------------------- /Packaging/Images/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /Packaging/Images/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /Packaging/Images/production.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/Packaging/Images/production.png -------------------------------------------------------------------------------- /Packaging/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 8 | 9 | 13 | 14 | 15 | NicoNicoViewer 16 | mrtska 17 | Images\StoreLogo.png 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | NicoNicoViewer 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SRNicoNico 2 | ニコニコ動画を見るだけのアプリケーション 3 | WPFでニコニコ動画の動画をhtml5でストリーミング再生します。 4 | 5 | # 使用言語 6 | C# XAML TypeScript JavaScript Html5 CSS3 7 | 8 | # 開発環境 9 | Visual Studio 2019 Professional 10 | 11 | # ライセンス 12 | MITライセンス 13 | 14 | -------------------------------------------------------------------------------- /SRNicoNico.Tests/SRNicoNico.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0-windows10.0.19041.0 5 | 6 | false 7 | x64 8 | SRNicoNico 9 | 10 | 11 | 12 | 13 | 14 | 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | all 17 | 18 | 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | all 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /SRNicoNico.Tests/Tests/Constants.cs.example: -------------------------------------------------------------------------------- 1 | namespace SRNicoNico.Tests { 2 | public static class Constants { 3 | 4 | public const string UserSession = ""; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SRNicoNico.Tests/Tests/HistoryServiceUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using SRNicoNico.Services; 4 | using Xunit; 5 | 6 | namespace SRNicoNico.Tests { 7 | /// 8 | /// IHistoryServiceのユニットテスト 9 | /// 10 | public class HistoryServiceUnitTest { 11 | 12 | private readonly ISessionService SessionService; 13 | private readonly IHistoryService HistoryService; 14 | 15 | public HistoryServiceUnitTest() { 16 | 17 | SessionService = TestingNicoNicoViewer.Instance.TestSessionService; 18 | HistoryService = new NicoNicoHistoryService(SessionService, null); 19 | } 20 | 21 | /// 22 | /// アカウントの視聴履歴が正しく取れることのテスト 23 | /// 24 | [Fact] 25 | public async Task GetAccountHistoryUnitTest() { 26 | 27 | await foreach (var history in HistoryService.GetAccountHistoryAsync()) { 28 | 29 | // 値が取れているかの確認 30 | Assert.False(string.IsNullOrEmpty(history.Id)); 31 | Assert.False(string.IsNullOrEmpty(history.Title)); 32 | Assert.NotNull(history.ShortDescription); 33 | Assert.False(string.IsNullOrEmpty(history.ThumbnailUrl)); 34 | Assert.True(history.RegisteredAt != default); 35 | Assert.True(history.WatchedAt != default); 36 | Assert.True(history.WatchCount > 0); 37 | Assert.True(history.ViewCount > 0); 38 | Assert.True(history.Duration > 0); 39 | 40 | // 最初の1つ目だけ確認する 41 | break; 42 | } 43 | } 44 | 45 | /// 46 | /// アカウントの視聴履歴が削除出来ることのテスト 47 | /// 48 | [Fact] 49 | public async Task DeleteAccountHistoryUnitTest() { 50 | 51 | // sm9を視聴履歴に追加する 無くても削除API自体は成功するっぽいけど 52 | await SessionService.GetAsync("https://www.nicovideo.jp/watch/sm9"); 53 | 54 | // ちょっと待つ 55 | await Task.Delay(1000); 56 | 57 | var result = await HistoryService.DeleteAccountHistoryAsync("sm9"); 58 | 59 | // trueなら成功 60 | Assert.True(result); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SRNicoNico.Tests/Tests/LiveServiceUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using SRNicoNico.Services; 3 | using Xunit; 4 | 5 | namespace SRNicoNico.Tests { 6 | /// 7 | /// ILiveServiceのユニットテスト 8 | /// 9 | public class LiveServiceUnitTest { 10 | 11 | private readonly ILiveService LiveService; 12 | 13 | public LiveServiceUnitTest() { 14 | 15 | LiveService = new NicoNicoLiveService(TestingNicoNicoViewer.Instance.TestSessionService); 16 | } 17 | 18 | /// 19 | /// フォローしているコミュニティやチャンネルが放送中の生放送のリストが正しく取得出来ることのテスト 20 | /// 21 | [Fact] 22 | public async Task GetAccountHistoryUnitTest() { 23 | 24 | foreach (var history in await LiveService.GetOngoingLivesAsync()) { 25 | 26 | // 値が取れているかの確認 27 | Assert.NotEmpty(history.CommunityName); 28 | Assert.NotEmpty(history.ProviderType); 29 | Assert.NotEmpty(history.Title); 30 | Assert.NotEmpty(history.ThumbnailLinkUrl); 31 | Assert.NotEmpty(history.Thumbnailurl); 32 | 33 | break; 34 | } 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SRNicoNico.Tests/Tests/SearchServiceUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using SRNicoNico.Services; 4 | using Xunit; 5 | 6 | namespace SRNicoNico.Tests { 7 | /// 8 | /// ISearchServiceのユニットテスト 9 | /// 10 | public class SearchServiceUnitTest { 11 | 12 | private readonly ISessionService SessionService; 13 | private readonly ISearchService SearchService; 14 | 15 | public SearchServiceUnitTest() { 16 | 17 | SessionService = TestingNicoNicoViewer.Instance.TestSessionService; 18 | SearchService = new NicoNicoSearchService(SessionService, new TestingHistoryService(), new TestingAccountService(), null); 19 | } 20 | 21 | /// 22 | /// 検索が正しく出来ることのテスト 23 | /// 24 | [Fact] 25 | public async Task SearchUnitTest() { 26 | 27 | var result = await SearchService.SearchAsync(SearchSortKey.ViewCountDesc, SearchType.Tag, "Factorio"); 28 | 29 | Assert.NotNull(result.Value); 30 | Assert.NotEmpty(result.Items); 31 | } 32 | 33 | /// 34 | /// ジャンル情報が取得出来ることのテスト 35 | /// 36 | [Fact] 37 | public async Task GetGenreFacetUnitTest() { 38 | 39 | var result = await SearchService.GetGenreFacetAsync(SearchType.Tag, "Factorio"); 40 | Assert.NotEmpty(result); 41 | 42 | foreach (var facet in result) { 43 | 44 | Assert.NotNull(facet.Key); 45 | Assert.NotNull(facet.Label); 46 | 47 | Assert.NotEqual(0, facet.Count); 48 | break; 49 | } 50 | } 51 | 52 | /// 53 | /// お気に入り登録したタグが正しく取得出来ることのテスト 54 | /// 55 | [Fact] 56 | public async Task GetFavTagUnitTest() { 57 | 58 | var result = await SearchService.GetFavoriteTagsAsync(); 59 | Assert.NotEmpty(result); 60 | } 61 | 62 | /// 63 | /// サジェストがが正しく取得出来ることのテスト 64 | /// 65 | [Fact] 66 | public async Task GetTagSuggestionUnitTest() { 67 | 68 | var result = await SearchService.GetTagSuggestionAsync("a"); 69 | Assert.NotEmpty(result); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /SRNicoNico.Tests/Tests/TestingAccountService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using SRNicoNico.Entities; 5 | using SRNicoNico.Models.NicoNicoWrapper; 6 | using SRNicoNico.Services; 7 | 8 | namespace SRNicoNico.Tests { 9 | public class TestingAccountService : IAccountService { 10 | public Task AddMutedAccountAsync(AccountType type, string accountId) { 11 | throw new NotImplementedException(); 12 | } 13 | 14 | public void FlushCache() { 15 | throw new NotImplementedException(); 16 | } 17 | 18 | public Task> GetMutedAccountsAsync() { 19 | throw new NotImplementedException(); 20 | } 21 | 22 | public bool IsMuted(VideoItem item) { 23 | return false; 24 | } 25 | 26 | public bool IsMutedChannel(string channelId) { 27 | return false; 28 | } 29 | 30 | public bool IsMutedCommunity(string communityId) { 31 | return false; 32 | } 33 | 34 | public bool IsMutedUser(string userId) { 35 | return false; 36 | } 37 | 38 | public Task RemoveMutedAccountAsync(AccountType type, string accountId) { 39 | throw new NotImplementedException(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SRNicoNico.Tests/Tests/TestingHistoryService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using SRNicoNico.Entities; 5 | using SRNicoNico.Models.NicoNicoWrapper; 6 | using SRNicoNico.Services; 7 | 8 | namespace SRNicoNico.Tests { 9 | public class TestingHistoryService : IHistoryService { 10 | public Task DeleteAccountHistoryAsync(string videoId) { 11 | throw new NotImplementedException(); 12 | } 13 | 14 | public Task DeleteLocalHistoryAsync(string videoId) { 15 | throw new NotImplementedException(); 16 | } 17 | 18 | public IAsyncEnumerable GetAccountHistoryAsync() { 19 | throw new NotImplementedException(); 20 | } 21 | 22 | public IAsyncEnumerable GetLocalHistoryAsync() { 23 | throw new NotImplementedException(); 24 | } 25 | 26 | public Task HasWatchedAsync(string videoId) { 27 | return Task.FromResult(false); 28 | } 29 | 30 | public Task SyncLocalHistoryAsync(IEnumerable histories) { 31 | throw new NotImplementedException(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SRNicoNico/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo( 4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 5 | //(used if a resource is not found in the page, 6 | // or application resource dictionaries) 7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 8 | //(used if a resource is not found in the page, 9 | // app, or any theme specific resource dictionaries) 10 | )] 11 | -------------------------------------------------------------------------------- /SRNicoNico/Entities/ABRepeatPosition.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace SRNicoNico.Entities { 4 | /// 5 | /// ABリピートのリピート位置を動画単位で持つテーブル 6 | /// 7 | public class ABRepeatPosition { 8 | #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 9 | 10 | /// 11 | /// 動画ID 主キー 12 | /// 13 | [Key] 14 | public string VideoId { get; set; } 15 | 16 | /// 17 | /// ABリピートのA地点 18 | /// 19 | public double RepeatA { get; set; } 20 | 21 | /// 22 | /// ABリピートのB地点 23 | /// 24 | public double RepeatB { get; set; } 25 | 26 | #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SRNicoNico/Entities/LocalHistory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace SRNicoNico.Entities { 5 | /// 6 | /// ローカル視聴履歴テーブル 7 | /// 8 | public class LocalHistory { 9 | #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 10 | 11 | /// 12 | /// 動画ID 主キー 13 | /// 14 | [Key] 15 | public string VideoId { get; set; } 16 | 17 | /// 18 | /// 動画タイトル 19 | /// 20 | public string Title { get; set; } 21 | 22 | /// 23 | /// 動画説明文 24 | /// 25 | public string ShortDescription { get; set; } 26 | 27 | /// 28 | /// 動画のサムネイルURL 29 | /// 30 | public string ThumbnailUrl { get; set; } 31 | 32 | /// 33 | /// 動画の長さ 秒単位 34 | /// 35 | public int Duration { get; set; } 36 | 37 | /// 38 | /// 動画視聴回数 39 | /// 40 | public int WatchCount { get; set; } 41 | 42 | /// 43 | /// 動画投稿日時 44 | /// 45 | public DateTimeOffset PostedAt { get; set; } 46 | 47 | /// 48 | /// 最終視聴日 INDEX 49 | /// 50 | public DateTimeOffset LastWatchedAt { get; set; } 51 | 52 | #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SRNicoNico/Entities/MutedAccount.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace SRNicoNico.Entities { 4 | /// 5 | /// ミュート設定テーブル 6 | /// 7 | public class MutedAccount { 8 | #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 9 | 10 | /// 11 | /// 主キー サロゲートキー 12 | /// 13 | [Key] 14 | public int Key { get; set; } 15 | 16 | /// 17 | /// アカウントタイプ 18 | /// 19 | public AccountType AccountType { get; set; } 20 | 21 | /// 22 | /// アカウントID 23 | /// 24 | public string AccountId { get; set; } 25 | 26 | #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 27 | } 28 | 29 | public enum AccountType { 30 | [Display(Name = "ユーザー")] 31 | User, 32 | [Display(Name = "チャンネル")] 33 | Channel, 34 | [Display(Name = "コミュニティ")] 35 | Community 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SRNicoNico/Entities/RankingVisibility.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace SRNicoNico.Entities { 4 | /// 5 | /// ランキング表示設定テーブル 6 | /// 7 | public class RankingVisibility { 8 | #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 9 | 10 | /// 11 | /// 動画ID 主キー 12 | /// 13 | [Key] 14 | public string GenreKey { get; set; } 15 | 16 | /// 17 | /// 表示するかどうか 18 | /// 19 | public bool IsVisible { get; set; } 20 | 21 | #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SRNicoNico/Entities/SearchHistory.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace SRNicoNico.Entities { 4 | /// 5 | /// 検索履歴テーブル 6 | /// 7 | public class SearchHistory { 8 | #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 9 | 10 | /// 11 | /// 検索文字列 12 | /// 13 | [Key] 14 | public string Query { get; set; } 15 | 16 | /// 17 | /// 順番 18 | /// 19 | public int Order { get; set; } 20 | 21 | #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SRNicoNico/Html/player.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /SRNicoNico/Html/style.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | height: 100%; 4 | background-color: black; 5 | overflow: hidden; 6 | } 7 | 8 | video { 9 | width: 100%; 10 | height: 100%; 11 | } 12 | 13 | canvas { 14 | width: 100%; 15 | height: 100%; 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | right: 0; 20 | bottom: 0; 21 | pointer-events: none; 22 | } 23 | #comment { 24 | font-size: 54px; 25 | } -------------------------------------------------------------------------------- /SRNicoNico/Html/webpack.config.ts: -------------------------------------------------------------------------------- 1 | import webpack from 'webpack'; 2 | 3 | const config: webpack.Configuration = { 4 | mode: 'production', 5 | entry: ['./Html\\videolayer.ts'], 6 | output: { 7 | path: __dirname, 8 | filename: 'player.bundle.js', 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.ts$/, 14 | use: 'ts-loader' 15 | }, { 16 | test: /\.scss$/, 17 | use: [ 18 | 'style-loader', 19 | { 20 | loader: 'css-loader', 21 | options: { 22 | sourceMap: false, 23 | importLoaders: 2 24 | } 25 | }, 26 | { 27 | loader: 'sass-loader', 28 | } 29 | ] 30 | } 31 | ] 32 | }, 33 | resolve: { 34 | extensions: [ '.ts', '.js', '.css' ] 35 | } 36 | }; 37 | 38 | export default config; -------------------------------------------------------------------------------- /SRNicoNico/Icons/Category.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/SRNicoNico/Icons/Category.png -------------------------------------------------------------------------------- /SRNicoNico/Icons/production.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrtska/SRNicoNico/0bab4c914ab1b6a1ce182dc078c9ace76ac80619/SRNicoNico/Icons/production.ico -------------------------------------------------------------------------------- /SRNicoNico/Migrations/20210228172733_InitialDbContextMigration.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Migrations; 5 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 6 | using SRNicoNico.Models; 7 | 8 | namespace SRNicoNico.Migrations { 9 | [DbContext(typeof(ViewerDbContext))] 10 | [Migration("20210228172733_InitialDbContextMigration")] 11 | partial class InitialDbContextMigration { 12 | protected override void BuildTargetModel(ModelBuilder modelBuilder) { 13 | #pragma warning disable 612, 618 14 | modelBuilder 15 | .HasAnnotation("ProductVersion", "3.1.12"); 16 | 17 | modelBuilder.Entity("SRNicoNico.Entities.LocalHistory", b => { 18 | b.Property("VideoId") 19 | .HasColumnType("TEXT"); 20 | 21 | b.Property("Duration") 22 | .HasColumnType("INTEGER"); 23 | 24 | b.Property("LastWatchedAt") 25 | .HasColumnType("INTEGER"); 26 | 27 | b.Property("PostedAt") 28 | .HasColumnType("INTEGER"); 29 | 30 | b.Property("ShortDescription") 31 | .IsRequired() 32 | .HasColumnType("TEXT"); 33 | 34 | b.Property("ThumbnailUrl") 35 | .IsRequired() 36 | .HasColumnType("TEXT"); 37 | 38 | b.Property("Title") 39 | .IsRequired() 40 | .HasColumnType("TEXT"); 41 | 42 | b.Property("WatchCount") 43 | .HasColumnType("INTEGER"); 44 | 45 | b.HasKey("VideoId"); 46 | 47 | b.HasIndex("LastWatchedAt"); 48 | 49 | b.ToTable("LocalHistory"); 50 | }); 51 | #pragma warning restore 612, 618 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SRNicoNico/Migrations/20210228172733_InitialDbContextMigration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace SRNicoNico.Migrations { 4 | public partial class InitialDbContextMigration : Migration { 5 | protected override void Up(MigrationBuilder migrationBuilder) { 6 | migrationBuilder.CreateTable( 7 | name: "LocalHistory", 8 | columns: table => new { 9 | VideoId = table.Column(nullable: false), 10 | Title = table.Column(nullable: false), 11 | ShortDescription = table.Column(nullable: false), 12 | ThumbnailUrl = table.Column(nullable: false), 13 | Duration = table.Column(nullable: false), 14 | WatchCount = table.Column(nullable: false), 15 | PostedAt = table.Column(nullable: false), 16 | LastWatchedAt = table.Column(nullable: false) 17 | }, 18 | constraints: table => { 19 | table.PrimaryKey("PK_LocalHistory", x => x.VideoId); 20 | }); 21 | 22 | migrationBuilder.CreateIndex( 23 | name: "IX_LocalHistory_LastWatchedAt", 24 | table: "LocalHistory", 25 | column: "LastWatchedAt"); 26 | } 27 | 28 | protected override void Down(MigrationBuilder migrationBuilder) { 29 | migrationBuilder.DropTable( 30 | name: "LocalHistory"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SRNicoNico/Migrations/20210605161628_AddABRepeatPositionTable.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Migrations; 5 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 6 | using SRNicoNico.Models; 7 | 8 | namespace SRNicoNico.Migrations { 9 | [DbContext(typeof(ViewerDbContext))] 10 | [Migration("20210605161628_AddABRepeatPositionTable")] 11 | partial class AddABRepeatPositionTable { 12 | protected override void BuildTargetModel(ModelBuilder modelBuilder) { 13 | #pragma warning disable 612, 618 14 | modelBuilder 15 | .HasAnnotation("ProductVersion", "3.1.15"); 16 | 17 | modelBuilder.Entity("SRNicoNico.Entities.ABRepeatPosition", b => { 18 | b.Property("VideoId") 19 | .HasColumnType("TEXT"); 20 | 21 | b.Property("RepeatA") 22 | .HasColumnType("REAL"); 23 | 24 | b.Property("RepeatB") 25 | .HasColumnType("REAL"); 26 | 27 | b.HasKey("VideoId"); 28 | 29 | b.ToTable("ABRepeatPosition"); 30 | }); 31 | 32 | modelBuilder.Entity("SRNicoNico.Entities.LocalHistory", b => { 33 | b.Property("VideoId") 34 | .HasColumnType("TEXT"); 35 | 36 | b.Property("Duration") 37 | .HasColumnType("INTEGER"); 38 | 39 | b.Property("LastWatchedAt") 40 | .HasColumnType("INTEGER"); 41 | 42 | b.Property("PostedAt") 43 | .HasColumnType("INTEGER"); 44 | 45 | b.Property("ShortDescription") 46 | .IsRequired() 47 | .HasColumnType("TEXT"); 48 | 49 | b.Property("ThumbnailUrl") 50 | .IsRequired() 51 | .HasColumnType("TEXT"); 52 | 53 | b.Property("Title") 54 | .IsRequired() 55 | .HasColumnType("TEXT"); 56 | 57 | b.Property("WatchCount") 58 | .HasColumnType("INTEGER"); 59 | 60 | b.HasKey("VideoId"); 61 | 62 | b.HasIndex("LastWatchedAt"); 63 | 64 | b.ToTable("LocalHistory"); 65 | }); 66 | #pragma warning restore 612, 618 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /SRNicoNico/Migrations/20210605161628_AddABRepeatPositionTable.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace SRNicoNico.Migrations { 4 | public partial class AddABRepeatPositionTable : Migration { 5 | protected override void Up(MigrationBuilder migrationBuilder) { 6 | migrationBuilder.CreateTable( 7 | name: "ABRepeatPosition", 8 | columns: table => new { 9 | VideoId = table.Column(nullable: false), 10 | RepeatA = table.Column(nullable: false), 11 | RepeatB = table.Column(nullable: false) 12 | }, 13 | constraints: table => { 14 | table.PrimaryKey("PK_ABRepeatPosition", x => x.VideoId); 15 | }); 16 | } 17 | 18 | protected override void Down(MigrationBuilder migrationBuilder) { 19 | migrationBuilder.DropTable( 20 | name: "ABRepeatPosition"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SRNicoNico/Migrations/20211127145716_AddRankingVisibilityMigration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace SRNicoNico.Migrations { 4 | public partial class AddRankingVisibilityMigration : Migration { 5 | protected override void Up(MigrationBuilder migrationBuilder) { 6 | migrationBuilder.CreateTable( 7 | name: "RankingVisibility", 8 | columns: table => new { 9 | GenreKey = table.Column(nullable: false), 10 | IsVisible = table.Column(nullable: false) 11 | }, 12 | constraints: table => { 13 | table.PrimaryKey("PK_RankingVisibility", x => x.GenreKey); 14 | }); 15 | } 16 | 17 | protected override void Down(MigrationBuilder migrationBuilder) { 18 | migrationBuilder.DropTable( 19 | name: "RankingVisibility"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SRNicoNico/Migrations/20211209175716_AddMutedAccountMigration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace SRNicoNico.Migrations { 4 | public partial class AddMutedAccountMigration : Migration { 5 | protected override void Up(MigrationBuilder migrationBuilder) { 6 | migrationBuilder.CreateTable( 7 | name: "MutedAccount", 8 | columns: table => new { 9 | Key = table.Column(nullable: false) 10 | .Annotation("Sqlite:Autoincrement", true), 11 | AccountType = table.Column(nullable: false), 12 | AccountId = table.Column(nullable: false) 13 | }, 14 | constraints: table => { 15 | table.PrimaryKey("PK_MutedAccount", x => x.Key); 16 | }); 17 | } 18 | 19 | protected override void Down(MigrationBuilder migrationBuilder) { 20 | migrationBuilder.DropTable( 21 | name: "MutedAccount"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SRNicoNico/Migrations/20211215130038_AddSearchHistoryMigration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace SRNicoNico.Migrations { 4 | public partial class AddSearchHistoryMigration : Migration { 5 | protected override void Up(MigrationBuilder migrationBuilder) { 6 | migrationBuilder.CreateTable( 7 | name: "SearchHistory", 8 | columns: table => new { 9 | Query = table.Column(nullable: false), 10 | Order = table.Column(nullable: false) 11 | }, 12 | constraints: table => { 13 | table.PrimaryKey("PK_SearchHistory", x => x.Query); 14 | }); 15 | } 16 | 17 | protected override void Down(MigrationBuilder migrationBuilder) { 18 | migrationBuilder.DropTable( 19 | name: "SearchHistory"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SRNicoNico/Models/INicoNicoViewer.cs: -------------------------------------------------------------------------------- 1 | namespace SRNicoNico.Models { 2 | public interface INicoNicoViewer { 3 | /// 4 | /// NicoNicoViewerのバージョン 5 | /// 6 | double CurrentVersion { get; } 7 | 8 | /// 9 | /// 指定したURLに適したViewModelを作成してUIを表示する 10 | /// 最適なUIが無かった場合はWebViewで開かれる 11 | /// 12 | /// 開きたいURL 13 | void OpenUrl(string url); 14 | 15 | /// 16 | /// URLのタイプを判定する 17 | /// 18 | /// 判定したいURL 19 | /// 判定結果 20 | NicoNicoUrlType DetectUrlType(string url); 21 | 22 | /// 23 | /// 指定したURLがNicoNicoViewerで開けるかどうかを確認する 24 | /// 25 | /// 確認したいURL 26 | /// NicoNicoViewerが開けるURLならTrue 27 | bool CanOpenUrl(string url); 28 | } 29 | 30 | public enum NicoNicoUrlType { 31 | /// 32 | /// 動画 33 | /// 34 | Video, 35 | /// 36 | /// ユーザー 37 | /// 38 | User, 39 | /// 40 | /// マイリスト 41 | /// 42 | Mylist, 43 | /// 44 | /// シリーズ 45 | /// 46 | Series, 47 | /// 48 | /// その他 49 | /// 50 | Other 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /SRNicoNico/Models/JsonObjectExtension.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using DynaJson; 3 | 4 | namespace SRNicoNico.Models { 5 | /// 6 | /// JsonObjectの拡張メソッド 7 | /// 8 | public static class JsonObjectExtension { 9 | 10 | /// 11 | /// Jsonの配列をstringのリストに変換する 12 | /// 13 | /// JsonObject 14 | /// string配列 15 | public static IEnumerable ToStringArray(this JsonObject jsonObject) { 16 | 17 | var list = new List(); 18 | foreach (var element in (dynamic)jsonObject) { 19 | 20 | list.Add(element); 21 | } 22 | return list; 23 | } 24 | 25 | /// 26 | /// Jsonの配列をstringのリストに変換する 27 | /// 28 | /// JsonObject 29 | /// デフォルト値として追加する値 30 | /// string配列 31 | public static IEnumerable ToStringArray(this JsonObject jsonObject, params string[] defaultValues) { 32 | 33 | var list = new List(); 34 | list.AddRange(defaultValues); 35 | 36 | foreach (var element in (dynamic)jsonObject) { 37 | 38 | list.Add(element); 39 | } 40 | return list; 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/History/HistoryVideoItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// 視聴履歴の動画情報 6 | /// 7 | public class HistoryVideoItem : VideoItem { 8 | /// 9 | /// 最終視聴日時 10 | /// 11 | public DateTimeOffset WatchedAt { get; set; } 12 | 13 | /// 14 | /// 視聴回数 15 | /// 16 | public int WatchCount { get; set; } 17 | 18 | /// 19 | /// 動画のIDかな? 20 | /// 21 | public string WatchId { get; set; } = default!; 22 | 23 | public HistoryVideoItem() { 24 | } 25 | 26 | public HistoryVideoItem(dynamic item) { 27 | Fill(item); 28 | } 29 | 30 | public override VideoItem Fill(dynamic item) { 31 | 32 | WatchedAt = DateTimeOffset.Parse(item.lastViewedAt); 33 | WatchCount = (int) item.views; 34 | WatchId = item.watchId; 35 | 36 | return base.Fill((object)item.video); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Live/OngoingLive.cs: -------------------------------------------------------------------------------- 1 | namespace SRNicoNico.Models.NicoNicoWrapper { 2 | /// 3 | /// 放送中の生放送 4 | /// 5 | public class OngoingLive { 6 | /// 7 | /// コミュニティ名 (チャンネル名の時もある) 8 | /// 9 | public string CommunityName { get; set; } = default!; 10 | /// 11 | /// 経過時間 12 | /// 13 | public int ElapsedTime { get; set; } 14 | /// 15 | /// 生放送ID 16 | /// 17 | public string Id { get; set; } = default!; 18 | /// 19 | /// community, channel, officialのどれか 20 | /// 21 | public string ProviderType { get; set; } = default!; 22 | /// 23 | /// サムネイルURL 24 | /// 25 | public string Thumbnailurl { get; set; } = default!; 26 | /// 27 | /// 生放送URL 28 | /// 29 | public string ThumbnailLinkUrl { get; set; } = default!; 30 | /// 31 | /// 生放送タイトル 32 | /// 33 | public string Title { get; set; } = default!; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Mylist/Mylist.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// マイリストの情報 6 | /// 7 | public class Mylist { 8 | /// 9 | /// デフォルトの並び順のキー 10 | /// 11 | public string DefaultSortKey { get; set; } = default!; 12 | /// 13 | /// デフォルトの並び順 14 | /// ascかdesc 15 | /// 16 | public string DefaultSortOrder { get; set; } = default!; 17 | /// 18 | /// マイリストの説明文 19 | /// 20 | public string? Description { get; set; } 21 | /// 22 | /// マイリストをフォローしている人の数 23 | /// 24 | public int FollowerCount { get; set; } 25 | /// 26 | /// 不可視のアイテムがあるかどうか 27 | /// 謎 28 | /// 29 | public bool HasInvisibleItems { get; set; } 30 | /// 31 | /// 次のページがあるかどうか 32 | /// 33 | public bool HasNext { get; set; } 34 | /// 35 | /// マイリストのID 36 | /// 37 | public string Id { get; set; } = default!; 38 | /// 39 | /// マイリストをフォローしているかどうか 40 | /// 41 | public bool IsFollowing { get; set; } 42 | /// 43 | /// マイリストが公開されているかどうか 44 | /// 45 | public bool IsPublic { get; set; } 46 | /// 47 | /// マイリスト名 48 | /// 49 | public string Name { get; set; } = default!; 50 | /// 51 | /// マイリストに含まれている動画の総数 52 | /// 53 | public int TotalItemCount { get; set; } 54 | 55 | /// 56 | /// 動画投稿者のサムネイルURL 57 | /// 58 | public string? OwnerIconUrl { get; set; } 59 | /// 60 | /// 動画投稿者のID 61 | /// 62 | public string? OwnerId { get; set; } 63 | /// 64 | /// 動画投稿者の名前 65 | /// 66 | public string? OwnerName { get; set; } 67 | /// 68 | /// 動画投稿者の種類 69 | /// userかchannelかhidden 70 | /// 71 | public string? OwnerType { get; set; } 72 | 73 | /// 74 | /// あとで見るのリスト 75 | /// TotalCountと同じ数とは限らない 76 | /// 77 | public IEnumerable Entries { get; set; } = default!; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Mylist/MylistItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SRNicoNico.Models.NicoNicoWrapper { 5 | /// 6 | /// マイリストの情報 7 | /// 8 | public class MylistItem { 9 | /// 10 | /// マイリストを作成した日付 11 | /// 12 | public DateTimeOffset CreatedAt { get; set; } 13 | /// 14 | /// デフォルトの並び順のキー 15 | /// 16 | public string DefaultSortKey { get; set; } = default!; 17 | /// 18 | /// デフォルトの並び順 19 | /// ascかdesc 20 | /// 21 | public string DefaultSortOrder { get; set; } = default!; 22 | /// 23 | /// マイリストの説明文 24 | /// 25 | public string? Description { get; set; } 26 | /// 27 | /// マイリストをフォローしている人の数 28 | /// 29 | public int FollowerCount { get; set; } 30 | /// 31 | /// マイリストのID 32 | /// 33 | public string Id { get; set; } = default!; 34 | /// 35 | /// マイリストをフォローしているかどうか 36 | /// 37 | public bool IsFollowing { get; set; } 38 | /// 39 | /// マイリストが公開されているかどうか 40 | /// 41 | public bool IsPublic { get; set; } 42 | /// 43 | /// マイリストに含まれている動画の数 44 | /// 45 | public int ItemsCount { get; set; } 46 | /// 47 | /// マイリスト名 48 | /// 49 | public string Name { get; set; } = default!; 50 | 51 | /// 52 | /// 動画投稿者のサムネイルURL 53 | /// 54 | public string? OwnerIconUrl { get; set; } 55 | /// 56 | /// 動画投稿者のID 57 | /// 58 | public string? OwnerId { get; set; } 59 | /// 60 | /// 動画投稿者の名前 61 | /// 62 | public string? OwnerName { get; set; } 63 | /// 64 | /// 動画投稿者の種類 65 | /// userかchannelかhidden 66 | /// 67 | public string OwnerType { get; set; } = default!; 68 | 69 | /// 70 | /// マイリストに含まれている動画のサンプル 71 | /// 72 | public IEnumerable SampleItems { get; set; } = default!; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Mylist/MylistVideoItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// あとで見るやマイリストの動画情報 6 | /// 7 | public class MylistVideoItem : VideoItem { 8 | /// 9 | /// あとで見るやマイリストに追加された日時 10 | /// 11 | public DateTimeOffset AddedAt { get; set; } 12 | /// 13 | /// アイテムID 14 | /// 15 | public string ItemId { get; set; } = default!; 16 | /// 17 | /// メモ 18 | /// マイリストコメント的なもの 19 | /// 20 | public string Memo { get; set; } = default!; 21 | /// 22 | /// ステータス 23 | /// public, hidden, memberOnly それ以外もあるかも 24 | /// 25 | public string Status { get; set; } = default!; 26 | /// 27 | /// 動画のIDかな? 28 | /// 29 | public string WatchId { get; set; } = default!; 30 | 31 | public override VideoItem Fill(dynamic item) { 32 | 33 | AddedAt = DateTimeOffset.Parse(item.addedAt); 34 | ItemId = item.itemId.ToString(); 35 | Memo = item.memo() ? item.memo : item.description; // あとで見るはmemoだけどマイリストはdescription 36 | Status = item.status; 37 | WatchId = item.watchId; 38 | 39 | return base.Fill((object)item.video); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/NicoRepo/NicoRepoList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SRNicoNico.Models.NicoNicoWrapper { 6 | /// 7 | /// ニコレポ情報 8 | /// 9 | public class NicoRepoList { 10 | /// 11 | /// さらに読み込むニコレポがあるかどうか 12 | /// 13 | public bool HasNext { get; set; } 14 | 15 | public string? MaxId { get; set; } 16 | 17 | public string? MinId { get; set; } 18 | 19 | /// 20 | /// ニコレポリスト 21 | /// 22 | public IEnumerable? Entries { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Ranking/CustomRankingDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// カスタムランキング情報 6 | /// 7 | public class CustomRankingDetails : RankingDetails { 8 | /// 9 | /// レーンID 10 | /// 11 | public int LaneId { get; set; } 12 | /// 13 | /// レーンタイプ custom固定のはず 14 | /// 15 | public string LaneType { get; set; } = default!; 16 | /// 17 | /// カスタムランキング名 18 | /// 19 | public string Title { get; set; } = default!; 20 | /// 21 | /// ランキングタイプ tagかgenre 22 | /// 23 | public string CustomType { get; set; } = default!; 24 | /// 25 | /// ランキングを構成しているジャンル 26 | /// Typeがgenreの時のみ有効 27 | /// 28 | public IDictionary Genres { get; set; } = default!; 29 | /// 30 | /// ランキングを構成しているタグ 31 | /// Typeがtagの時のみ有効 32 | /// 33 | public IEnumerable Tags { get; set; } = default!; 34 | /// 35 | /// チャンネル動画をランキングに含むかどうか 36 | /// 37 | public string ChannelVideoListingStatus { get; set; } = default!; 38 | /// 39 | /// デフォルトで用意されているランキングかどうか 40 | /// 41 | public bool IsDefault { get; set; } 42 | /// 43 | /// デフォルトのランキング名 44 | /// 45 | public string DefaultTitle { get; set; } = default!; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Ranking/HotTopics.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SRNicoNico.Models.NicoNicoWrapper { 5 | /// 6 | /// 話題の一覧 7 | /// 8 | public class HotTopics { 9 | /// 10 | /// 要素 11 | /// 12 | public IEnumerable Items { get; set; } = default!; 13 | /// 14 | /// ジャンル更新日? 15 | /// 16 | public DateTimeOffset StartAt { get; set; } 17 | } 18 | 19 | public class HotTopicsItem { 20 | /// 21 | /// キー 22 | /// 23 | public string Key { get; set; } = default!; 24 | /// 25 | /// ラベル 26 | /// 27 | public string Label { get; set; } = default!; 28 | /// 29 | /// タグ 30 | /// 31 | public string Tag { get; set; } = default!; 32 | /// 33 | /// ジャンルのキー 34 | /// 35 | public string GenreKey { get; set; } = default!; 36 | /// 37 | /// ジャンルのラベル 38 | /// 39 | public string GenreLabel { get; set; } = default!; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Ranking/PopularTags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SRNicoNico.Models.NicoNicoWrapper { 5 | /// 6 | /// 人気のタグ 7 | /// 8 | public class PopularTags { 9 | /// 10 | /// 人気のタグ 11 | /// 12 | public IEnumerable Tags { get; set; } = default!; 13 | /// 14 | /// 人気のタグ更新日? 15 | /// 16 | public DateTimeOffset StartAt { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Ranking/RankingDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// ランキング情報 6 | /// 7 | public class RankingDetails { 8 | /// 9 | /// 次があるか 10 | /// 11 | public bool HasNext { get; set; } 12 | /// 13 | /// 動画リスト 14 | /// 15 | public IEnumerable VideoList { get; set; } = default!; 16 | } 17 | 18 | public class RankingVideoItem : VideoItem { 19 | /// 20 | /// 順位 21 | /// 22 | public int Rank { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Ranking/RankingSetting.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// カスタムランキングの設定 6 | /// 7 | public class RankingSetting { 8 | 9 | /// 10 | /// 設定 11 | /// 12 | public RankingSettingsEntry Setting { get; set; } = default!; 13 | 14 | /// 15 | /// ジャンル情報 16 | /// 17 | public IDictionary GenreMap { get; set; } = default!; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Ranking/RankingSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// カスタムランキングの設定 6 | /// 7 | public class RankingSettings { 8 | 9 | /// 10 | /// 設定のリスト 11 | /// 12 | public IEnumerable Settings { get; set; } = default!; 13 | 14 | /// 15 | /// ジャンル情報 16 | /// 17 | public IDictionary GenreMap { get; set; } = default!; 18 | } 19 | 20 | public class RankingSettingsEntry { 21 | /// 22 | /// ランキングのレーンID 23 | /// 24 | public int LaneId { get; set; } 25 | /// 26 | /// レーンタイトル 27 | /// 28 | public string Title { get; set; } = default!; 29 | /// 30 | /// ランキングタイプ tagかgenre 31 | /// 32 | public string Type { get; set; } = default!; 33 | 34 | /// 35 | /// 全ジャンル選択かどうか 36 | /// 37 | public bool IsAllGenre { get; set; } 38 | /// 39 | /// ランキングを構成しているジャンル 40 | /// Typeがgenreの時のみ有効 41 | /// 42 | public IEnumerable GenreKeys { get; set; } = default!; 43 | /// 44 | /// ランキングを構成しているタグ 45 | /// Typeがtagの時のみ有効 46 | /// 47 | public IEnumerable Tags { get; set; } = default!; 48 | 49 | /// 50 | /// チャンネル動画をランキングに含むかどうか 51 | /// only, excluded, includedのどれか 52 | /// 53 | public string ChannelVideoListingStatus { get; set; } = default!; 54 | /// 55 | /// デフォルトで用意されているランキングかどうか 56 | /// 57 | public bool IsDefault { get; set; } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Search/SearchGenreFacet.cs: -------------------------------------------------------------------------------- 1 | namespace SRNicoNico.Models.NicoNicoWrapper { 2 | /// 3 | /// ジャンル情報 4 | /// 5 | public class SearchGenreFacet { 6 | /// 7 | /// ジャンルのキー 8 | /// 9 | public string Key { get; set; } = default!; 10 | /// 11 | /// ジャンルのラベル 12 | /// 13 | public string Label { get; set; } = default!; 14 | /// 15 | /// 動画数 16 | /// 17 | public int Count { get; set; } 18 | /// 19 | /// 取得した時間 20 | /// 21 | public long Time { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Search/SearchResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SRNicoNico.Services; 3 | 4 | namespace SRNicoNico.Models.NicoNicoWrapper { 5 | public class SearchResult { 6 | /// 7 | /// タグかキーワードか 8 | /// 9 | public SearchType SearchType { get; set; } 10 | /// 11 | /// 検索タグ 12 | /// 13 | public string Value { get; set; } = default!; 14 | /// 15 | /// 検索結果の数 16 | /// 17 | public int TotalCount { get; set; } 18 | /// 19 | /// 次のページがあるかどうか 20 | /// 21 | public bool HasNext { get; set; } 22 | 23 | /// 24 | /// 検索結果 25 | /// 26 | public IEnumerable Items { get; set; } = default!; 27 | 28 | /// 29 | /// 取得した時間 30 | /// 31 | public long Time { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Series/Series.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SRNicoNico.Models.NicoNicoWrapper { 5 | /// 6 | /// シリーズ 7 | /// 8 | public class Series { 9 | /// 10 | /// シリーズID 11 | /// 12 | public string? SeriesId { get; set; } 13 | /// 14 | /// オーナータイプ 15 | /// 16 | public string? OwnerType { get; set; } 17 | /// 18 | /// オーナーID 19 | /// 20 | public string? OwnerId { get; set; } 21 | /// 22 | /// オーナー名 23 | /// 24 | public string? OwnerName { get; set; } 25 | /// 26 | /// シリーズ名 27 | /// 28 | public string? Title { get; set; } 29 | /// 30 | /// シリーズ説明文 31 | /// 32 | public string? Description { get; set; } 33 | 34 | /// 35 | /// サムネイルURL 36 | /// 37 | public string? ThumbnailUrl { get; set; } 38 | /// 39 | /// リストに表示されるかどうか 40 | /// 41 | public bool IsListed { get; set; } 42 | /// 43 | /// シリーズ作成日時 44 | /// 45 | public DateTimeOffset CreatedAt { get; set; } 46 | /// 47 | /// シリーズ更新日時 48 | /// 49 | public DateTimeOffset UpdatedAt { get; set; } 50 | 51 | /// 52 | /// シリーズの中の動画数 53 | /// 54 | public int TotalCount { get; set; } 55 | /// 56 | /// シリーズのリスト 57 | /// 58 | public IEnumerable? Items { get; set; } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Series/SeriesList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// シリーズリスト 6 | /// 7 | public class SeriesList { 8 | /// 9 | /// シリーズのリスト 10 | /// 11 | public IEnumerable? Items { get; set; } 12 | /// 13 | /// シリーズの総数 14 | /// 15 | public int TotalCount { get; set; } 16 | } 17 | 18 | public class SeriesListItem { 19 | /// 20 | /// シリーズID 21 | /// 22 | public string? Id { get; set; } 23 | /// 24 | /// シリーズ名 25 | /// 26 | public string? Title { get; set; } 27 | /// 28 | /// シリーズ説明文 29 | /// 30 | public string? Description { get; set; } 31 | /// 32 | /// 含まれる動画の数 33 | /// 34 | public int ItemsCount { get; set; } 35 | /// 36 | /// サムネイルURL 37 | /// 38 | public string? ThumbnailUrl { get; set; } 39 | /// 40 | /// リストに表示されるかどうか 41 | /// 42 | public bool IsListed { get; set; } 43 | /// 44 | /// オーナータイプ 45 | /// 46 | public string? OwnerType { get; set; } 47 | /// 48 | /// オーナーID 49 | /// 50 | public string? OwnerId { get; set; } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/User/ChannelEntry.cs: -------------------------------------------------------------------------------- 1 | namespace SRNicoNico.Models.NicoNicoWrapper { 2 | /// 3 | /// チャンネル情報 4 | /// 5 | public class ChannelEntry { 6 | 7 | /// 8 | /// チャンネルの税抜価格(多分) 9 | /// 10 | public int BodyPrice { get; set; } 11 | 12 | /// 13 | /// チャンネルに入会可能かどうか 14 | /// 15 | public bool CanAdmit { get; set; } 16 | 17 | /// 18 | /// チャンネルの説明文 19 | /// 20 | public string? Description { get; set; } 21 | 22 | /// 23 | /// チャンネルのID 24 | /// 25 | public string? Id { get; set; } 26 | 27 | /// 28 | /// 成人向けのチャンネルかどうか 29 | /// 30 | public bool IsAdult { get; set; } 31 | 32 | /// 33 | /// 無料かどうか 34 | /// 35 | public bool IsFree { get; set; } 36 | 37 | /// 38 | /// チャンネル名 39 | /// 40 | public string? Name { get; set; } 41 | 42 | /// 43 | /// チャンネルの提供者または所有者 44 | /// 45 | public string? OwnerName { get; set; } 46 | 47 | /// 48 | /// チャンネルの税込価格(多分) 49 | /// 50 | public int Price { get; set; } 51 | 52 | /// 53 | /// チャンネルのURLの部分 54 | /// 55 | public string? ScreenName { get; set; } 56 | 57 | /// 58 | /// チャンネルに入会しているかどうか 59 | /// 60 | public bool IsJoining { get; set; } 61 | 62 | /// 63 | /// チャンネルのサムネイルURL(小さい版) 64 | /// 65 | public string? ThumbnailSmallUrl { get; set; } 66 | 67 | /// 68 | /// チャンネルのサムネイルURL 69 | /// 70 | public string? ThumbnailUrl { get; set; } 71 | 72 | /// 73 | /// チャンネルのパーマリンク 74 | /// 75 | public string? Url { get; set; } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/User/CommunityList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// コミュニティ情報のリスト 6 | /// 7 | public class CommunityList { 8 | 9 | /// 10 | /// フォローしているコミュニティ数 11 | /// 12 | public int Total { get; set; } 13 | 14 | /// 15 | /// 取得しているページ 16 | /// 17 | public int Page { get; set; } 18 | 19 | /// 20 | /// コミュニティリスト 21 | /// 22 | public IEnumerable? Entries { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/User/TagEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// タグ情報 6 | /// 7 | public class TagEntry { 8 | 9 | /// 10 | /// タグ名 11 | /// 12 | public string Name { get; set; } = default!; 13 | 14 | /// 15 | /// タグの概要文 16 | /// 17 | public string Summary { get; set; } = default!; 18 | 19 | /// 20 | /// タグをフォローした時間 21 | /// 22 | public DateTimeOffset FollowedAt { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/User/UserEntry.cs: -------------------------------------------------------------------------------- 1 | namespace SRNicoNico.Models.NicoNicoWrapper { 2 | /// 3 | /// ユーザー情報 4 | /// 5 | public class UserEntry { 6 | 7 | /// 8 | /// ニコニコのユーザーID 9 | /// 10 | public string Id { get; set; } = default!; 11 | 12 | /// 13 | /// ニコニコのユーザー名 14 | /// 15 | public string NickName { get; set; } = default!; 16 | 17 | /// 18 | /// ユーザーのサムネイルのURL 19 | /// 20 | public string ThumbnailUrl { get; set; } = default!; 21 | 22 | /// 23 | /// ユーザーの説明文 htmlタグ付き 24 | /// 25 | public string Description { get; set; } = default!; 26 | 27 | /// 28 | /// ユーザーの説明文 htmlタグ無し 29 | /// 30 | public string StrippedDescription { get; set; } = default!; 31 | 32 | /// 33 | /// プレミアム会員かどうか 34 | /// 35 | public bool IsPremium { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/User/UserFollowList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// フォローしている/されているユーザーのリスト 6 | /// 7 | public class UserFollowList { 8 | /// 9 | /// ユーザーリスト 10 | /// 11 | public IEnumerable? Items { get; set; } 12 | /// 13 | /// 位置 14 | /// 15 | public string? Cursor { get; set; } 16 | /// 17 | /// フォローしている数 18 | /// 19 | public int Followees { get; set; } 20 | /// 21 | /// フォローされている数 22 | /// 23 | public int Followers { get; set; } 24 | /// 25 | /// 次があるかどうか 26 | /// 27 | public bool HasNext { get; set; } 28 | } 29 | 30 | public class UserFollowItem { 31 | /// 32 | /// ユーザーID 33 | /// 34 | public string? UserId { get; set; } 35 | /// 36 | /// 説明文 37 | /// 38 | public string? Description { get; set; } 39 | /// 40 | /// HTMLタグを削除した説明文 41 | /// 42 | public string? StrippedDescription { get; set; } 43 | /// 44 | /// ユーザー名 45 | /// 46 | public string? Nickname { get; set; } 47 | /// 48 | /// プレミアム会員かどうか 49 | /// 50 | public bool IsPremium { get; set; } 51 | /// 52 | /// 自分がフォローしているかどうか 53 | /// 54 | public bool IsFollowing { get; set; } 55 | /// 56 | /// サムネイルURL 57 | /// 58 | public string? ThumbnailLargeUrl { get; set; } 59 | /// 60 | /// サムネイルURL 61 | /// 62 | public string? ThumbnailSmallUrl { get; set; } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/User/UserList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// ユーザー情報のリスト 6 | /// 7 | public class UserList { 8 | 9 | /// 10 | /// フォローしているユーザー数 11 | /// 12 | public int Total { get; set; } 13 | 14 | /// 15 | /// 取得しているページ 16 | /// 17 | public int Page { get; set; } 18 | 19 | /// 20 | /// ユーザーリスト 21 | /// 22 | public IEnumerable Entries { get; set; } = default!; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Video/DmcSession.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace SRNicoNico.Models.NicoNicoWrapper { 5 | /// 6 | /// 作成したDMCのセッション 7 | /// 8 | public class DmcSession { 9 | /// 10 | /// セッションID 11 | /// 12 | public string? Id { get; set; } 13 | 14 | /// 15 | /// 動画ID 16 | /// 17 | public string? VideoId { get; set; } 18 | /// 19 | /// オーディオID 20 | /// 21 | public string? AudioId { get; set; } 22 | 23 | /// 24 | /// 動画URL 25 | /// 26 | public string? ContentUri { get; set; } 27 | 28 | /// 29 | /// バージョン 30 | /// 31 | public string? Version { get; set; } 32 | 33 | /// 34 | /// 生のJsonオブジェクト 35 | /// 36 | public string? RawJson { get; set; } 37 | 38 | /// 39 | /// API URL 40 | /// 41 | public string? ApiUrl { get; set; } 42 | 43 | /// 44 | /// セッション作成時間 45 | /// 46 | public DateTimeOffset CreatedTime { get; set; } 47 | 48 | /// 49 | /// セッション有効期限 50 | /// 51 | public DateTimeOffset ExpireTime { get; set; } 52 | 53 | /// 54 | /// DMS用Cookie 55 | /// 56 | public Cookie? DmsCookie { get; set; } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/Video/VideoStoryBoard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | 6 | namespace SRNicoNico.Models.NicoNicoWrapper { 7 | /// 8 | /// ストーリーボード情報 9 | /// 10 | public class VideoStoryBoard : IDisposable { 11 | 12 | /// 13 | /// ストーリーボードの画像1枚分の高さ 14 | /// 15 | public int ThumbnailHeight { get; set; } 16 | 17 | /// 18 | /// ストーリーボードの画像1枚分の横幅 19 | /// 20 | public int ThumbnailWidth { get; set; } 21 | 22 | /// 23 | /// 画像の行数 24 | /// 25 | public int Rows { get; set; } 26 | /// 27 | /// 画像の列数 28 | /// 29 | public int Columns { get; set; } 30 | 31 | /// 32 | /// 画像間の秒数 33 | /// 34 | public int Interval { get; set; } 35 | 36 | /// 37 | /// ストーリーボードの画像のマップ 38 | /// 39 | public IDictionary? BitmapMap { get; set; } 40 | 41 | public void Dispose() { 42 | BitmapMap?.Values.ToList().ForEach(f => f.Dispose()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /SRNicoNico/Models/NicoNicoWrapper/WatchLater/WatchLaterList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SRNicoNico.Models.NicoNicoWrapper { 4 | /// 5 | /// 「あとで見る」のリスト 6 | /// 7 | public class WatchLaterList { 8 | /// 9 | /// 不可視のアイテムがあるかどうか 10 | /// 謎 11 | /// 12 | public bool HasInvisibleItems { get; set; } 13 | /// 14 | /// 次のページがあるかどうか 15 | /// 16 | public bool HasNext { get; set; } 17 | /// 18 | /// あとで見るの総数 19 | /// 20 | public int TotalCount { get; set; } 21 | /// 22 | /// あとで見るのリスト 23 | /// TotalCountと同じ数とは限らない 24 | /// 25 | public IEnumerable Entries { get; set; } = default!; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SRNicoNico/Models/StatusErrorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Http; 4 | 5 | namespace SRNicoNico.Models { 6 | /// 7 | /// APIアクセス時に正常なレスポンスが帰ってこなかった時にスローされる例外 8 | /// 仕様変更や鯖落ちなど 9 | /// 10 | public class StatusErrorException : HttpRequestException { 11 | /// 12 | /// エラーになったリクエストのステータスコード 13 | /// 503などが入る想定 14 | /// 15 | public HttpStatusCode StatusCode { get; private set; } 16 | 17 | public StatusErrorException(HttpStatusCode statusCode) : base($"データ取得中にエラーが発生しました ステータス: {statusCode}") { 18 | 19 | StatusCode = statusCode; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SRNicoNico/SRNicoNico.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | net6.0-windows10.0.19041.0 6 | true 7 | enable 8 | x86;x64 9 | false 10 | win10-x64 11 | Icons\production.ico 12 | full 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | all 30 | runtime; build; native; contentfiles; analyzers; buildtransitive 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Always 41 | 42 | 43 | Always 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /SRNicoNico/Services/IAccountService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using SRNicoNico.Entities; 4 | using SRNicoNico.Models.NicoNicoWrapper; 5 | 6 | namespace SRNicoNico.Services { 7 | /// 8 | /// アカウントサービス 9 | /// 10 | public interface IAccountService { 11 | 12 | /// 13 | /// 指定した動画がミュート対象かを返す 14 | /// 15 | /// 確認対象 16 | /// ミュート対象ならTrue 17 | bool IsMuted(VideoItem item); 18 | 19 | /// 20 | /// 指定したユーザがミュート対象かを返す 21 | /// 22 | /// 確認対象 23 | /// ミュート対象ならTrue 24 | bool IsMutedUser(string userId); 25 | 26 | /// 27 | /// 指定したチャンネルがミュート対象かを返す 28 | /// 29 | /// 確認対象 30 | /// ミュート対象ならTrue 31 | bool IsMutedChannel(string channelId); 32 | 33 | /// 34 | /// 指定したコミュニティがミュート対象かを返す 35 | /// 36 | /// 確認対象 37 | /// ミュート対象ならTrue 38 | bool IsMutedCommunity(string communityId); 39 | 40 | /// 41 | /// ミュートアカウントのキャッシュをフラッシュする 42 | /// 43 | void FlushCache(); 44 | 45 | /// 46 | /// 全てのミュート設定を取得する 47 | /// 48 | /// ミュート設定 49 | Task> GetMutedAccountsAsync(); 50 | 51 | /// 52 | /// 指定した条件でミュート設定を追加する 53 | /// 54 | /// アカウントタイプ 55 | /// ID 56 | /// 既に登録済みならfalseを返す 57 | Task AddMutedAccountAsync(AccountType type, string accountId); 58 | 59 | /// 60 | /// 指定した条件のミュート設定を削除する 61 | /// 62 | /// アカウントタイプ 63 | /// ID 64 | Task RemoveMutedAccountAsync(AccountType type, string accountId); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /SRNicoNico/Services/IChannelCommunityService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace SRNicoNico.Services { 6 | /// 7 | /// チャンネルとコミュニティ関連の処理を提供するサービス 8 | /// 9 | public interface IChannelCommunityService { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SRNicoNico/Services/IHistoryService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using SRNicoNico.Entities; 6 | using SRNicoNico.Models.NicoNicoWrapper; 7 | 8 | namespace SRNicoNico.Services { 9 | /// 10 | /// 視聴履歴を操作する処理を提供するサービス 11 | /// 12 | public interface IHistoryService { 13 | 14 | /// 15 | /// アカウントの視聴履歴を取得できる分だけ返す 16 | /// 17 | /// アカウントの視聴履歴 取得に失敗した場合はnull 18 | /// 取得に失敗した場合 19 | IAsyncEnumerable GetAccountHistoryAsync(); 20 | 21 | /// 22 | /// ローカルの視聴履歴を取得できる分だけ返す 23 | /// 24 | /// ローカルの視聴履歴 25 | IAsyncEnumerable GetLocalHistoryAsync(); 26 | 27 | /// 28 | /// アカウントの視聴履歴を削除する 29 | /// 30 | /// 削除したい動画ID 31 | /// 削除に成功したらTrue 32 | Task DeleteAccountHistoryAsync(string videoId); 33 | 34 | /// 35 | /// ローカルの視聴履歴を削除する 36 | /// 視聴時間でソートされる 37 | /// 38 | /// 削除したい動画ID 39 | /// 削除に成功したらTrue 40 | Task DeleteLocalHistoryAsync(string videoId); 41 | 42 | /// 43 | /// 渡した視聴履歴をローカル視聴履歴に同期させる 44 | /// 45 | /// アカウントの視聴履歴 46 | /// 成功したらTrue 47 | Task SyncLocalHistoryAsync(IEnumerable histories); 48 | 49 | /// 50 | /// 指定した動画が視聴済みかどうかを返す 51 | /// 52 | /// 確認したい動画のID 53 | /// 視聴済みならTrue 54 | Task HasWatchedAsync(string videoId); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SRNicoNico/Services/ILiveService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using SRNicoNico.Models.NicoNicoWrapper; 4 | 5 | namespace SRNicoNico.Services { 6 | /// 7 | /// 生放送関連の処理を提供するサービス 8 | /// 9 | public interface ILiveService { 10 | 11 | /// 12 | /// 現在放送中の生放送を取得する 13 | /// 14 | /// 放送中の生放送のリスト 15 | Task> GetOngoingLivesAsync(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SRNicoNico/Services/ISeriesService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using SRNicoNico.Models.NicoNicoWrapper; 5 | 6 | namespace SRNicoNico.Services { 7 | /// 8 | /// シリーズ関連の処理を提供するサービス 9 | /// 10 | public interface ISeriesService { 11 | 12 | /// 13 | /// 指定したユーザーIDのシリーズを取得する 14 | /// 15 | /// ユーザーID 16 | /// ページ 17 | /// ページ数 18 | /// シリーズのリスト 19 | Task GetUserSeriesAsync(string userId, int page = 1, int pageSize = 100); 20 | 21 | /// 22 | /// 指定したIDのシリーズ情報を取得する 23 | /// 24 | /// シリーズID 25 | /// シリーズ情報 26 | Task GetSeriesAsync(string seriesId); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SRNicoNico/Services/NicoNicoLiveService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using DynaJson; 4 | using SRNicoNico.Models; 5 | using SRNicoNico.Models.NicoNicoWrapper; 6 | 7 | namespace SRNicoNico.Services { 8 | /// 9 | /// ILiveServiceの実装 10 | /// 11 | public class NicoNicoLiveService : ILiveService { 12 | /// 13 | /// 現在放送中の生放送を取得するAPI 14 | /// 15 | private const string GetOngoingLiveApiUrl = "https://papi.live.nicovideo.jp/api/relive/notifybox.content"; 16 | 17 | private readonly ISessionService SessionService; 18 | 19 | public NicoNicoLiveService(ISessionService sessionService) { 20 | 21 | SessionService = sessionService; 22 | } 23 | 24 | /// 25 | public async Task> GetOngoingLivesAsync() { 26 | 27 | var query = new GetRequestQueryBuilder(GetOngoingLiveApiUrl) 28 | .AddQuery("row", 100); 29 | 30 | using var result = await SessionService.GetAsync(query.Build()).ConfigureAwait(false); 31 | if (!result.IsSuccessStatusCode) { 32 | 33 | throw new StatusErrorException(result.StatusCode); 34 | } 35 | 36 | var json = JsonObject.Parse(await result.Content.ReadAsStringAsync().ConfigureAwait(false)); 37 | var data = json.data; 38 | var ret = new List(); 39 | 40 | foreach (var item in data.notifybox_content) { 41 | 42 | if (item == null) { 43 | continue; 44 | } 45 | ret.Add(new OngoingLive { 46 | CommunityName = item.community_name, 47 | ElapsedTime = (int)(item.elapsed_time / 60), 48 | Id = item.id, 49 | ProviderType = item.provider_type, 50 | ThumbnailLinkUrl = item.thumbnail_link_url, 51 | Thumbnailurl = item.thumbnail_url, 52 | Title = item.title 53 | }); 54 | } 55 | 56 | return ret; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Accent/Blue.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Accent/Orange.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Accent/Purple.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Generic.DisabledScrollViewerFlowDocumentScrollViewer.xaml: -------------------------------------------------------------------------------- 1 |  5 | 36 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Generic.HtmlRenderer.xaml: -------------------------------------------------------------------------------- 1 |  6 | 20 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Generic.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Theme.GridSplitter.xaml: -------------------------------------------------------------------------------- 1 |  3 | 15 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Theme.ProgressRing.xaml: -------------------------------------------------------------------------------- 1 |  5 | 12 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Theme.TabView.xaml: -------------------------------------------------------------------------------- 1 |  4 | 7 | 8 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Theme.ToolTip.xaml: -------------------------------------------------------------------------------- 1 |  5 | 31 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Theme.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SRNicoNico/Themes/Theme/Dark.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/Follow/ChannelFollowViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Windows.Input; 3 | using Livet; 4 | using SRNicoNico.Models; 5 | using SRNicoNico.Models.NicoNicoWrapper; 6 | using SRNicoNico.Services; 7 | 8 | namespace SRNicoNico.ViewModels { 9 | /// 10 | /// チャンネルフォローページのViewModel 11 | /// 12 | public class ChannelFollowViewModel : TabItemViewModel { 13 | 14 | /// 15 | /// フォローしているチャンネルのリスト 16 | /// 17 | public ObservableSynchronizedCollection ChannelItems { get; private set; } 18 | 19 | private readonly IUserService UserService; 20 | 21 | public ChannelFollowViewModel(IUserService userService) : base("チャンネル") { 22 | 23 | UserService = userService; 24 | ChannelItems = new ObservableSynchronizedCollection(); 25 | } 26 | 27 | /// 28 | /// フォローしているチャンネルを非同期で取得する 29 | /// 30 | public async void Loaded() { 31 | 32 | IsActive = true; 33 | Status = "フォローしているチャンネルを取得中"; 34 | ChannelItems.Clear(); 35 | try { 36 | 37 | await foreach (var entry in UserService.GetFollowedChannelsAsync()) { 38 | 39 | ChannelItems.Add(entry); 40 | } 41 | 42 | Status = string.Empty; 43 | } catch (StatusErrorException e) { 44 | 45 | Status = $"フォローしているチャンネルを取得出来ませんでした。 ステータスコード: {e.StatusCode}"; 46 | } finally { 47 | 48 | IsActive = false; 49 | } 50 | } 51 | 52 | /// 53 | /// 月額課金額を計算してステータスバーに表示する 54 | /// 55 | public void CalcMonthlyPayment() { 56 | 57 | Status = $"月額{ChannelItems.Where(w => w.IsJoining).Sum(s => s.Price):N0}円 (税抜:{ChannelItems.Where(w => w.IsJoining).Sum(s => s.BodyPrice):N0}円)"; 58 | } 59 | 60 | /// 61 | /// 更新ボタンが押された時に実行される 62 | /// 63 | public void Reload() { 64 | 65 | // 単に再取得するだけ 66 | Loaded(); 67 | } 68 | 69 | public override void KeyDown(KeyEventArgs e) { 70 | 71 | // F5で更新 72 | if (e.Key == Key.F5) { 73 | 74 | Reload(); 75 | e.Handled = true; 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/Follow/CommunityFollowViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | using Livet; 3 | using SRNicoNico.Models; 4 | using SRNicoNico.Models.NicoNicoWrapper; 5 | using SRNicoNico.Services; 6 | 7 | namespace SRNicoNico.ViewModels { 8 | /// 9 | /// コミュニティフォローページのViewModel 10 | /// 11 | public class CommunityFollowViewModel : PageSpinnerViewModel { 12 | 13 | /// 14 | /// フォローしているコミュニティのリスト 15 | /// 16 | public ObservableSynchronizedCollection CommunityItems { get; private set; } 17 | 18 | private readonly IUserService UserService; 19 | 20 | public CommunityFollowViewModel(IUserService userService) : base("コミュニティ", 10) { 21 | 22 | UserService = userService; 23 | CommunityItems = new ObservableSynchronizedCollection(); 24 | } 25 | 26 | /// 27 | /// フォローしているコミュニティを非同期で取得する 28 | /// 29 | public void Loaded() { 30 | 31 | SpinPage(1); 32 | } 33 | 34 | /// 35 | /// 更新ボタンが押された時に実行される 36 | /// 37 | public void Reload() { 38 | 39 | // 単に再取得するだけ 40 | Loaded(); 41 | } 42 | 43 | public override void KeyDown(KeyEventArgs e) { 44 | 45 | // F5で更新 46 | if (e.Key == Key.F5) { 47 | 48 | Reload(); 49 | e.Handled = true; 50 | } 51 | } 52 | 53 | public override async void SpinPage(int page) { 54 | base.SpinPage(page); 55 | 56 | IsActive = true; 57 | Status = "フォローしているコミュニティを取得中"; 58 | CommunityItems.Clear(); 59 | try { 60 | 61 | var result = await UserService.GetFollowedCommunitiesAsync(page, 10); 62 | Total = result.Total; 63 | 64 | foreach (var entry in result.Entries!) { 65 | 66 | CommunityItems.Add(entry); 67 | } 68 | 69 | Status = string.Empty; 70 | } catch (StatusErrorException e) { 71 | 72 | Status = $"フォローしているコミュニティを取得出来ませんでした。 ステータスコード: {e.StatusCode}"; 73 | } finally { 74 | 75 | IsActive = false; 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/Follow/MylistFollowViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | using Livet; 3 | using SRNicoNico.Models; 4 | using SRNicoNico.Models.NicoNicoWrapper; 5 | using SRNicoNico.Services; 6 | 7 | namespace SRNicoNico.ViewModels { 8 | /// 9 | /// マイリストフォローページのViewModel 10 | /// 11 | public class MylistFollowViewModel : TabItemViewModel { 12 | 13 | /// 14 | /// フォローしているマイリストのリスト 15 | /// 16 | public ObservableSynchronizedCollection MylistItems { get; private set; } 17 | 18 | private readonly IUserService UserService; 19 | 20 | public MylistFollowViewModel(IUserService userService) : base("マイリスト") { 21 | 22 | UserService = userService; 23 | MylistItems = new ObservableSynchronizedCollection(); 24 | } 25 | 26 | /// 27 | /// フォローしているマイリストを非同期で取得する 28 | /// 29 | public async void Loaded() { 30 | 31 | IsActive = true; 32 | Status = "フォローしているマイリストを取得中"; 33 | MylistItems.Clear(); 34 | try { 35 | 36 | await foreach (var entry in UserService.GetFollowedMylistsAsync()) { 37 | 38 | MylistItems.Add(entry); 39 | } 40 | 41 | Status = string.Empty; 42 | } catch (StatusErrorException e) { 43 | 44 | Status = $"フォローしているマイリストを取得出来ませんでした。 ステータスコード: {e.StatusCode}"; 45 | } finally { 46 | 47 | IsActive = false; 48 | } 49 | } 50 | 51 | public void Unfollow() { 52 | 53 | 54 | } 55 | 56 | 57 | /// 58 | /// 更新ボタンが押された時に実行される 59 | /// 60 | public void Reload() { 61 | 62 | // 単に再取得するだけ 63 | Loaded(); 64 | } 65 | 66 | public override void KeyDown(KeyEventArgs e) { 67 | 68 | // F5で更新 69 | if (e.Key == Key.F5) { 70 | 71 | Reload(); 72 | e.Handled = true; 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/History/LocalHistoryViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | using Livet; 3 | using SRNicoNico.Entities; 4 | using SRNicoNico.Services; 5 | 6 | namespace SRNicoNico.ViewModels { 7 | /// 8 | /// ローカル視聴履歴ページのViewModel 9 | /// 10 | public class LocalHistoryViewModel : TabItemViewModel { 11 | 12 | /// 13 | /// ローカルの視聴履歴のリスト 14 | /// 15 | public ObservableSynchronizedCollection HistoryItems { get; private set; } 16 | 17 | private readonly IHistoryService HistoryService; 18 | 19 | public LocalHistoryViewModel(IHistoryService historyService) : base("ローカル") { 20 | 21 | HistoryService = historyService; 22 | HistoryItems = new ObservableSynchronizedCollection(); 23 | } 24 | 25 | /// 26 | /// 視聴履歴を非同期で取得する 27 | /// 28 | public async void Loaded() { 29 | 30 | IsActive = true; 31 | Status = "ローカルの視聴履歴を取得中"; 32 | HistoryItems.Clear(); 33 | 34 | // 視聴履歴を取得する 35 | await foreach (var entry in HistoryService.GetLocalHistoryAsync()) { 36 | 37 | HistoryItems.Add(entry); 38 | } 39 | 40 | Status = string.Empty; 41 | IsActive = false; 42 | } 43 | 44 | /// 45 | /// ローカルの視聴履歴を削除する 46 | /// 47 | /// 削除したい動画 48 | public async void DeleteLocalHistory(LocalHistory entry) { 49 | 50 | Status = $"{entry.VideoId}の視聴履歴を削除中"; 51 | 52 | if (await HistoryService.DeleteLocalHistoryAsync(entry.VideoId!)) { 53 | 54 | HistoryItems.Remove(entry); 55 | Status = $"{entry.VideoId}の視聴履歴を削除しました"; 56 | } else { 57 | 58 | Status = $"{entry.VideoId}の視聴履歴の削除に失敗しました"; 59 | } 60 | } 61 | 62 | /// 63 | /// 更新ボタンが押された時に実行される 64 | /// 65 | public void Reload() { 66 | 67 | // 単に再取得するだけ 68 | Loaded(); 69 | } 70 | 71 | public override void KeyDown(KeyEventArgs e) { 72 | 73 | // F5で更新 74 | if (e.Key == Key.F5) { 75 | 76 | Reload(); 77 | e.Handled = true; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/Misc/StartViewModel.cs: -------------------------------------------------------------------------------- 1 | using SRNicoNico.Models; 2 | 3 | namespace SRNicoNico.ViewModels { 4 | /// 5 | /// スタートページクラスのDataContext 6 | /// 7 | public class StartViewModel : TabItemViewModel { 8 | 9 | /// 10 | /// 現在のNicoNicoViewerのバージョン 11 | /// 12 | public double CurrentVersion { get; private set; } 13 | 14 | public StartViewModel(INicoNicoViewer vm) : base("スタート") { 15 | 16 | CurrentVersion = vm.CurrentVersion; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/NicoRepo/NicoRepoListAllViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SRNicoNico.Services; 3 | 4 | namespace SRNicoNico.ViewModels { 5 | /// 6 | /// ニコレポの「すべて」タブ 7 | /// 8 | public class NicoRepoListAllViewModel : NicoRepoListViewModel { 9 | 10 | /// 11 | public override NicoRepoType NicoRepoType => NicoRepoType.All; 12 | 13 | /// 14 | public override IEnumerable FilterItems => FilterAll; 15 | 16 | public NicoRepoListAllViewModel(INicoRepoService nicorepoService) : base(nicorepoService, "すべて") { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/NicoRepo/NicoRepoListChannelViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SRNicoNico.Services; 3 | 4 | namespace SRNicoNico.ViewModels { 5 | /// 6 | /// ニコレポの「チャンネル」タブ 7 | /// 8 | public class NicoRepoListChannelViewModel : NicoRepoListViewModel { 9 | 10 | /// 11 | public override NicoRepoType NicoRepoType => NicoRepoType.Channel; 12 | 13 | /// 14 | public override IEnumerable FilterItems => FilterAll; 15 | 16 | public NicoRepoListChannelViewModel(INicoRepoService nicorepoService) : base(nicorepoService, "チャンネル") { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/NicoRepo/NicoRepoListCommunityViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SRNicoNico.Services; 3 | 4 | namespace SRNicoNico.ViewModels { 5 | /// 6 | /// ニコレポの「コミュニティ」タブ 7 | /// 8 | public class NicoRepoListCommunityViewModel : NicoRepoListViewModel { 9 | 10 | /// 11 | public override NicoRepoType NicoRepoType => NicoRepoType.Community; 12 | 13 | /// 14 | public override IEnumerable FilterItems => FilterAll; 15 | 16 | public NicoRepoListCommunityViewModel(INicoRepoService nicorepoService) : base(nicorepoService, "コミュニティ") { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/NicoRepo/NicoRepoListMylistViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SRNicoNico.Services; 3 | 4 | namespace SRNicoNico.ViewModels { 5 | /// 6 | /// ニコレポの「マイリスト」タブ 7 | /// 8 | public class NicoRepoListMylistViewModel : NicoRepoListViewModel { 9 | 10 | /// 11 | public override NicoRepoType NicoRepoType => NicoRepoType.Mylist; 12 | 13 | /// 14 | public override IEnumerable FilterItems => FilterOnlyAll; 15 | 16 | public NicoRepoListMylistViewModel(INicoRepoService nicorepoService) : base(nicorepoService, "マイリスト") { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/NicoRepo/NicoRepoListSelfViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SRNicoNico.Services; 3 | 4 | namespace SRNicoNico.ViewModels { 5 | /// 6 | /// ニコレポの「自分」タブ 7 | /// 8 | public class NicoRepoListSelfViewModel : NicoRepoListViewModel { 9 | 10 | /// 11 | public override NicoRepoType NicoRepoType => NicoRepoType.Self; 12 | 13 | /// 14 | public override IEnumerable FilterItems => FilterOnlyAll; 15 | 16 | public NicoRepoListSelfViewModel(INicoRepoService nicorepoService) : base(nicorepoService, "自分") { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/NicoRepo/NicoRepoListUserViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SRNicoNico.Services; 3 | 4 | namespace SRNicoNico.ViewModels { 5 | /// 6 | /// ニコレポの「ユーザー」タブ 7 | /// 8 | public class NicoRepoListUserViewModel : NicoRepoListViewModel { 9 | 10 | /// 11 | public override NicoRepoType NicoRepoType => NicoRepoType.User; 12 | 13 | /// 14 | public override IEnumerable FilterItems => FilterAll; 15 | 16 | public NicoRepoListUserViewModel(INicoRepoService nicorepoService) : base(nicorepoService, "ユーザー") { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/Other/OpenSourceViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace SRNicoNico.ViewModels { 2 | /// 3 | /// その他ページのオープンソースソフトウェアタブのViewModel 4 | /// 5 | public class OpenSourceViewModel : TabItemViewModel { 6 | 7 | public OpenSourceViewModel() : base("オープンソースソフトウェア") { 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/Other/OverviewViewModel.cs: -------------------------------------------------------------------------------- 1 | using Unity; 2 | 3 | namespace SRNicoNico.ViewModels { 4 | /// 5 | /// その他ページのアプリ説明タブのViewModel 6 | /// 7 | public class OverviewViewModel : TabItemViewModel { 8 | 9 | public OverviewViewModel() : base("このソフトウェアについて") { 10 | 11 | } 12 | 13 | /// 14 | /// NicoNicoViewerのアップデートを確認する 15 | /// 16 | public void CheckUpdate() { 17 | 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/Other/PrivacyPolicyViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace SRNicoNico.ViewModels { 2 | /// 3 | /// その他ページのプライバシーポリシータブのViewModel 4 | /// 5 | public class PrivacyPolicyViewModel : TabItemViewModel { 6 | 7 | public PrivacyPolicyViewModel() : base("プライバシーポリシー") { 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/Settings/SettingsCommentViewModel.cs: -------------------------------------------------------------------------------- 1 | using SRNicoNico.Models; 2 | 3 | namespace SRNicoNico.ViewModels { 4 | /// 5 | /// 設定ページのコメントタブのViewModel 6 | /// 7 | public class SettingsCommentViewModel : TabItemViewModel { 8 | 9 | /// 10 | /// かんたんコメントを無効にするかどうか 11 | /// 12 | public bool DisableEasyComment { 13 | get { return Settings.DisableEasyComment; } 14 | set { 15 | if (Settings.DisableEasyComment == value) 16 | return; 17 | Settings.DisableEasyComment = value; 18 | RaisePropertyChanged(); 19 | } 20 | } 21 | 22 | private readonly ISettings Settings; 23 | 24 | public SettingsCommentViewModel(ISettings settings) : base("コメント設定") { 25 | 26 | Settings = settings; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/Settings/SettingsLiveViewModel.cs: -------------------------------------------------------------------------------- 1 | using SRNicoNico.Models; 2 | 3 | namespace SRNicoNico.ViewModels { 4 | /// 5 | /// 設定ページの生放送タブのViewModel 6 | /// 7 | public class SettingsLiveViewModel : TabItemViewModel { 8 | 9 | /// 10 | /// 生放送更新通知間隔 11 | /// 12 | public int RefreshInterval { 13 | get { return Settings.LiveNotifyRefreshInterval; } 14 | set { 15 | if (Settings.LiveNotifyRefreshInterval == value) 16 | return; 17 | // 0は拒否する 18 | if (value == 0) { 19 | value = 5; 20 | } 21 | Settings.LiveNotifyRefreshInterval = value; 22 | MainContent.LiveNotify!.UpdateInterval(); 23 | RaisePropertyChanged(); 24 | } 25 | } 26 | 27 | private readonly ISettings Settings; 28 | private readonly MainContentViewModel MainContent; 29 | 30 | public SettingsLiveViewModel(ISettings settings, MainContentViewModel mainContent) : base("生放送設定") { 31 | 32 | Settings = settings; 33 | MainContent = mainContent; 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/User/UserMylistViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | using Livet; 3 | using SRNicoNico.Models; 4 | using SRNicoNico.Models.NicoNicoWrapper; 5 | using SRNicoNico.Services; 6 | 7 | namespace SRNicoNico.ViewModels { 8 | /// 9 | /// ユーザーページの公開マイリストのViewModel 10 | /// 11 | public class UserMylistViewModel : TabItemViewModel { 12 | 13 | private ObservableSynchronizedCollection _MylistItems = new ObservableSynchronizedCollection(); 14 | /// 15 | /// マイリスト一覧 16 | /// 17 | public ObservableSynchronizedCollection MylistItems { 18 | get { return _MylistItems; } 19 | set { 20 | if (_MylistItems == value) 21 | return; 22 | _MylistItems = value; 23 | RaisePropertyChanged(); 24 | } 25 | } 26 | 27 | private readonly IMylistService MylistService; 28 | private readonly string UserId; 29 | 30 | public UserMylistViewModel(IMylistService mylistService, string userId) : base("マイリスト") { 31 | 32 | MylistService = mylistService; 33 | UserId = userId; 34 | } 35 | 36 | public async void Loaded() { 37 | 38 | IsActive = true; 39 | Status = "マイリストを取得中"; 40 | MylistItems.Clear(); 41 | try { 42 | 43 | await foreach (var mylist in MylistService.GetUserPublicMylistAsync(UserId, 3)) { 44 | // 改行をスペースに置換する 45 | mylist.Description = mylist.Description!.Replace("\r\n", " "); 46 | MylistItems.Add(mylist); 47 | } 48 | 49 | Status = string.Empty; 50 | } catch (StatusErrorException e) { 51 | 52 | Status = $"マイリストを取得出来ませんでした。 ステータスコード: {e.StatusCode}"; 53 | } finally { 54 | 55 | IsActive = false; 56 | } 57 | } 58 | 59 | /// 60 | /// 再読み込み 61 | /// 62 | public void Reload() { 63 | 64 | Loaded(); 65 | } 66 | 67 | public override void KeyDown(KeyEventArgs e) { 68 | 69 | // F5で更新 70 | if (e.Key == Key.F5) { 71 | 72 | Reload(); 73 | e.Handled = true; 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /SRNicoNico/ViewModels/User/UserSeriesViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | using SRNicoNico.Models; 3 | using SRNicoNico.Models.NicoNicoWrapper; 4 | using SRNicoNico.Services; 5 | 6 | namespace SRNicoNico.ViewModels { 7 | /// 8 | /// ユーザーページのシリーズのViewModel 9 | /// 10 | public class UserSeriesViewModel : PageSpinnerViewModel { 11 | 12 | private SeriesList? _SeriesList; 13 | /// 14 | /// シリーズ情報 15 | /// 16 | public SeriesList? SeriesList { 17 | get { return _SeriesList; } 18 | set { 19 | if (_SeriesList == value) 20 | return; 21 | _SeriesList = value; 22 | RaisePropertyChanged(); 23 | } 24 | } 25 | 26 | private readonly ISeriesService SeriesService; 27 | private readonly string UserId; 28 | 29 | public UserSeriesViewModel(ISeriesService seriesService, string userId) : base("シリーズ", 100) { 30 | 31 | SeriesService = seriesService; 32 | UserId = userId; 33 | } 34 | 35 | public void Loaded() { 36 | 37 | SpinPage(1); 38 | } 39 | 40 | public override async void SpinPage(int page) { 41 | base.SpinPage(page); 42 | 43 | IsActive = true; 44 | Status = "シリーズを取得中"; 45 | try { 46 | SeriesList = await SeriesService.GetUserSeriesAsync(UserId, page); 47 | Total = SeriesList.TotalCount; 48 | 49 | Status = string.Empty; 50 | } catch (StatusErrorException e) { 51 | 52 | Status = $"シリーズを取得出来ませんでした。 ステータスコード: {e.StatusCode}"; 53 | } finally { 54 | 55 | IsActive = false; 56 | } 57 | } 58 | 59 | /// 60 | /// 再読み込み 61 | /// 62 | public void Reload() { 63 | 64 | Loaded(); 65 | } 66 | 67 | public override void KeyDown(KeyEventArgs e) { 68 | 69 | // F5で更新 70 | if (e.Key == Key.F5) { 71 | 72 | Reload(); 73 | e.Handled = true; 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Actions/AddWatchLaterAction.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using Microsoft.Xaml.Behaviors; 3 | using SRNicoNico.Models; 4 | using SRNicoNico.Services; 5 | using SRNicoNico.ViewModels; 6 | using Unity; 7 | 8 | namespace SRNicoNico.Views.Actions { 9 | /// 10 | /// Viewからあとで見るに登録を行うトリガーアクション 11 | /// 12 | public class AddWatchLaterAction : TriggerAction { 13 | 14 | /// 15 | /// URL本体 16 | /// 17 | public string WatchId { 18 | get { return (string)GetValue(WatchIdProperty); } 19 | set { SetValue(WatchIdProperty, value); } 20 | } 21 | public static readonly DependencyProperty WatchIdProperty = 22 | DependencyProperty.Register(nameof(WatchId), typeof(string), typeof(AddWatchLaterAction), new PropertyMetadata("")); 23 | 24 | protected async override void Invoke(object parameter) { 25 | 26 | if (string.IsNullOrEmpty(WatchId)) { 27 | 28 | return; 29 | } 30 | 31 | var mylistService = App.UnityContainer!.Resolve(); 32 | var vm = App.UnityContainer!.Resolve(); 33 | 34 | vm.Status = "あとで見るに登録中"; 35 | try { 36 | 37 | var result = await mylistService.AddWatchLaterAsync(WatchId, null); 38 | if (result) { 39 | vm.Status = "あとで見るに登録しました"; 40 | } else { 41 | vm.Status = "すでに登録済みです"; 42 | } 43 | 44 | } catch (StatusErrorException e) { 45 | vm.Status = $"あとで見るに動画を登録出来ませんでした。 ステータスコード: {e.StatusCode}"; 46 | return; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Actions/CopyToClipBoardAction.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using Microsoft.Xaml.Behaviors; 3 | 4 | namespace SRNicoNico.Views.Actions { 5 | /// 6 | /// 指定したテキストをクリップボードにコピーするトリガーアクション 7 | /// 8 | public class CopyToClipBoardAction : TriggerAction { 9 | /// 10 | /// コピーしたいテキスト 11 | /// 12 | public string Text { 13 | get { return (string)GetValue(TextProperty); } 14 | set { SetValue(TextProperty, value); } 15 | } 16 | public static readonly DependencyProperty TextProperty = 17 | DependencyProperty.Register(nameof(Text), typeof(string), typeof(CopyToClipBoardAction), new PropertyMetadata("")); 18 | 19 | protected override void Invoke(object parameter) { 20 | 21 | Clipboard.SetText(Text); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Actions/MouseMiddleClickTrigger.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Input; 3 | using Microsoft.Xaml.Behaviors; 4 | 5 | namespace SRNicoNico.Views.Actions { 6 | /// 7 | /// マウスの中クリックが押された時にアクションを発火するトリガー 8 | /// 9 | public class MouseMiddleClickTrigger : TriggerBase { 10 | 11 | protected override void OnAttached() { 12 | 13 | AssociatedObject.MouseUp += AssociatedObject_MouseUp; 14 | } 15 | 16 | private void AssociatedObject_MouseUp(object sender, MouseButtonEventArgs e) { 17 | 18 | if (e.ChangedButton == MouseButton.Middle && e.MiddleButton == MouseButtonState.Released) { 19 | 20 | InvokeActions(e); 21 | } 22 | } 23 | 24 | protected override void OnDetaching() { 25 | AssociatedObject.MouseUp -= AssociatedObject_MouseUp; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Actions/MuteAccountAction.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using Microsoft.Xaml.Behaviors; 3 | using SRNicoNico.Entities; 4 | using SRNicoNico.Models.NicoNicoWrapper; 5 | using SRNicoNico.Services; 6 | using SRNicoNico.ViewModels; 7 | using Unity; 8 | 9 | namespace SRNicoNico.Views.Actions { 10 | /// 11 | /// 対象の動画を投稿したアカウントをミュートするトリガーアクション 12 | /// 13 | public class MuteAccountAction : TriggerAction { 14 | 15 | /// 16 | /// VideoItem本体 17 | /// 18 | public VideoItem Item { 19 | get { return (VideoItem)GetValue(WatchIdProperty); } 20 | set { SetValue(WatchIdProperty, value); } 21 | } 22 | public static readonly DependencyProperty WatchIdProperty = 23 | DependencyProperty.Register(nameof(Item), typeof(VideoItem), typeof(MuteAccountAction), new FrameworkPropertyMetadata(null)); 24 | 25 | protected async override void Invoke(object parameter) { 26 | 27 | if (Item == null || Item.OwnerType == null) { 28 | return; 29 | } 30 | 31 | var accountService = App.UnityContainer!.Resolve(); 32 | var vm = App.UnityContainer!.Resolve(); 33 | 34 | if (Item.OwnerType == "user") { 35 | 36 | await accountService.AddMutedAccountAsync(AccountType.User, Item.OwnerId!); 37 | } else if (Item.OwnerType == "channel") { 38 | 39 | await accountService.AddMutedAccountAsync(AccountType.Channel, Item.OwnerId!); 40 | } else if (Item.OwnerType == "community") { 41 | 42 | await accountService.AddMutedAccountAsync(AccountType.Community, Item.OwnerId!); 43 | } else { 44 | return; 45 | } 46 | 47 | Item.IsMuted = true; 48 | vm.Status = "ミュート設定に登録しました"; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Actions/NicoNicoOpenAction.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using Microsoft.Xaml.Behaviors; 3 | using SRNicoNico.Models; 4 | using Unity; 5 | 6 | namespace SRNicoNico.Views.Actions { 7 | /// 8 | /// Viewから各ニコニコのリンクを開くトリガーアクション 9 | /// 10 | public class NicoNicoOpenAction : TriggerAction { 11 | 12 | /// 13 | /// URL本体 14 | /// 15 | public string Url { 16 | get { return (string)GetValue(UrlProperty); } 17 | set { SetValue(UrlProperty, value); } 18 | } 19 | public static readonly DependencyProperty UrlProperty = 20 | DependencyProperty.Register(nameof(Url), typeof(string), typeof(NicoNicoOpenAction), new PropertyMetadata("")); 21 | 22 | protected override void Invoke(object parameter) { 23 | 24 | var nnv = App.UnityContainer!.Resolve(); 25 | 26 | // URLを最適なUIで開く 27 | nnv.OpenUrl(Url); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Actions/WebViewOpenAction.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using Microsoft.Xaml.Behaviors; 3 | using SRNicoNico.ViewModels; 4 | 5 | namespace SRNicoNico.Views.Actions { 6 | /// 7 | /// 指定したURLをWebViewで開くトリガーアクション 8 | /// 9 | public class WebViewOpenAction : TriggerAction { 10 | /// 11 | /// URL本体 12 | /// 13 | public string Url { 14 | get { return (string)GetValue(UrlProperty); } 15 | set { SetValue(UrlProperty, value); } 16 | } 17 | public static readonly DependencyProperty UrlProperty = 18 | DependencyProperty.Register(nameof(Url), typeof(string), typeof(WebViewOpenAction), new PropertyMetadata("")); 19 | 20 | protected override void Invoke(object parameter) { 21 | 22 | // MainWindowからMainWindowViewModelを経由してWebViewを開くようにする 23 | if (!string.IsNullOrEmpty(Url) && Application.Current.MainWindow.DataContext is MainWindowViewModel vm) { 24 | 25 | vm.MainContent.WebView?.AddTab(Url, false); 26 | // WebViewをActiveにする 27 | vm.MainContent.SelectedItem = vm.MainContent.WebView; 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Behaviors/CommentAutoScrollBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | using Microsoft.Xaml.Behaviors; 6 | using SRNicoNico.Models.NicoNicoWrapper; 7 | 8 | namespace SRNicoNico.Views.Behaviors { 9 | /// 10 | /// コメントリストを自動スクロールするビヘイビア 11 | /// 12 | public class CommentAutoScrollBehavior : Behavior { 13 | 14 | /// 15 | /// オートスクロールの有効状態 16 | /// 17 | public bool AutoScrollEnabled { 18 | get => (bool)GetValue(AutoScrollEnabledProperty); 19 | set => SetValue(AutoScrollEnabledProperty, value); 20 | } 21 | public static readonly DependencyProperty AutoScrollEnabledProperty = 22 | DependencyProperty.Register(nameof(AutoScrollEnabled), typeof(bool), typeof(CommentAutoScrollBehavior), new FrameworkPropertyMetadata(true)); 23 | 24 | /// 25 | /// 現在再生時間 26 | /// 27 | public double CurrentTime { 28 | get => (double)GetValue(CurrentTimeProperty); 29 | set => SetValue(CurrentTimeProperty, value); 30 | } 31 | public static readonly DependencyProperty CurrentTimeProperty = 32 | DependencyProperty.Register(nameof(CurrentTime), typeof(double), typeof(CommentAutoScrollBehavior), new FrameworkPropertyMetadata(0D, (o, e) => { 33 | 34 | var behavior = (CommentAutoScrollBehavior)o; 35 | behavior.CurrentTimeChanged((double)e.NewValue); 36 | })); 37 | 38 | private void CurrentTimeChanged(double value) { 39 | 40 | // オートスクロールが無効、コメント欄にマウスカーソルが乗っている、コメントが0件の時は何もしない 41 | if (!AutoScrollEnabled || AssociatedObject.IsMouseOver || AssociatedObject.Items.IsEmpty) { 42 | return; 43 | } 44 | 45 | if (!(AssociatedObject.ItemsSource is IEnumerable items)) { 46 | return; 47 | } 48 | 49 | var comment = items.LastOrDefault(w => w.Vpos <= (int)(value * 100)); 50 | if (comment != null) { 51 | AssociatedObject.ScrollIntoView(comment); 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Behaviors/ParagraphHtmlRenderingBehavior.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Windows; 5 | using System.Windows.Documents; 6 | using SRNicoNico.Views.Converters; 7 | 8 | namespace SRNicoNico.Views.Behaviors { 9 | /// 10 | /// ParagraphにHTMLをロードする添付プロパティを提供する 11 | /// 12 | public static class ParagraphHtmlRenderingBehavior { 13 | 14 | public static string GetRawHtmlText(Paragraph wb) { 15 | return (string)wb.GetValue(RawHtmlTextProperty); 16 | } 17 | public static void SetRawHtmlText(Paragraph wb, string html) { 18 | wb.SetValue(RawHtmlTextProperty, html); 19 | } 20 | public static readonly DependencyProperty RawHtmlTextProperty = 21 | DependencyProperty.RegisterAttached("RawHtmlText", typeof(string), typeof(ParagraphHtmlRenderingBehavior), new FrameworkPropertyMetadata("", OnHtmlTextChanged)); 22 | 23 | 24 | private static void OnHtmlTextChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e) { 25 | 26 | if (!(depObj is Paragraph txtBox)) { 27 | return; 28 | } 29 | if (!(e.NewValue is string html)) { 30 | return; 31 | } 32 | 33 | string xaml; 34 | InlineCollection xamLines; 35 | try { 36 | 37 | xaml = HtmlToXamlConverter.ConvertHtmlToXaml(html, false); 38 | xamLines = ((Paragraph)((Section)System.Windows.Markup.XamlReader.Parse(xaml)).Blocks.FirstBlock).Inlines; 39 | 40 | } catch { 41 | return; 42 | } 43 | var newLines = new Inline[xamLines.Count]; 44 | xamLines.CopyTo(newLines, 0); 45 | 46 | txtBox.Inlines.Clear(); 47 | foreach (var l in newLines) { 48 | 49 | txtBox.Inlines.Add(l); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Behaviors/SearchRadioButtonBehavior.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | using Microsoft.Xaml.Behaviors; 5 | using SRNicoNico.Models.NicoNicoWrapper; 6 | 7 | namespace SRNicoNico.Views.Behaviors { 8 | /// 9 | /// ラジオボタンにチェックを入れるBehavior 10 | /// 11 | public class SearchRadioButtonBehavior : Behavior { 12 | 13 | protected override void OnAttached() { 14 | 15 | AssociatedObject.Loaded += AssociatedObject_Loaded; 16 | } 17 | 18 | private void AssociatedObject_Loaded(object sender, RoutedEventArgs e) { 19 | 20 | if (AssociatedObject.DataContext is SearchGenreFacet facet) { 21 | // allだったらLoadedイベント時にチェックを入れる 22 | if (facet.Key == "all") { 23 | AssociatedObject.IsChecked = true; 24 | } 25 | } 26 | } 27 | 28 | protected override void OnDetaching() { 29 | 30 | AssociatedObject.Loaded -= AssociatedObject_Loaded; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Behaviors/TextBlockHtmlRenderingBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Documents; 4 | using SRNicoNico.Views.Converters; 5 | 6 | namespace SRNicoNico.Views.Behaviors { 7 | /// 8 | /// TextBlock用htmlレンダリング用の添付プロパティを提供する 9 | /// 10 | public static class TextBlockHtmlRenderingBehavior { 11 | 12 | public static string GetHtmlText(TextBlock wb) { 13 | return (string)wb.GetValue(HtmlTextProperty); 14 | } 15 | public static void SetHtmlText(TextBlock wb, string html) { 16 | wb.SetValue(HtmlTextProperty, html); 17 | } 18 | public static readonly DependencyProperty HtmlTextProperty = 19 | DependencyProperty.RegisterAttached("HtmlText", typeof(string), typeof(TextBlockHtmlRenderingBehavior), new FrameworkPropertyMetadata(string.Empty, OnHtmlTextChanged)); 20 | 21 | 22 | private static void OnHtmlTextChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e) { 23 | 24 | if (!(depObj is TextBlock txtBox)) { 25 | return; 26 | } 27 | if (!(e.NewValue is string)) { 28 | return; 29 | } 30 | var html = e.NewValue as string; 31 | string xaml; 32 | InlineCollection xamLines; 33 | 34 | try { 35 | 36 | xaml = HtmlToXamlConverter.ConvertHtmlToXaml(html, false); 37 | xamLines = ((Paragraph)((Section)System.Windows.Markup.XamlReader.Parse(xaml)).Blocks.FirstBlock).Inlines; 38 | 39 | } catch { 40 | return; 41 | } 42 | 43 | var newLines = new Inline[xamLines.Count]; 44 | xamLines.CopyTo(newLines, 0); 45 | 46 | txtBox.Inlines.Clear(); 47 | foreach (var l in newLines) { 48 | txtBox.Inlines.Add(l); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Behaviors/TextBlockHyperlinkBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using System.Windows; 3 | using System.Windows.Documents; 4 | using System.Windows.Navigation; 5 | using Microsoft.Xaml.Behaviors; 6 | using SRNicoNico.Models; 7 | using Unity; 8 | 9 | namespace SRNicoNico.Views.Behaviors { 10 | /// 11 | /// TextBlockのハイパーリンクを動作するようにするBehavior 12 | /// 13 | public class TextBlockHyperlinkBehavior : Behavior { 14 | 15 | /// 16 | /// ブラウザで開くことを強制するかどうか 17 | /// 18 | public bool ForceOpenWithBrowser { 19 | get { return (bool)GetValue(ForceOpenWithBrowserProperty); } 20 | set { SetValue(ForceOpenWithBrowserProperty, value); } 21 | } 22 | public static readonly DependencyProperty ForceOpenWithBrowserProperty = 23 | DependencyProperty.Register("ForceOpenWithBrowser", typeof(bool), typeof(TextBlockHyperlinkBehavior), new PropertyMetadata(false)); 24 | 25 | 26 | 27 | protected override void OnAttached() { 28 | 29 | base.OnAttached(); 30 | 31 | // ツリー配下のHyperlinkにイベントを設定する 32 | var style = new Style { TargetType = typeof(Hyperlink) }; 33 | style.Setters.Add(new EventSetter(Hyperlink.RequestNavigateEvent, new RequestNavigateEventHandler(RequestNavigate))); 34 | style.Setters.Add(new EventSetter(FrameworkContentElement.LoadedEvent, new RoutedEventHandler(Loaded))); 35 | AssociatedObject.Resources.Add(typeof(Hyperlink), style); 36 | } 37 | 38 | private void RequestNavigate(object sender, RequestNavigateEventArgs e) { 39 | 40 | if (ForceOpenWithBrowser) { 41 | // ダウンロードリンクをデフォルトブラウザで開く 42 | Process.Start(new ProcessStartInfo { 43 | UseShellExecute = true, 44 | FileName = e.Uri.OriginalString 45 | }); 46 | return; 47 | } 48 | 49 | var nnv = App.UnityContainer!.Resolve(); 50 | // URLを最適なUIで開く 51 | nnv.OpenUrl(e.Uri.OriginalString); 52 | } 53 | 54 | private void Loaded(object sender, RoutedEventArgs e) { 55 | 56 | var hyperlink = (Hyperlink)sender; 57 | hyperlink.ToolTip = hyperlink.NavigateUri.OriginalString; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Behaviors/TextBoxNumericOnlyBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | using System.Windows.Input; 3 | using Microsoft.Xaml.Behaviors; 4 | 5 | namespace SRNicoNico.Views.Behaviors { 6 | /// 7 | /// TextBoxに数字以外入力出来なくするBehavior 8 | /// 9 | public class TextBoxNumericOnlyBehavior : Behavior { 10 | 11 | protected override void OnAttached() { 12 | 13 | base.OnAttached(); 14 | AssociatedObject.KeyDown += AssociatedObject_KeyDown; 15 | 16 | } 17 | 18 | private void AssociatedObject_KeyDown(object sender, KeyEventArgs e) { 19 | 20 | // 数字キー以外入力を拒否する 21 | if ((Key.D0 <= e.Key && e.Key <= Key.D9) || (Key.NumPad0 <= e.Key && e.Key <= Key.NumPad9) || (Key.Delete == e.Key) || (Key.Back == e.Key) || (Key.Tab == e.Key) || (Key.Enter == e.Key)) { 22 | 23 | e.Handled = false; 24 | } else { 25 | 26 | e.Handled = true; 27 | } 28 | } 29 | 30 | protected override void OnDetaching() { 31 | 32 | base.OnDetaching(); 33 | AssociatedObject.KeyDown -= AssociatedObject_KeyDown; 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Behaviors/WebViewNavigationBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.Web.WebView2.Core; 3 | using Microsoft.Web.WebView2.Wpf; 4 | using Microsoft.Xaml.Behaviors; 5 | 6 | namespace SRNicoNico.Views.Behaviors { 7 | /// 8 | /// 初期URL以外に遷移しようとした時にブラウザでリンクを開くようにするBehavior 9 | /// 10 | public class WebViewNavigationBehavior : Behavior { 11 | protected async override void OnAttached() { 12 | 13 | await AssociatedObject.EnsureCoreWebView2Async(); 14 | AssociatedObject.CoreWebView2.NavigationStarting += AssociatedObject_NavigationStarting; 15 | AssociatedObject.CoreWebView2.ProcessFailed += CoreWebView2_ProcessFailed; 16 | } 17 | 18 | 19 | protected override void OnDetaching() { 20 | 21 | AssociatedObject.CoreWebView2.NavigationStarting -= AssociatedObject_NavigationStarting; 22 | AssociatedObject.CoreWebView2.ProcessFailed -= CoreWebView2_ProcessFailed; 23 | } 24 | 25 | private void CoreWebView2_ProcessFailed(object? sender, CoreWebView2ProcessFailedEventArgs e) { 26 | 27 | // クラッシュしないようにイベントを登録だけしておく 28 | } 29 | 30 | 31 | private void AssociatedObject_NavigationStarting(object? sender, CoreWebView2NavigationStartingEventArgs e) { 32 | 33 | if (e.Uri == AssociatedObject.Source.OriginalString) { 34 | 35 | return; 36 | } 37 | Process.Start(new ProcessStartInfo(e.Uri) { UseShellExecute = true }); 38 | e.Cancel = true; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Behaviors/WindowInputEventBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Input; 3 | using Microsoft.Xaml.Behaviors; 4 | using SRNicoNico.ViewModels; 5 | 6 | namespace SRNicoNico.Views.Behaviors { 7 | /// 8 | /// ウィンドウのインプット系のイベントをフックしてViewModelに転送する 9 | /// 10 | public class WindowInputEventBehavior : Behavior { 11 | 12 | protected override void OnAttached() { 13 | 14 | AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown; 15 | AssociatedObject.PreviewKeyUp += AssociatedObject_PreviewKeyUp; 16 | AssociatedObject.PreviewMouseDown += AssociatedObject_PreviewMouseDown; 17 | } 18 | 19 | protected override void OnDetaching() { 20 | 21 | AssociatedObject.PreviewKeyDown -= AssociatedObject_PreviewKeyDown; 22 | AssociatedObject.PreviewKeyUp -= AssociatedObject_PreviewKeyUp; 23 | AssociatedObject.PreviewMouseDown -= AssociatedObject_PreviewMouseDown; 24 | } 25 | private void AssociatedObject_PreviewKeyDown(object sender, KeyEventArgs e) { 26 | 27 | if (AssociatedObject.DataContext is MainWindowViewModel vm) { 28 | 29 | vm.KeyDown(e); 30 | } 31 | } 32 | 33 | private void AssociatedObject_PreviewKeyUp(object sender, KeyEventArgs e) { 34 | 35 | if (AssociatedObject.DataContext is MainWindowViewModel vm) { 36 | 37 | vm.KeyUp(e); 38 | } 39 | } 40 | 41 | private void AssociatedObject_PreviewMouseDown(object sender, MouseButtonEventArgs e) { 42 | 43 | if (AssociatedObject.DataContext is MainWindowViewModel vm) { 44 | 45 | vm.MouseDown(e); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/ChannelEntryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class ChannelEntryView : UserControl { 5 | public ChannelEntryView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/ChannelFollow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class ChannelFollow : UserControl { 5 | public ChannelFollow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/CommunityEntryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class CommunityEntryView : UserControl { 5 | public CommunityEntryView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/CommunityFollow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class CommunityFollow : UserControl { 5 | public CommunityFollow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/Follow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Follow : UserControl { 5 | public Follow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/MylistEntryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class MylistEntryView : UserControl { 5 | public MylistEntryView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/MylistFollow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class MylistFollow : UserControl { 5 | public MylistFollow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/TagEntryView.xaml: -------------------------------------------------------------------------------- 1 |  13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/TagEntryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class TagEntryView : UserControl { 5 | public TagEntryView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/TagFollow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class TagFollow : UserControl { 5 | public TagFollow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/UserEntryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserEntryView : UserControl { 5 | public UserEntryView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Follow/UserFollow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserFollow : UserControl { 5 | public UserFollow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/History/AccountHistory.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class AccountHistory : UserControl { 5 | public AccountHistory() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/History/History.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class History : UserControl { 5 | public History() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/History/HistoryEntryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class HistoryEntryView : UserControl { 5 | public HistoryEntryView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/History/LocalHistory.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class LocalHistory : UserControl { 5 | public LocalHistory() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/History/LocalHistoryEntryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class LocalHistoryEntryView : UserControl { 5 | public LocalHistoryEntryView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Live/LiveNotify.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class LiveNotify : UserControl { 5 | public LiveNotify() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/MainContent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class MainContent : UserControl { 5 | public MainContent() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Misc/CrashReportWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using MetroRadiance.UI.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class CrashReportWindow : MetroWindow { 5 | public CrashReportWindow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Misc/ExitConfirmWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using MetroRadiance.UI.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class ExitConfirmWindow : MetroWindow { 5 | public ExitConfirmWindow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Misc/Start.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Start : UserControl { 5 | public Start() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Misc/WebViewInstallWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using MetroRadiance.UI.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class WebViewInstallWindow : MetroWindow { 5 | public WebViewInstallWindow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Mylist/CreateMylistWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using MetroRadiance.UI.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class CreateMylistWindow : MetroWindow { 5 | public CreateMylistWindow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Mylist/Mylist.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Mylist : UserControl { 5 | public Mylist() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Mylist/MylistResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class MylistResult : UserControl { 5 | public MylistResult() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Mylist/PublicMylist.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class PublicMylist : UserControl { 5 | public PublicMylist() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/NicoRepo/NicoRepo.xaml: -------------------------------------------------------------------------------- 1 |  14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/NicoRepo/NicoRepo.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class NicoRepo : UserControl { 5 | public NicoRepo() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/NicoRepo/NicoRepoEntryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class NicoRepoEntryView : UserControl { 5 | public NicoRepoEntryView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/NicoRepo/NicoRepoResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class NicoRepoResult : UserControl { 5 | public NicoRepoResult() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Other/OpenSource.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class OpenSource : UserControl { 5 | public OpenSource() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Other/Other.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Other : UserControl { 5 | public Other() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Other/Overview.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Overview : UserControl { 5 | public Overview() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Other/PrivacyPolicy.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class PrivacyPolicy : UserControl { 5 | public PrivacyPolicy() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Ranking/CustomRankingEditor.xaml.cs: -------------------------------------------------------------------------------- 1 | using MetroRadiance.UI.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class CustomRankingEditor : MetroWindow { 5 | public CustomRankingEditor() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Ranking/CustomRankingResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class CustomRankingResult : UserControl { 5 | public CustomRankingResult() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Ranking/HotTopicRankingResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class HotTopicRankingResult : UserControl { 5 | public HotTopicRankingResult() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Ranking/Ranking.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Ranking : UserControl { 5 | public Ranking() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Ranking/RankingResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class RankingResult : UserControl { 5 | public RankingResult() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Ranking/RankingVideoItemView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class RankingVideoItemView : UserControl { 5 | public RankingVideoItemView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Search/Search.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Search : UserControl { 5 | public Search() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Search/SearchResult.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class SearchResult : UserControl { 5 | public SearchResult() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Series/Series.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Series : UserControl { 5 | public Series() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Settings/Settings.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Settings : UserControl { 5 | public Settings() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Settings/SettingsComment.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Settings/SettingsComment.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class SettingsComment : UserControl { 5 | public SettingsComment() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Settings/SettingsGeneral.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class SettingsGeneral : UserControl { 5 | public SettingsGeneral() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Settings/SettingsLive.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Settings/SettingsLive.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class SettingsLive : UserControl { 5 | public SettingsLive() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Settings/SettingsMutedAccount.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class SettingsMutedAccount : UserControl { 5 | public SettingsMutedAccount() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Settings/SettingsRanking.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class SettingsRanking : UserControl { 5 | public SettingsRanking() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Settings/SettingsVideo.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class SettingsVideo : UserControl { 5 | public SettingsVideo() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/SignIn/SignInView.xaml.cs: -------------------------------------------------------------------------------- 1 | using MetroRadiance.UI.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class SignInView : MetroWindow { 5 | public SignInView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/User.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class User : UserControl { 5 | public User() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserFollowView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserFollowView : UserControl { 5 | public UserFollowView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserFollower.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserFollower : UserControl { 5 | public UserFollower() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserFollowing.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserFollowing : UserControl { 5 | public UserFollowing() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserMylist.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserMylist : UserControl { 5 | public UserMylist() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserMylistView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserMylistView : UserControl { 5 | public UserMylistView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserNicoRepo.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserNicoRepo : UserControl { 5 | public UserNicoRepo() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserSeries.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserSeries : UserControl { 5 | public UserSeries() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserSeriesView.xaml: -------------------------------------------------------------------------------- 1 |  13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserSeriesView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserSeriesView : UserControl { 5 | public UserSeriesView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserVideo.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserVideo : UserControl { 5 | public UserVideo() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/User/UserVideoView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class UserVideoView : UserControl { 5 | public UserVideoView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/Video.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class Video : UserControl { 5 | public Video() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/VideoComment.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class VideoComment : UserControl { 5 | public VideoComment() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/VideoController.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class VideoController : UserControl { 5 | public VideoController() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/VideoDescription.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | using System.Windows.Controls.Primitives; 5 | using System.Windows.Documents; 6 | using SRNicoNico.Models; 7 | using SRNicoNico.Models.NicoNicoWrapper; 8 | using SRNicoNico.ViewModels; 9 | 10 | namespace SRNicoNico.Views { 11 | public partial class VideoDescription : UserControl { 12 | 13 | private VideoViewModel ViewModel => (VideoViewModel)DataContext; 14 | 15 | public VideoDescription() { 16 | InitializeComponent(); 17 | } 18 | 19 | 20 | public void OpenHyperlink(object sender, RoutedEventArgs e) { 21 | 22 | var hyperlink = (Hyperlink)sender; 23 | var url = hyperlink.NavigateUri.OriginalString; 24 | 25 | if (ViewModel.NicoNicoViewer.DetectUrlType(url) == NicoNicoUrlType.Video) { 26 | 27 | ViewModel.NavigateTo(url[31..].Split('?')[0]); 28 | } else { 29 | 30 | // 別のタブで開くので動画を一時停止する濫觴 31 | ViewModel.Pause(); 32 | ViewModel.NicoNicoViewer.OpenUrl(hyperlink.NavigateUri.OriginalString); 33 | } 34 | } 35 | 36 | private void InitializeHyperlink(object sender, RoutedEventArgs e) { 37 | 38 | var hyperlink = (Hyperlink)sender; 39 | 40 | hyperlink.ToolTip = new TextBlock { Text = hyperlink.NavigateUri?.OriginalString ?? "" }; 41 | hyperlink.ToolTipOpening += OnToolTipOpening; 42 | } 43 | 44 | private async void OnToolTipOpening(object sender, ToolTipEventArgs e) { 45 | 46 | var hyperlink = (Hyperlink)sender; 47 | var url = hyperlink.NavigateUri?.OriginalString ?? ""; 48 | 49 | if (ViewModel.NicoNicoViewer.DetectUrlType(url) == NicoNicoUrlType.Video) { 50 | 51 | // 動画情報をレイジーロードする 52 | if (hyperlink.Tag == null) { 53 | 54 | hyperlink.Tag = await ViewModel.VideoService.WatchAsync(url[31..].Split('?')[0], true); 55 | hyperlink.ToolTip = new VideoToolTip { DataContext = ((WatchApiData)hyperlink.Tag).Video }; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/VideoFullScreen.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Input; 3 | using SRNicoNico.ViewModels; 4 | 5 | namespace SRNicoNico.Views { 6 | public partial class VideoFullScreen : Window { 7 | public VideoFullScreen() { 8 | InitializeComponent(); 9 | } 10 | 11 | private void Window_PreviewKeyDown(object sender, KeyEventArgs e) { 12 | 13 | if (DataContext is VideoViewModel vm) { 14 | vm.KeyDown(e); 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/VideoFullScreenDescription.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class VideoFullScreenDescription : UserControl { 5 | public VideoFullScreenDescription() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/VideoInformation.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class VideoInformation : UserControl { 5 | public VideoInformation() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/VideoTabView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class VideoTabView : UserControl { 5 | public VideoTabView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/VideoToolTip.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/Video/VideoToolTip.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class VideoToolTip : UserControl { 5 | public VideoToolTip() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/VideoItemView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class VideoItemView : UserControl { 5 | public VideoItemView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/WatchLater/WatchLater.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class WatchLater : UserControl { 5 | public WatchLater() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/WatchLater/WatchLaterEntryView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class WatchLaterEntryView : UserControl { 5 | public WatchLaterEntryView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/WebView/WebView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class WebView : UserControl { 5 | public WebView() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Contents/WebView/WebViewContent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class WebViewContent : UserControl { 5 | public WebViewContent() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Controls/DisabledScrollViewerFlowDocumentScrollViewer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Windows.Controls; 4 | using System.Windows.Controls.Primitives; 5 | using System.Windows.Input; 6 | 7 | namespace SRNicoNico.Views.Controls { 8 | public class DisabledScrollViewerFlowDocumentScrollViewer : FlowDocumentScrollViewer { 9 | 10 | protected override void OnMouseWheel(MouseWheelEventArgs e) { 11 | 12 | var host = GetType().GetProperty("ScrollViewer", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException(); 13 | var scroll = host.GetValue(this) as ScrollViewer ?? throw new InvalidOperationException(); 14 | var info = scroll.GetType().GetProperty("ScrollInfo", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException(); 15 | var scrollInfo = info.GetValue(scroll) as IScrollInfo ?? throw new InvalidOperationException(); 16 | 17 | if (e.Delta < 0) { 18 | 19 | scrollInfo.MouseWheelDown(); 20 | } else { 21 | 22 | scrollInfo.MouseWheelUp(); 23 | } 24 | // FlowDocumentScrollViewerのスクロール処理を無効 25 | // FlowDocumentScrollViewerのScrollViewerは、スクロール処理がこのイベントを受け取った後に 26 | // _ContentHost.LineDown()/LineUp()しか呼んでいなく、スクロール量を全く考慮しないので使いづらい 27 | // リフレクションでScrollInfoを取得してマウスホイール用のスクロールメソッドを呼び出す 28 | } 29 | 30 | protected override void OnPrintCommand() { 31 | // 印刷機能を無効化 32 | //base.OnPrintCommand(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Controls/HtmlRenderer.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | 4 | namespace SRNicoNico.Views.Controls { 5 | /// 6 | /// htmlをWPF上でレンダリングするためのカスタムコントロール 7 | /// 8 | public class HtmlRenderer : Control { 9 | 10 | static HtmlRenderer() { 11 | DefaultStyleKeyProperty.OverrideMetadata(typeof(HtmlRenderer), new FrameworkPropertyMetadata(typeof(HtmlRenderer))); 12 | } 13 | 14 | /// 15 | /// 表示したいHTMLテキスト 16 | /// 17 | public string HtmlText { 18 | get { return (string)GetValue(HtmlTextProperty); } 19 | set { SetValue(HtmlTextProperty, value); } 20 | } 21 | 22 | public static readonly DependencyProperty HtmlTextProperty = 23 | DependencyProperty.Register(nameof(HtmlText), typeof(string), typeof(HtmlRenderer), new PropertyMetadata(string.Empty)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Controls/PageSpinner.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | 4 | namespace SRNicoNico.Views.Controls { 5 | /// 6 | /// ページネーション用のUIを提供するカスタムコントロール 7 | /// 8 | public class PageSpinner : ContentControl { 9 | 10 | static PageSpinner() { 11 | DefaultStyleKeyProperty.OverrideMetadata(typeof(PageSpinner), new FrameworkPropertyMetadata(typeof(PageSpinner))); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Controls/ToggleSwitch.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Input; 4 | 5 | namespace SRNicoNico.Views.Controls { 6 | /// 7 | /// UWPのToggleSwitchをWPFで使う 8 | /// 9 | public class ToggleSwitch : Control { 10 | 11 | static ToggleSwitch() { 12 | DefaultStyleKeyProperty.OverrideMetadata(typeof(ToggleSwitch), new FrameworkPropertyMetadata(typeof(ToggleSwitch))); 13 | } 14 | 15 | /// 16 | /// スイッチがONかOFFかどうか 17 | /// 18 | public bool IsOn { 19 | get { return (bool)GetValue(IsOnProperty); } 20 | set { SetValue(IsOnProperty, value); } 21 | } 22 | public static readonly DependencyProperty IsOnProperty = 23 | DependencyProperty.Register(nameof(IsOn), typeof(bool), typeof(ToggleSwitch), new FrameworkPropertyMetadata(false)); 24 | 25 | private Grid? RootGrid; 26 | 27 | private void MouseLeftButtonDownHandler(object sender, MouseButtonEventArgs e) { 28 | 29 | // GridがクリックされたらIsOnを反転する 30 | IsOn ^= true; 31 | } 32 | 33 | public override void OnApplyTemplate() { 34 | base.OnApplyTemplate(); 35 | 36 | if (RootGrid != null) { 37 | 38 | RootGrid.MouseLeftButtonDown -= MouseLeftButtonDownHandler; 39 | } 40 | 41 | RootGrid = (Grid) GetTemplateChild("PART_Grid"); 42 | RootGrid.MouseLeftButtonDown += MouseLeftButtonDownHandler; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Converters/CommentLabelConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Windows.Data; 5 | 6 | namespace SRNicoNico.Views.Converters { 7 | /// 8 | /// コメントのラベルをヒューマンリーダブルな形式に変換する 9 | /// 10 | [ValueConversion(typeof(string), typeof(string))] 11 | public class CommentLabelConverter : IValueConverter { 12 | 13 | private readonly static Dictionary ConversionMap = new Dictionary() { 14 | ["default"] = "通常コメント", 15 | ["main"] = "通常コメント", 16 | ["easy"] = "かんたんコメント", 17 | ["owner"] = "投稿者コメント", 18 | ["community"] = "チャンネルコメント" 19 | }; 20 | 21 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 22 | 23 | var str = System.Convert.ToString(value)!; 24 | 25 | if (ConversionMap.ContainsKey(str)) { 26 | 27 | return ConversionMap[str]; 28 | } 29 | throw new InvalidOperationException(); 30 | } 31 | 32 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 33 | throw new InvalidOperationException(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Converters/DoubleToPacentageConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace SRNicoNico.Views.Converters { 6 | /// 7 | /// 小数点型の数値を%表記に変換する 8 | /// 9 | [ValueConversion(typeof(double), typeof(string))] 10 | public class DoubleToPacentageConverter : IValueConverter { 11 | 12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 13 | 14 | return $"{Math.Floor(System.Convert.ToDouble(value) * 100)}%"; 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 18 | throw new NotImplementedException(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Converters/DurationConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace SRNicoNico.Views.Converters { 6 | /// 7 | /// 秒を分と時間に分けて:で区切った文字に変換する 8 | /// 9 | [ValueConversion(typeof(int), typeof(string))] 10 | public class DurationConverter : IValueConverter { 11 | 12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 13 | 14 | var seconds = System.Convert.ToInt32(value); 15 | int minutes = seconds / 60; 16 | int second = seconds % 60; 17 | 18 | return $"{minutes}:{second:00}"; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Converters/EnumDisplayConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.Globalization; 4 | using System.Reflection; 5 | using System.Windows.Data; 6 | 7 | namespace SRNicoNico.Views.Converters { 8 | /// 9 | /// enumに付加されているDisplay属性の値にenumを変換する 10 | /// 11 | [ValueConversion(typeof(int), typeof(string))] 12 | public class EnumDisplayConverter : IValueConverter { 13 | 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 15 | // xamlのホットリロードが起きる時にnullが来ることがある 16 | if (value == null) { 17 | return null!; 18 | } 19 | var field = value.GetType().GetField(value.ToString()!); 20 | var display = field?.GetCustomAttribute(); 21 | 22 | return display is null ? value.ToString()! : display.Name; 23 | } 24 | 25 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 26 | throw new NotImplementedException(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Converters/FontFamilyToLocalizedNameConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | using System.Windows; 5 | using System.Windows.Data; 6 | using System.Windows.Markup; 7 | using System.Windows.Media; 8 | 9 | namespace SRNicoNico.Views.Converters { 10 | /// 11 | /// FontFamilyクラスをstringの名前に変換する 12 | /// 13 | [ValueConversion(typeof(FontFamily), typeof(string))] 14 | public class FontFamilyToLocalizedNameConverter : IValueConverter { 15 | 16 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { 17 | 18 | #if DEBUG 19 | if ((bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue) { 20 | return "Yu Gothic UI"; 21 | } 22 | #endif 23 | 24 | var v = (FontFamily)value; 25 | var currentLang = XmlLanguage.GetLanguage(culture.IetfLanguageTag); 26 | return v.FamilyNames.FirstOrDefault(o => o.Key == currentLang).Value ?? v.Source; 27 | } 28 | 29 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { 30 | throw new NotImplementedException(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Converters/InvertBoolConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace SRNicoNico.Views.Converters { 6 | /// 7 | /// bool値を反転するコンバータ 8 | /// 9 | [ValueConversion(typeof(bool), typeof(bool))] 10 | public class InvertBoolConverter : IValueConverter { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 12 | bool booleanValue = (bool)value; 13 | return !booleanValue; 14 | } 15 | 16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 17 | bool booleanValue = (bool)value; 18 | return !booleanValue; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SRNicoNico/Views/Converters/VposDurationConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace SRNicoNico.Views.Converters { 6 | /// 7 | /// センチ秒を分と時間に分けて:で区切った文字に変換する 8 | /// 9 | [ValueConversion(typeof(int), typeof(string))] 10 | public class VposDurationConverter : IValueConverter { 11 | 12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 13 | 14 | var seconds = System.Convert.ToInt32(value) / 100; 15 | int minutes = seconds / 60; 16 | int second = seconds % 60; 17 | 18 | return $"{minutes}:{second:00}"; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SRNicoNico/Views/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using MetroRadiance.UI.Controls; 2 | 3 | namespace SRNicoNico.Views { 4 | public partial class MainWindow : MetroWindow { 5 | public MainWindow() { 6 | InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SRNicoNico/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "mrtska", 3 | "name": "srniconico-html", 4 | "private": true, 5 | "license": "MIT", 6 | "homepage": "https://mrtska.net/niconicoviewer", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/mrtska/SRNicoNico.git" 10 | }, 11 | "scripts": { 12 | "build": "webpack -c ./Html/webpack.config.ts --mode production", 13 | "dev-watch": "webpack -c ./Html/webpack.config.ts --mode development --watch" 14 | }, 15 | "devDependencies": { 16 | "typescript": "5.3.3", 17 | "webpack": "5.90.3", 18 | "webpack-cli": "5.1.4", 19 | "hls.js": "1.5.6", 20 | "ts-loader": "9.5.1", 21 | "ts-node": "10.9.2", 22 | "css-loader": "6.10.0", 23 | "sass-loader": "14.1.1", 24 | "style-loader": "3.3.4", 25 | "sass": "1.71.1", 26 | "@types/node": "15.6.0", 27 | "@types/chrome": "0.0.260" 28 | }, 29 | "dependencies": {} 30 | } 31 | -------------------------------------------------------------------------------- /SRNicoNico/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "removeComments": true, 5 | "esModuleInterop": true, 6 | "sourceMap": true, 7 | "target": "ES2022", 8 | "lib": [ "dom", "ES2022" ], 9 | "moduleResolution": "Node" 10 | }, 11 | "exclude": [ 12 | "node_modules", 13 | "wwwroot" 14 | ] 15 | } 16 | --------------------------------------------------------------------------------