├── .github
    ├── ISSUE_TEMPLATE
    │   ├── bug_report.yml
    │   ├── custom.md
    │   └── feature_request.yml
    ├── PULL_REQUEST_TEMPLATE
    │   ├── bug_fix.md
    │   ├── feature_addition.md
    │   └── submit_h_keyframe.md
    ├── dependabot.yml
    └── workflows
    │   ├── ci.yml
    │   └── pr_check.yml
├── .gitignore
├── HanimeAnnouncementManagerWebUI
    ├── HanimeAnnouncementManager.html
    └── PermitAdmin.py
├── LICENSE
├── README.md
├── README_TECH.md
├── app
    ├── .gitignore
    ├── build.gradle.kts
    ├── keystore
    │   └── Han1meViewerKeystore.jks
    ├── proguard-rules.pro
    └── src
    │   ├── androidTest
    │       └── java
    │       │   └── com
    │       │       └── yenaly
    │       │           └── han1meviewer
    │       │               └── ExampleInstrumentedTest.kt
    │   ├── debug
    │       └── res
    │       │   └── values
    │       │       └── strings.xml
    │   ├── main
    │       ├── AndroidManifest.xml
    │       ├── assets
    │       │   ├── h_keyframes
    │       │   │   ├── 12444.json
    │       │   │   ├── 14463.json
    │       │   │   ├── 21806.json
    │       │   │   ├── 22068.json
    │       │   │   ├── 37176.json
    │       │   │   ├── 37177.json
    │       │   │   ├── 37178.json
    │       │   │   ├── 37179.json
    │       │   │   ├── 37220.json
    │       │   │   ├── 37221.json
    │       │   │   ├── 38387.json
    │       │   │   ├── 38389.json
    │       │   │   ├── 38457.json
    │       │   │   ├── 38461.json
    │       │   │   ├── 39192.json
    │       │   │   ├── 39305.json
    │       │   │   ├── 39306.json
    │       │   │   ├── 39468.json
    │       │   │   ├── 39811.json
    │       │   │   ├── 84717.json
    │       │   │   ├── 84718.json
    │       │   │   ├── 85926.json
    │       │   │   ├── 85927.json
    │       │   │   ├── 87968.json
    │       │   │   ├── 87969.json
    │       │   │   ├── 89087.json
    │       │   │   ├── 89088.json
    │       │   │   └── README.md
    │       │   ├── report_reason.json
    │       │   ├── search_options
    │       │   │   ├── brands.json
    │       │   │   ├── duration.json
    │       │   │   ├── genre.json
    │       │   │   ├── release_date.json
    │       │   │   ├── sort_option.json
    │       │   │   └── tags.json
    │       │   └── shaders
    │       │   │   ├── Anime4K_AutoDownscalePre_x2.glsl
    │       │   │   ├── Anime4K_AutoDownscalePre_x4.glsl
    │       │   │   ├── Anime4K_Clamp_Highlights.glsl
    │       │   │   ├── Anime4K_Restore_CNN_M.glsl
    │       │   │   ├── Anime4K_Restore_CNN_S.glsl
    │       │   │   ├── Anime4K_Restore_CNN_VL.glsl
    │       │   │   ├── Anime4K_Upscale_CNN_x2_M.glsl
    │       │   │   ├── Anime4K_Upscale_CNN_x2_S.glsl
    │       │   │   └── Anime4K_Upscale_CNN_x2_VL.glsl
    │       ├── java
    │       │   └── com
    │       │   │   └── yenaly
    │       │   │       └── han1meviewer
    │       │   │           ├── Constants.kt
    │       │   │           ├── FirebaseConstants.kt
    │       │   │           ├── HAdvancedSearch.kt
    │       │   │           ├── HCacheManager.kt
    │       │   │           ├── HCrashHandler.kt
    │       │   │           ├── HFileManager.kt
    │       │   │           ├── HInitializer.kt
    │       │   │           ├── HanimeApplication.kt
    │       │   │           ├── HanimeManager.kt
    │       │   │           ├── HanimeResolution.kt
    │       │   │           ├── Preferences.kt
    │       │   │           ├── VideoCoverSize.kt
    │       │   │           ├── logic
    │       │   │               ├── DatabaseRepo.kt
    │       │   │               ├── NetworkRepo.kt
    │       │   │               ├── Parser.kt
    │       │   │               ├── dao
    │       │   │               │   ├── CheckInRecordDao.kt
    │       │   │               │   ├── CheckInRecordDatabase.kt
    │       │   │               │   ├── DownloadDatabase.kt
    │       │   │               │   ├── HKeyframeDao.kt
    │       │   │               │   ├── HistoryDatabase.kt
    │       │   │               │   ├── MiscellanyDatabase.kt
    │       │   │               │   ├── SearchHistoryDao.kt
    │       │   │               │   ├── WatchHistoryDao.kt
    │       │   │               │   └── download
    │       │   │               │   │   ├── DownloadCategoryDao.kt
    │       │   │               │   │   └── HanimeDownloadDao.kt
    │       │   │               ├── entity
    │       │   │               │   ├── CheckInRecordEntity.kt
    │       │   │               │   ├── HKeyframeEntity.kt
    │       │   │               │   ├── SearchHistoryEntity.kt
    │       │   │               │   ├── WatchHistoryEntity.kt
    │       │   │               │   └── download
    │       │   │               │   │   ├── DownloadCategoryEntity.kt
    │       │   │               │   │   ├── HanimeCategoryCrossRef.kt
    │       │   │               │   │   ├── HanimeDownloadEntity.kt
    │       │   │               │   │   └── VideoWithCategories.kt
    │       │   │               ├── exception
    │       │   │               │   ├── CloudFlareBlockedException.kt
    │       │   │               │   ├── HanimeNotFoundException.kt
    │       │   │               │   ├── IPBlockedException.kt
    │       │   │               │   └── ParseException.kt
    │       │   │               ├── model
    │       │   │               │   ├── Announcement.kt
    │       │   │               │   ├── HanimeInfo.kt
    │       │   │               │   ├── HanimePreview.kt
    │       │   │               │   ├── HanimeVideo.kt
    │       │   │               │   ├── HomePage.kt
    │       │   │               │   ├── MultiItemEntity.kt
    │       │   │               │   ├── MyListItems.kt
    │       │   │               │   ├── MySubscriptions.kt
    │       │   │               │   ├── ParamEnum.kt
    │       │   │               │   ├── Playlists.kt
    │       │   │               │   ├── ReportReason.kt
    │       │   │               │   ├── SearchOption.kt
    │       │   │               │   ├── SearchTag.kt
    │       │   │               │   ├── VideoComments.kt
    │       │   │               │   ├── VideoItemType.kt
    │       │   │               │   └── github
    │       │   │               │   │   ├── Commit.kt
    │       │   │               │   │   ├── Latest.kt
    │       │   │               │   │   ├── Release.kt
    │       │   │               │   │   └── Workflow.kt
    │       │   │               ├── network
    │       │   │               │   ├── GitHubDns.kt
    │       │   │               │   ├── HCookieJar.kt
    │       │   │               │   ├── HDns.kt
    │       │   │               │   ├── HProxySelector.kt
    │       │   │               │   ├── HUpdater.kt
    │       │   │               │   ├── HanimeNetwork.kt
    │       │   │               │   ├── ServiceCreator.kt
    │       │   │               │   ├── interceptor
    │       │   │               │   │   ├── CloudflareInterceptor.kt
    │       │   │               │   │   ├── SpeedLimitInterceptor.kt
    │       │   │               │   │   ├── SpeedLimitResponseBody.kt
    │       │   │               │   │   ├── UrlLoggingInterceptor.kt
    │       │   │               │   │   └── UserAgentInterceptor.kt
    │       │   │               │   └── service
    │       │   │               │   │   ├── HGitHubService.kt
    │       │   │               │   │   ├── HanimeBaseService.kt
    │       │   │               │   │   ├── HanimeCommentService.kt
    │       │   │               │   │   ├── HanimeMyListService.kt
    │       │   │               │   │   └── HanimeSubscriptionService.kt
    │       │   │               └── state
    │       │   │               │   ├── DownloadState.kt
    │       │   │               │   ├── PageLoadingState.kt
    │       │   │               │   ├── VideoLoadingState.kt
    │       │   │               │   └── WebsiteState.kt
    │       │   │           ├── ui
    │       │   │               ├── StateLayoutMixin.kt
    │       │   │               ├── activity
    │       │   │               │   ├── CloudflareActivity.kt
    │       │   │               │   ├── LoginActivity.kt
    │       │   │               │   ├── MainActivity.kt
    │       │   │               │   ├── QRcodeScannerActivity.kt
    │       │   │               │   ├── SettingsActivity.kt
    │       │   │               │   └── SettingsRouter.kt
    │       │   │               ├── adapter
    │       │   │               │   ├── AdapterLikeDataBindingPage.kt
    │       │   │               │   ├── AnnouncementAdapter.kt
    │       │   │               │   ├── AnnouncementCardAdapter.kt
    │       │   │               │   ├── BaseSingleDifferAdapter.kt
    │       │   │               │   ├── DelayAdapter.kt
    │       │   │               │   ├── FixedGridLayoutManager.kt
    │       │   │               │   ├── HKeyframesRvAdapter.kt
    │       │   │               │   ├── HSearchTagAdapter.kt
    │       │   │               │   ├── HanimeAdvancedSearchHistoryAdapter.kt
    │       │   │               │   ├── HanimeDownloadedRvAdapter.kt
    │       │   │               │   ├── HanimeDownloadingRvAdapter.kt
    │       │   │               │   ├── HanimeMyListVideoAdapter.kt
    │       │   │               │   ├── HanimePreviewNewsRvAdapter.kt
    │       │   │               │   ├── HanimePreviewTourRvAdapter.kt
    │       │   │               │   ├── HanimeSearchHistoryRvAdapter.kt
    │       │   │               │   ├── HanimeVideoRvAdapter.kt
    │       │   │               │   ├── PlaylistRvAdapter.kt
    │       │   │               │   ├── ReleaseDateAdapter.kt
    │       │   │               │   ├── RvWrapper.kt
    │       │   │               │   ├── SharedHKeyframesRvAdapter.kt
    │       │   │               │   ├── SuperResolutionAdapter.kt
    │       │   │               │   ├── VideoColumnTitleAdapter.kt
    │       │   │               │   ├── VideoCommentRvAdapter.kt
    │       │   │               │   ├── VideoSpeedAdapter.kt
    │       │   │               │   └── WatchHistoryRvAdapter.kt
    │       │   │               ├── fragment
    │       │   │               │   ├── ComposeItem.kt
    │       │   │               │   ├── ComposePreview.kt
    │       │   │               │   ├── ComposePreviewDataSource.kt
    │       │   │               │   ├── ComposeUtils.kt
    │       │   │               │   ├── IToolbarFragment.kt
    │       │   │               │   ├── LoginNeededFragmentMixin.kt
    │       │   │               │   ├── PermissionRequester.kt
    │       │   │               │   ├── PlaylistBottomSheetDialogFragment.kt
    │       │   │               │   ├── ToolbarHost.kt
    │       │   │               │   ├── dailycheckin
    │       │   │               │   │   └── DailyCheckInFragment.kt
    │       │   │               │   ├── funny
    │       │   │               │   │   ├── FunnyTouchListener.kt
    │       │   │               │   │   └── SomeFunny.kt
    │       │   │               │   ├── home
    │       │   │               │   │   ├── DownloadFragment.kt
    │       │   │               │   │   ├── HomePageFragment.kt
    │       │   │               │   │   ├── MyFavVideoFragment.kt
    │       │   │               │   │   ├── MyPlayListFragmentV2.kt
    │       │   │               │   │   ├── MyPlaylistFragment.kt
    │       │   │               │   │   ├── MyWatchLaterFragment.kt
    │       │   │               │   │   ├── SubscriptionFragment.kt
    │       │   │               │   │   ├── WatchHistoryFragment.kt
    │       │   │               │   │   ├── download
    │       │   │               │   │   │   ├── DownloadedFragment.kt
    │       │   │               │   │   │   └── DownloadingFragment.kt
    │       │   │               │   │   ├── myplaylist
    │       │   │               │   │   │   ├── MyPlayListScreen.kt
    │       │   │               │   │   │   └── MyplayListBottomSheet.kt
    │       │   │               │   │   ├── preview
    │       │   │               │   │   │   ├── PreviewCommentFragment.kt
    │       │   │               │   │   │   └── PreviewFragment.kt
    │       │   │               │   │   └── subscription
    │       │   │               │   │   │   └── SubscriptionScreen.kt
    │       │   │               │   ├── search
    │       │   │               │   │   ├── HCheckBoxFragment.kt
    │       │   │               │   │   ├── HMultiChoicesDialog.kt
    │       │   │               │   │   ├── SearchFragment.kt
    │       │   │               │   │   └── SearchOptionsPopupFragment.kt
    │       │   │               │   ├── settings
    │       │   │               │   │   ├── DownloadSettingsFragment.kt
    │       │   │               │   │   ├── HKeyframeSettingsFragment.kt
    │       │   │               │   │   ├── HKeyframesFragment.kt
    │       │   │               │   │   ├── HomeSettingsFragment.kt
    │       │   │               │   │   ├── MpvPlayerSettings.kt
    │       │   │               │   │   ├── NetworkSettingsFragment.kt
    │       │   │               │   │   ├── PlayerSettingsFragment.kt
    │       │   │               │   │   └── SharedHKeyframesFragment.kt
    │       │   │               │   └── video
    │       │   │               │   │   ├── ChildCommentPopupFragment.kt
    │       │   │               │   │   ├── CommentFragment.kt
    │       │   │               │   │   ├── VideoFragment.kt
    │       │   │               │   │   └── VideoIntroductionFragment.kt
    │       │   │               ├── popup
    │       │   │               │   ├── CoilImageLoader.kt
    │       │   │               │   ├── HTimePickerPopup.kt
    │       │   │               │   └── ReplyPopup.kt
    │       │   │               ├── theme
    │       │   │               │   ├── Color.kt
    │       │   │               │   └── Theme.kt
    │       │   │               ├── view
    │       │   │               │   ├── BlurTransformation.kt
    │       │   │               │   ├── CenterLinearLayoutManager.kt
    │       │   │               │   ├── CollapsibleTags.kt
    │       │   │               │   ├── HOptionChip.kt
    │       │   │               │   ├── HanimeSearchBar.kt
    │       │   │               │   ├── HorizontalNestedScrollView.kt
    │       │   │               │   ├── LinearSmoothToStartScroller.kt
    │       │   │               │   ├── PlaylistHeader.kt
    │       │   │               │   ├── funcbar
    │       │   │               │   │   ├── Hanidapter.kt
    │       │   │               │   │   ├── Hanidock.kt
    │       │   │               │   │   ├── Hanidokitem.kt
    │       │   │               │   │   └── Hanidontroller.kt
    │       │   │               │   ├── pref
    │       │   │               │   │   ├── HPrivacyPreference.kt
    │       │   │               │   │   ├── MaterialDialogPreference.kt
    │       │   │               │   │   └── MaterialSliderPreference.kt
    │       │   │               │   └── video
    │       │   │               │   │   ├── HJzvdStd.kt
    │       │   │               │   │   ├── HMediaKernel.kt
    │       │   │               │   │   ├── HanimeDataSource.kt
    │       │   │               │   │   └── VideoPlayerAppBarBehavior.kt
    │       │   │               └── viewmodel
    │       │   │               │   ├── AppViewModel.kt
    │       │   │               │   ├── CheckInCalendarViewModel.kt
    │       │   │               │   ├── CommentViewModel.kt
    │       │   │               │   ├── DownloadViewModel.kt
    │       │   │               │   ├── IHCsrfToken.kt
    │       │   │               │   ├── MainViewModel.kt
    │       │   │               │   ├── MyListViewModel.kt
    │       │   │               │   ├── MyPlayListViewModelV2.kt
    │       │   │               │   ├── MySubscriptionsViewModel.kt
    │       │   │               │   ├── PreviewCommentPrefetcher.kt
    │       │   │               │   ├── PreviewViewModel.kt
    │       │   │               │   ├── SearchViewModel.kt
    │       │   │               │   ├── SettingsViewModel.kt
    │       │   │               │   ├── VideoViewModel.kt
    │       │   │               │   └── mylist
    │       │   │               │       ├── FavSubViewModel.kt
    │       │   │               │       ├── PlaylistSubViewModel.kt
    │       │   │               │       └── WatchLaterSubViewModel.kt
    │       │   │           ├── util
    │       │   │               ├── Adapters.kt
    │       │   │               ├── AlertDialogs.kt
    │       │   │               ├── Animations.kt
    │       │   │               ├── AnimeShaders.kt
    │       │   │               ├── Colors.kt
    │       │   │               ├── CommentUtils.kt
    │       │   │               ├── Common.kt
    │       │   │               ├── Cookies.kt
    │       │   │               ├── Files.kt
    │       │   │               ├── Firebases.kt
    │       │   │               ├── HImageMeower.kt
    │       │   │               ├── Networks.kt
    │       │   │               ├── Parcels.kt
    │       │   │               ├── Permissions.kt
    │       │   │               ├── Preferences.kt
    │       │   │               ├── SafFileManager.kt
    │       │   │               ├── TextViews.kt
    │       │   │               ├── ThemeUtils.kt
    │       │   │               ├── Versions.kt
    │       │   │               └── Views.kt
    │       │   │           └── worker
    │       │   │               ├── HUpdateWorker.kt
    │       │   │               ├── HanimeDownloadManager.kt
    │       │   │               ├── HanimeDownloadManagerV2.kt
    │       │   │               ├── HanimeDownloadWorker.kt
    │       │   │               └── WorkerMixin.kt
    │       └── res
    │       │   ├── anim
    │       │       ├── fade_in.xml
    │       │       ├── fade_out.xml
    │       │       ├── slide_in_left.xml
    │       │       ├── slide_in_right.xml
    │       │       ├── slide_out_left.xml
    │       │       └── slide_out_right.xml
    │       │   ├── color
    │       │       ├── nav_item_icon_color.xml
    │       │       └── nav_item_text_color.xml
    │       │   ├── drawable
    │       │       ├── akarin.png
    │       │       ├── apply_deep_links.png
    │       │       ├── baseline_add_24.xml
    │       │       ├── baseline_add_link_24.xml
    │       │       ├── baseline_advanced_search_24.xml
    │       │       ├── baseline_arrow_forward_ios_24.xml
    │       │       ├── baseline_atomic_24.xml
    │       │       ├── baseline_bug_report_24.xml
    │       │       ├── baseline_cache_24.xml
    │       │       ├── baseline_cert_24.xml
    │       │       ├── baseline_chip_24.xml
    │       │       ├── baseline_count_24.xml
    │       │       ├── baseline_count_down_24.xml
    │       │       ├── baseline_custom_24.xml
    │       │       ├── baseline_data_usage_24.xml
    │       │       ├── baseline_deband_24.xml
    │       │       ├── baseline_decoder_24.xml
    │       │       ├── baseline_delay_24.xml
    │       │       ├── baseline_domain_24.xml
    │       │       ├── baseline_edit_24.xml
    │       │       ├── baseline_error_outline_24.xml
    │       │       ├── baseline_export_24.xml
    │       │       ├── baseline_format_list_bulleted_24.xml
    │       │       ├── baseline_forum_24.xml
    │       │       ├── baseline_frame_inter_24.xml
    │       │       ├── baseline_frame_jump_24.xml
    │       │       ├── baseline_h_24.xml
    │       │       ├── baseline_hosts_24.xml
    │       │       ├── baseline_keyboard_arrow_down_24.xml
    │       │       ├── baseline_keyboard_arrow_up_24.xml
    │       │       ├── baseline_manage_24.xml
    │       │       ├── baseline_more_horiz_24.xml
    │       │       ├── baseline_online_manage_24.xml
    │       │       ├── baseline_overtime_24.xml
    │       │       ├── baseline_path_24.xml
    │       │       ├── baseline_player_24.xml
    │       │       ├── baseline_prohibit_24.xml
    │       │       ├── baseline_refresh_24.xml
    │       │       ├── baseline_remove_circle_24.xml
    │       │       ├── baseline_render_24.xml
    │       │       ├── baseline_seek_24.xml
    │       │       ├── baseline_share_24.xml
    │       │       ├── baseline_share_first_24.xml
    │       │       ├── baseline_simp_to_trad_24.xml
    │       │       ├── baseline_sort_24.xml
    │       │       ├── baseline_speed2_24.xml
    │       │       ├── baseline_speed_24.xml
    │       │       ├── baseline_touch_24.xml
    │       │       ├── baseline_vpn_24.xml
    │       │       ├── bg_default_header.png
    │       │       ├── cookies_intro1.png
    │       │       ├── frosted_glass.xml
    │       │       ├── gradient_black_transparent_90.xml
    │       │       ├── ic_baseline_4k_24.xml
    │       │       ├── ic_baseline_access_time_24.xml
    │       │       ├── ic_baseline_alert_24.xml
    │       │       ├── ic_baseline_arrow_back_24.xml
    │       │       ├── ic_baseline_arrow_forward_24.xml
    │       │       ├── ic_baseline_book.xml
    │       │       ├── ic_baseline_cancel_24.xml
    │       │       ├── ic_baseline_check_circle_24.xml
    │       │       ├── ic_baseline_clear_all_24.xml
    │       │       ├── ic_baseline_close_24.xml
    │       │       ├── ic_baseline_comment_24.xml
    │       │       ├── ic_baseline_delete_24.xml
    │       │       ├── ic_baseline_disable_24.xml
    │       │       ├── ic_baseline_download_24.xml
    │       │       ├── ic_baseline_favorite_24.xml
    │       │       ├── ic_baseline_favorite_border_24.xml
    │       │       ├── ic_baseline_help_24.xml
    │       │       ├── ic_baseline_history_24.xml
    │       │       ├── ic_baseline_home_24.xml
    │       │       ├── ic_baseline_info_24.xml
    │       │       ├── ic_baseline_language_24.xml
    │       │       ├── ic_baseline_list_24.xml
    │       │       ├── ic_baseline_mask.xml
    │       │       ├── ic_baseline_moon_24.xml
    │       │       ├── ic_baseline_more_time_24.xml
    │       │       ├── ic_baseline_newspaper_24.xml
    │       │       ├── ic_baseline_pantsu.xml
    │       │       ├── ic_baseline_pause_24.xml
    │       │       ├── ic_baseline_pause_24_tintwhite.xml
    │       │       ├── ic_baseline_play_arrow_24.xml
    │       │       ├── ic_baseline_play_arrow_24_tintwhite.xml
    │       │       ├── ic_baseline_play_circle_outline_24.xml
    │       │       ├── ic_baseline_reply_24.xml
    │       │       ├── ic_baseline_report_24.xml
    │       │       ├── ic_baseline_scan_24.xml
    │       │       ├── ic_baseline_search_24.xml
    │       │       ├── ic_baseline_send_24.xml
    │       │       ├── ic_baseline_settings_24.xml
    │       │       ├── ic_baseline_share_24.xml
    │       │       ├── ic_baseline_skip_24.xml
    │       │       ├── ic_baseline_speed_24.xml
    │       │       ├── ic_baseline_theme_24.xml
    │       │       ├── ic_baseline_thumb_down_alt_24.xml
    │       │       ├── ic_baseline_thumb_down_off_alt_24.xml
    │       │       ├── ic_baseline_thumb_up_alt_24.xml
    │       │       ├── ic_baseline_thumb_up_off_alt_24.xml
    │       │       ├── ic_baseline_update_24.xml
    │       │       ├── ic_baseline_watch_later_24.xml
    │       │       ├── ic_clock.xml
    │       │       ├── ic_comments.xml
    │       │       ├── ic_ext_link.xml
    │       │       ├── ic_launcher.webp
    │       │       ├── ic_launcher_calc.webp
    │       │       ├── ic_launcher_cornhub.webp
    │       │       ├── ic_launcher_debug_background.xml
    │       │       ├── ic_launcher_xxt.webp
    │       │       ├── ic_oss.xml
    │       │       ├── ic_pip_mode.xml
    │       │       ├── ic_send_selector.xml
    │       │       ├── ic_setting_applock.xml
    │       │       ├── ic_setting_ci.xml
    │       │       ├── ic_setting_lang.xml
    │       │       ├── ic_subscribtion.xml
    │       │       ├── ic_video_quilty.xml
    │       │       ├── icon_circle_bg.xml
    │       │       ├── indicator_active.xml
    │       │       ├── indicator_inactive.xml
    │       │       ├── linear_gradient_90.xml
    │       │       ├── linear_gradient_90_notrans.xml
    │       │       ├── neuro_sad.png
    │       │       ├── outline_home_24.xml
    │       │       ├── scaled_added_time.xml
    │       │       ├── search_bar_background.xml
    │       │       ├── shape_download_func_bar.xml
    │       │       ├── shape_preview_button_left.xml
    │       │       ├── shape_preview_button_right.xml
    │       │       └── shape_title_mask.xml
    │       │   ├── layout
    │       │       ├── activity_cloudflare.xml
    │       │       ├── activity_login.xml
    │       │       ├── activity_main.xml
    │       │       ├── activity_settings.xml
    │       │       ├── activity_video.xml
    │       │       ├── base_column_title.xml
    │       │       ├── delay_test_dialog.xml
    │       │       ├── dialog_announcement.xml
    │       │       ├── dialog_apply_deep_links.xml
    │       │       ├── dialog_login.xml
    │       │       ├── dialog_modify_h_keyframe.xml
    │       │       ├── dialog_modify_h_keyframes.xml
    │       │       ├── dialog_playlist_modify_edit_text.xml
    │       │       ├── dialog_proxy.xml
    │       │       ├── fragment_bottom_sheet_list.xml
    │       │       ├── fragment_comment.xml
    │       │       ├── fragment_download.xml
    │       │       ├── fragment_h_keyframes.xml
    │       │       ├── fragment_home_page.xml
    │       │       ├── fragment_list_only.xml
    │       │       ├── fragment_page_list.xml
    │       │       ├── fragment_playlist.xml
    │       │       ├── fragment_preview.xml
    │       │       ├── fragment_preview_comment.xml
    │       │       ├── fragment_search.xml
    │       │       ├── fragment_video.xml
    │       │       ├── fragment_video_introduction.xml
    │       │       ├── item_announcement.xml
    │       │       ├── item_announcement_card.xml
    │       │       ├── item_delay_result.xml
    │       │       ├── item_h_keyframe.xml
    │       │       ├── item_h_keyframes.xml
    │       │       ├── item_hanidock.xml
    │       │       ├── item_hanime_advanced_search_history.xml
    │       │       ├── item_hanime_downloaded.xml
    │       │       ├── item_hanime_downloading.xml
    │       │       ├── item_hanime_preview_news_pic.xml
    │       │       ├── item_hanime_preview_news_v2.xml
    │       │       ├── item_hanime_video.xml
    │       │       ├── item_hanime_video_simplified.xml
    │       │       ├── item_playlist.xml
    │       │       ├── item_preview_tour_simplified.xml
    │       │       ├── item_rv_wrapper.xml
    │       │       ├── item_search_history.xml
    │       │       ├── item_shared_h_keyframes.xml
    │       │       ├── item_simple_card.xml
    │       │       ├── item_simple_icon_with_text.xml
    │       │       ├── item_video_column_title.xml
    │       │       ├── item_video_comment.xml
    │       │       ├── item_video_introduction.xml
    │       │       ├── item_video_tag_chip.xml
    │       │       ├── item_watch_history.xml
    │       │       ├── jz_layout_speed.xml
    │       │       ├── layout_collapsible_tag.xml
    │       │       ├── layout_dialog_progress.xml
    │       │       ├── layout_empty_view.xml
    │       │       ├── layout_hanidock.xml
    │       │       ├── layout_hanime_search_bar.xml
    │       │       ├── layout_header_h_keyframes.xml
    │       │       ├── layout_jzvd_with_speed.xml
    │       │       ├── layout_playlist_header_v2.xml
    │       │       ├── layout_rv_scrollbars.xml
    │       │       ├── nav_header_ability.xml
    │       │       ├── pop_up_ext_h_time_picker.xml
    │       │       ├── pop_up_fragment_child_comment.xml
    │       │       ├── pop_up_fragment_search_options.xml
    │       │       ├── pop_up_hanime_search_tag.xml
    │       │       ├── pop_up_reply.xml
    │       │       └── pref_material_slider.xml
    │       │   ├── menu
    │       │       ├── menu_comment_sort.xml
    │       │       ├── menu_downloaded_toolbar.xml
    │       │       ├── menu_downloading_toolbar.xml
    │       │       ├── menu_main_nv.xml
    │       │       ├── menu_main_toolbar.xml
    │       │       ├── menu_my_list_toolbar.xml
    │       │       ├── menu_playlist_toolbar.xml
    │       │       ├── menu_preview_toolbar.xml
    │       │       └── menu_watch_history_toolbar.xml
    │       │   ├── mipmap-anydpi-v26
    │       │       ├── ic_launcher.xml
    │       │       ├── ic_launcher_calc.xml
    │       │       ├── ic_launcher_calc_round.xml
    │       │       ├── ic_launcher_cornhub.xml
    │       │       ├── ic_launcher_cornhub_round.xml
    │       │       ├── ic_launcher_debug.xml
    │       │       ├── ic_launcher_debug_round.xml
    │       │       ├── ic_launcher_round.xml
    │       │       ├── ic_launcher_xxt.xml
    │       │       └── ic_launcher_xxt_round.xml
    │       │   ├── mipmap-hdpi
    │       │       ├── ic_launcher.webp
    │       │       ├── ic_launcher_calc.webp
    │       │       ├── ic_launcher_calc_foreground.webp
    │       │       ├── ic_launcher_cornhub.webp
    │       │       ├── ic_launcher_cornhub_foreground.webp
    │       │       ├── ic_launcher_debug.webp
    │       │       ├── ic_launcher_debug_foreground.webp
    │       │       ├── ic_launcher_foreground.webp
    │       │       ├── ic_launcher_round.webp
    │       │       ├── ic_launcher_xxt.webp
    │       │       ├── ic_launcher_xxt_background.webp
    │       │       └── ic_launcher_xxt_foreground.webp
    │       │   ├── mipmap-mdpi
    │       │       ├── ic_launcher.webp
    │       │       ├── ic_launcher_calc.webp
    │       │       ├── ic_launcher_calc_foreground.webp
    │       │       ├── ic_launcher_cornhub.webp
    │       │       ├── ic_launcher_cornhub_foreground.webp
    │       │       ├── ic_launcher_debug.webp
    │       │       ├── ic_launcher_debug_foreground.webp
    │       │       ├── ic_launcher_foreground.webp
    │       │       ├── ic_launcher_round.webp
    │       │       ├── ic_launcher_xxt.webp
    │       │       ├── ic_launcher_xxt_background.webp
    │       │       └── ic_launcher_xxt_foreground.webp
    │       │   ├── mipmap-xhdpi
    │       │       ├── ic_launcher.webp
    │       │       ├── ic_launcher_calc.webp
    │       │       ├── ic_launcher_calc_foreground.webp
    │       │       ├── ic_launcher_cornhub.webp
    │       │       ├── ic_launcher_cornhub_foreground.webp
    │       │       ├── ic_launcher_debug.webp
    │       │       ├── ic_launcher_debug_foreground.webp
    │       │       ├── ic_launcher_foreground.webp
    │       │       ├── ic_launcher_round.webp
    │       │       ├── ic_launcher_xxt.webp
    │       │       ├── ic_launcher_xxt_background.webp
    │       │       └── ic_launcher_xxt_foreground.webp
    │       │   ├── mipmap-xxhdpi
    │       │       ├── ic_launcher.webp
    │       │       ├── ic_launcher_calc.webp
    │       │       ├── ic_launcher_calc_foreground.webp
    │       │       ├── ic_launcher_calc_round.webp
    │       │       ├── ic_launcher_cornhub.webp
    │       │       ├── ic_launcher_cornhub_foreground.webp
    │       │       ├── ic_launcher_cornhub_round.webp
    │       │       ├── ic_launcher_debug.webp
    │       │       ├── ic_launcher_debug_foreground.webp
    │       │       ├── ic_launcher_debug_round.webp
    │       │       ├── ic_launcher_foreground.webp
    │       │       ├── ic_launcher_round.webp
    │       │       ├── ic_launcher_xxt.webp
    │       │       ├── ic_launcher_xxt_background.webp
    │       │       ├── ic_launcher_xxt_foreground.webp
    │       │       └── ic_launcher_xxt_round.webp
    │       │   ├── mipmap-xxxhdpi
    │       │       ├── ic_launcher.webp
    │       │       ├── ic_launcher_calc.webp
    │       │       ├── ic_launcher_calc_foreground.webp
    │       │       ├── ic_launcher_calc_round.webp
    │       │       ├── ic_launcher_cornhub.webp
    │       │       ├── ic_launcher_cornhub_foreground.webp
    │       │       ├── ic_launcher_cornhub_round.webp
    │       │       ├── ic_launcher_debug.webp
    │       │       ├── ic_launcher_debug_foreground.webp
    │       │       ├── ic_launcher_debug_round.webp
    │       │       ├── ic_launcher_foreground.webp
    │       │       ├── ic_launcher_round.webp
    │       │       ├── ic_launcher_xxt.webp
    │       │       ├── ic_launcher_xxt_background.webp
    │       │       ├── ic_launcher_xxt_foreground.webp
    │       │       └── ic_launcher_xxt_round.webp
    │       │   ├── navigation
    │       │       ├── nav_main.xml
    │       │       └── nav_settings.xml
    │       │   ├── raw
    │       │       └── akarin.png
    │       │   ├── values-en
    │       │       └── strings.xml
    │       │   ├── values-ja
    │       │       └── strings.xml
    │       │   ├── values-land
    │       │       └── dimens.xml
    │       │   ├── values-night
    │       │       └── colors.xml
    │       │   ├── values-zh-rCN
    │       │       └── strings.xml
    │       │   ├── values
    │       │       ├── arrays.xml
    │       │       ├── bools.xml
    │       │       ├── colors.xml
    │       │       ├── dimens.xml
    │       │       ├── ic_launcher_background.xml
    │       │       ├── ic_launcher_calc_background.xml
    │       │       ├── ic_launcher_cornhub_background.xml
    │       │       ├── ids.xml
    │       │       ├── strings.xml
    │       │       └── themes.xml
    │       │   └── xml
    │       │       ├── backup_rules.xml
    │       │       ├── data_extraction_rules.xml
    │       │       ├── file_paths.xml
    │       │       ├── setting_mpv_player.xml
    │       │       ├── settings_download.xml
    │       │       ├── settings_h_keyframe.xml
    │       │       ├── settings_home.xml
    │       │       ├── settings_network.xml
    │       │       └── settings_player.xml
    │   └── test
    │       └── java
    │           └── com
    │               └── yenaly
    │                   └── han1meviewer
    │                       └── ExampleUnitTest.kt
├── build.gradle.kts
├── buildSrc
    ├── build.gradle.kts
    └── src
    │   └── main
    │       └── java
    │           └── Config.kt
├── develop
├── gradle.properties
├── gradle
    ├── libs.versions.toml
    └── wrapper
    │   ├── gradle-wrapper.jar
    │   └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── icon
    ├── icon_han1me_viewer-rurires.png
    ├── icon_han1me_viewer-rurires.svg
    └── icon_transparent_han1me_viewer-rurires.png
├── readme_01.png
├── readme_02.png
├── readme_03.png
├── readme_04.png
├── readme_05.png
├── readme_06.png
├── readme_07.png
├── settings.gradle.kts
└── yenaly_libs
    ├── .gitignore
    ├── build.gradle.kts
    ├── consumer-rules.pro
    ├── proguard-rules.pro
    └── src
        ├── androidTest
            └── java
            │   └── com
            │       └── yenaly
            │           └── yenaly_libs
            │               └── ExampleInstrumentedTest.kt
        ├── main
            ├── AndroidManifest.xml
            ├── java
            │   └── com
            │   │   └── yenaly
            │   │       └── yenaly_libs
            │   │           ├── ActivityManager.kt
            │   │           ├── SingletonHolder.kt
            │   │           ├── base
            │   │               ├── IViewBinding.kt
            │   │               ├── YenalyActivity.kt
            │   │               ├── YenalyApplication.kt
            │   │               ├── YenalyBottomSheetDialogFragment.kt
            │   │               ├── YenalyCrashHandler.kt
            │   │               ├── YenalyFragment.kt
            │   │               ├── YenalyInitializer.kt
            │   │               ├── YenalyViewModel.kt
            │   │               ├── dialog
            │   │               │   └── YenalyCrashDialogActivity.kt
            │   │               ├── frame
            │   │               │   ├── FrameActivity.kt
            │   │               │   └── FrameFragment.kt
            │   │               ├── preference
            │   │               │   ├── LongClickablePreference.kt
            │   │               │   ├── LongClickableSwitchPreference.kt
            │   │               │   └── MaterialSwitchPreference.kt
            │   │               ├── settings
            │   │               │   ├── YenalySettingsActivity.kt
            │   │               │   └── YenalySettingsFragment.kt
            │   │               └── view
            │   │               │   ├── NestedScrollableHost.kt
            │   │               │   └── RecyclerViewAtViewPager2.kt
            │   │           └── utils
            │   │               ├── ActivityResultUtil.kt
            │   │               ├── AppUtil.kt
            │   │               ├── ArrayUtil.kt
            │   │               ├── Base64Util.kt
            │   │               ├── ClipboardUtil.kt
            │   │               ├── ContextUtil.kt
            │   │               ├── DeviceUtil.kt
            │   │               ├── FileUtil.kt
            │   │               ├── ImageUtil.kt
            │   │               ├── LanguageHelper.kt
            │   │               ├── LogUtil.kt
            │   │               ├── OrientationManager.kt
            │   │               ├── ResourceUtil.kt
            │   │               ├── ShareUtil.kt
            │   │               ├── SharedPreferencesUtil.kt
            │   │               ├── SingleFlowLaunch.kt
            │   │               ├── SnackBarUtil.kt
            │   │               ├── SystemStatusUtil.kt
            │   │               ├── TextUtil.kt
            │   │               ├── ToastUtil.kt
            │   │               ├── UnicodeUtil.kt
            │   │               ├── UriUtil.kt
            │   │               ├── _AesUtil.kt
            │   │               ├── _GsonUtil.kt
            │   │               ├── _IntentUtil.kt
            │   │               ├── _LazyUtil.kt
            │   │               ├── span
            │   │                   ├── SpannedTextGenerator.kt
            │   │                   ├── YenalyImageSpan.kt
            │   │                   └── YenalyQuoteSpan.kt
            │   │               └── view
            │   │                   ├── AppBarLayoutStateChangeListener.kt
            │   │                   ├── BottomNavViewMediator.kt
            │   │                   ├── BottomNavViewUtil.kt
            │   │                   ├── BottomNavigationViewMediator.kt
            │   │                   ├── ClickUtil.kt
            │   │                   ├── EditTextUtil.kt
            │   │                   ├── SimpleBottomNavViewMediator.kt
            │   │                   ├── SimpleFragmentStateAdapter.kt
            │   │                   ├── TabLayoutUtil.kt
            │   │                   ├── ViewPagerUtil.kt
            │   │                   ├── ViewUtil.kt
            │   │                   └── YenalyHideBottomViewOnScrollBehavior.kt
            └── res
            │   ├── layout
            │       ├── yenaly_activity_crash_dialog.xml
            │       ├── yenaly_activity_settings.xml
            │       └── yenaly_preference_switch_widget.xml
            │   ├── values
            │       ├── ids.xml
            │       ├── strings.xml
            │       └── styles.xml
            │   └── xml
            │       └── http_network_config.xml
        └── test
            └── java
                └── com
                    └── yenaly
                        └── yenaly_libs
                            └── UtilUnitTest.kt
/.github/ISSUE_TEMPLATE/custom.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | name: 自定義問題
 3 | about: 描述此問題的目的
 4 | title: ''
 5 | labels: ''
 6 | assignees: ''
 7 | 
 8 | ---
 9 | 
10 | 
11 | 
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
 1 | name: ⭐ 功能請求
 2 | description: 建議一個功能來改善 Han1meViewer
 3 | labels: [ good idea | 好主意 ]
 4 | body:
 5 | 
 6 |   - type: textarea
 7 |     id: feature-description
 8 |     attributes:
 9 |       label: 描述您建議的功能
10 |       description: 如何改進 Han1meViewer?
11 |       placeholder: |
12 |         Example:
13 |           "我想要bla bla bla..."
14 |     validations:
15 |       required: true
16 | 
17 |   - type: textarea
18 |     id: other-details
19 |     attributes:
20 |       label: 其他你想講的
21 |       description: 比如哪些軟體有您所說的類似功能,我方便偷過來
22 |       placeholder: |
23 |         其他補充資訊
24 | 
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/bug_fix.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | name: "Bug 修復"
 3 | about: "用於提交 Bug 修復的拉取請求"
 4 | title: "[BUGFIX] <簡短描述>"
 5 | labels: "bug"
 6 | assignees: ""
 7 | ---
 8 | 
 9 | ### 描述
10 | 
11 | 
12 | 
13 | ### 修復方法
14 | 
15 | 
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/feature_addition.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | name: "新功能添加"
 3 | about: "用於提交新功能的拉取請求"
 4 | title: "[FEATURE] <簡短描述>"
 5 | labels: "good idea | 好主意"
 6 | assignees: ""
 7 | ---
 8 | 
 9 | ### 功能描述
10 | 
11 | 
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/submit_h_keyframe.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | name: "提交關鍵H幀"
 3 | about: "分享你的關鍵H幀"
 4 | title: "[HKeyframe] <簡短描述>"
 5 | labels: "𝐇Keyframe"
 6 | assignees: ""
 7 | ---
 8 | 
 9 | ### 關鍵H幀描述
10 | 
11 | 
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 |   - package-ecosystem: gradle
4 |     directory: "/" # Location of package manifests
5 |     schedule:
6 |       interval: weekly
--------------------------------------------------------------------------------
/.github/workflows/pr_check.yml:
--------------------------------------------------------------------------------
 1 | permissions:
 2 |   contents: read
 3 | name: Pull Request Check
 4 | 
 5 | on:
 6 |   pull_request:
 7 |     branches: [ "main" ]
 8 |     paths-ignore:
 9 |       - "**.md"
10 | 
11 | jobs:
12 |   check:
13 | 
14 |     runs-on: ubuntu-latest
15 | 
16 |     steps:
17 |       - name: Checkout
18 |         uses: actions/checkout@v4
19 | 
20 |       - name: Set up JDK 21
21 |         uses: actions/setup-java@v4
22 |         with:
23 |           java-version: '21'
24 |           distribution: 'temurin'
25 |           cache: gradle
26 | 
27 |       - name: Load Google Services File
28 |         env:
29 |           DATA: ${{ secrets.GOOGLE_SERVICES_JSON_BASE64 }}
30 |         run: echo $DATA | base64 -di > app/google-services.json
31 | 
32 |       - name: Grant execute permission for gradlew
33 |         run: chmod +x gradlew
34 | 
35 |       - name: Build
36 |         run: ./gradlew buildDebug -x lint
37 | 
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
 1 | *.iml
 2 | .gradle
 3 | /local.properties
 4 | /.idea/caches
 5 | /.idea/libraries
 6 | /.idea/modules.xml
 7 | /.idea/workspace.xml
 8 | /.idea/navEditor.xml
 9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /captures
12 | .externalNativeBuild
13 | .cxx
14 | local.properties
15 | /app/ha1_github_token.txt
16 | /app/release/
17 | /app/debug/
18 | # Android Studio 项目文件
19 | /.idea/
20 | /.gradle/
21 | /build/
22 | /captures/
23 | 
24 | # Gradle 缓存
25 | .gradle/
26 | gradle-app.setting
27 | !gradle-wrapper.jar
28 | 
29 | # 构建输出
30 | **/build/
31 | **/outputs/
32 | 
33 | # 本地配置文件
34 | **/google-services.json
35 | **/app/google-services.json
36 | 
37 | # 系统文件
38 | Thumbs.db
39 | 
40 | # 日志和临时文件
41 | *.log
42 | *.tmp
43 | *.swp
44 | 
45 | # 开发环境文件
46 | .env
47 | .secrets/
48 | 
49 | # Kotlin 相关
50 | .kotlin/
51 | .kotlin_dependencies
52 | 
53 | # 其他忽略项
54 | **/extra/
55 | **/test-output/
56 | **/reports/
57 | **/profiles/
58 | 
59 | # 特定项目忽略
60 | /yenaly_libs/local/
61 | /icon/temp/
62 | 
63 | # 但保留gradle wrapper
64 | !gradle/wrapper/gradle-wrapper.jar
65 | 
66 | # 忽略所有构建输出的 APK 文件
67 | **/build/outputs/apk/
68 | **/*.apk
69 | 
70 | # 忽略 debug 测试构建
71 | /app/build/outputs/apk/debug/
--------------------------------------------------------------------------------
/HanimeAnnouncementManagerWebUI/PermitAdmin.py:
--------------------------------------------------------------------------------
 1 | import firebase_admin
 2 | from firebase_admin import credentials, auth
 3 | 
 4 | cred = credentials.Certificate("serviceAccountKey.json")
 5 | firebase_admin.initialize_app(cred)
 6 | 
 7 | # 需要设置权限的用户 UID
 8 | uid = ''
 9 | 
10 | # 设置自定义声明
11 | auth.set_custom_user_claims(uid, {'isAdmin' :True})
12 | 
13 | print('成功设置管理员权限')
14 | 
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /keystore/ha1_keystore_password.txt
3 | /ha1_github_token.txt
4 | 
--------------------------------------------------------------------------------
/app/keystore/Han1meViewerKeystore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/keystore/Han1meViewerKeystore.jks
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/yenaly/han1meviewer/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer
 2 | 
 3 | import androidx.test.platform.app.InstrumentationRegistry
 4 | import androidx.test.ext.junit.runners.AndroidJUnit4
 5 | 
 6 | import org.junit.Test
 7 | import org.junit.runner.RunWith
 8 | 
 9 | import org.junit.Assert.*
10 | 
11 | /**
12 |  * Instrumented test, which will execute on an Android device.
13 |  *
14 |  * See [testing documentation](http://d.android.com/tools/testing).
15 |  */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 |     @Test
19 |     fun useAppContext() {
20 |         // Context of the app under test.
21 |         val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 |         assertEquals("com.yenaly.han1meviewer", appContext.packageName)
23 |     }
24 | }
--------------------------------------------------------------------------------
/app/src/debug/res/values/strings.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     HANi [Debug]
4 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/12444.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "12444",
 3 |   "group": "思春期SEX",
 4 |   "title": "思春期SEX#1",
 5 |   "episode": 1,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 482500,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 545000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 832000,
18 |       "prompt": null
19 |     }
20 |   ]
21 | }
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/14463.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "14463",
 3 |   "group": "思春期SEX",
 4 |   "title": "思春期SEX#3",
 5 |   "episode": 3,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 311500,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 432500,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 824000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 861300,
22 |       "prompt": null
23 |     }
24 |   ]
25 | }
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/21806.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "21806",
 3 |   "group": "思春期SEX",
 4 |   "title": "思春期SEX#4",
 5 |   "episode": 4,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 481000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 657700,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 742700,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 813000,
22 |       "prompt": null
23 |     }
24 |   ]
25 | }
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/22068.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "22068",
 3 |   "group": "思春期SEX",
 4 |   "title": "思春期SEX#2",
 5 |   "episode": 2,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 324000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 602000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 734000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 816000,
22 |       "prompt": null
23 |     }
24 |   ]
25 | }
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/37176.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "37176",
 3 |   "group": "援助交配",
 4 |   "title": "援助交配#1",
 5 |   "episode": 1,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 363600,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 633000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 796000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 881700,
22 |       "prompt": null
23 |     }
24 |   ]
25 | }
26 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/37177.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "37177",
 3 |   "group": "援助交配",
 4 |   "title": "援助交配#2",
 5 |   "episode": 2,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 376000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 420000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 600000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 774000,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 800000,
26 |       "prompt": null
27 |     },
28 |     {
29 |       "position": 840000,
30 |       "prompt": null
31 |     },
32 |     {
33 |       "position": 856500,
34 |       "prompt": null
35 |     }
36 |   ]
37 | }
38 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/37178.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "37178",
 3 |   "group": "援助交配",
 4 |   "title": "援助交配#3",
 5 |   "episode": 3,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 239000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 307000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 439000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 641000,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 820000,
26 |       "prompt": null
27 |     }
28 |   ]
29 | }
30 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/37179.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "37179",
 3 |   "group": "援助交配",
 4 |   "title": "援助交配#4",
 5 |   "episode": 4,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 36000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 480000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 570000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 655000,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 800000,
26 |       "prompt": null
27 |     }
28 |   ]
29 | }
30 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/37220.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "37220",
 3 |   "group": "今泉家似乎變成辣妹的聚會所",
 4 |   "title": "今泉家似乎變成辣妹的聚會所#1",
 5 |   "episode": 1,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 265000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 403000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 493000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 540000,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 604000,
26 |       "prompt": null
27 |     },
28 |     {
29 |       "position": 725000,
30 |       "prompt": null
31 |     },
32 |     {
33 |       "position": 769000,
34 |       "prompt": null
35 |     }
36 |   ]
37 | }
38 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/37221.json:
--------------------------------------------------------------------------------
 1 | 
 2 | {
 3 |   "videoCode": "37221",
 4 |   "group": "今泉家似乎變成辣妹的聚會所",
 5 |   "title": "今泉家似乎變成辣妹的聚會所#2",
 6 |   "episode": 2,
 7 |   "author": "NeKoOuO",
 8 |   "keyframes": [
 9 |     {
10 |       "position": 278500,
11 |       "prompt": null
12 |     },
13 |     {
14 |       "position": 403000,
15 |       "prompt": null
16 |     },
17 |     {
18 |       "position": 510000,
19 |       "prompt": null
20 |     },
21 |     {
22 |       "position": 627000,
23 |       "prompt": null
24 |     },
25 |     {
26 |       "position": 836000,
27 |       "prompt": null
28 |     }
29 |   ]
30 | }
31 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/38387.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "38387",
 3 |   "group": "援助交配",
 4 |   "title": "援助交配#5",
 5 |   "episode": 5,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 335000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 652000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 817000,
18 |       "prompt": null
19 |     }
20 |   ]
21 | }
22 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/38389.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "38389",
 3 |   "group": "闇憑村",
 4 |   "title": "闇憑村#1",
 5 |   "episode": 1,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 290700,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 428000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 510000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 592000,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 798000,
26 |       "prompt": null
27 |     },
28 |     {
29 |       "position": 934500,
30 |       "prompt": null
31 |     }
32 |   ]
33 | }
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/38457.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "38457",
 3 |   "group": "闇憑村",
 4 |   "title": "闇憑村#2",
 5 |   "episode": 2,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 345300,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 458000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 502500,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 507500,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 549000,
26 |       "prompt": null
27 |     },
28 |     {
29 |       "position": 562000,
30 |       "prompt": null
31 |     },
32 |     {
33 |       "position": 574000,
34 |       "prompt": null
35 |     },
36 |     {
37 |       "position": 686000,
38 |       "prompt": null
39 |     },
40 |     {
41 |       "position": 779500,
42 |       "prompt": null
43 |     },
44 |     {
45 |       "position": 868000,
46 |       "prompt": null
47 |     }
48 |   ]
49 | }
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/38461.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "38461",
 3 |   "group": "援助交配",
 4 |   "title": "援助交配#6",
 5 |   "episode": 6,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 86000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 638000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 755000,
18 |       "prompt": null
19 |     }
20 |   ]
21 | }
22 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/39192.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "39192",
 3 |   "group": "援助交配",
 4 |   "title": "援助交配#7",
 5 |   "episode": 7,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 260000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 413500,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 520000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 564000,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 656000,
26 |       "prompt": null
27 |     },
28 |     {
29 |       "position": 802000,
30 |       "prompt": null
31 |     }
32 |   ]
33 | }
34 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/39305.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "39305",
 3 |   "group": "到了異世界就拿出性本事",
 4 |   "title": "到了異世界就拿出性本事#1",
 5 |   "episode": 1,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 387500,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 457000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 712500,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 829500,
22 |       "prompt": null
23 |     }
24 |   ]
25 | }
26 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/39306.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "39306",
 3 |   "group": "到了異世界就拿出性本事",
 4 |   "title": "到了異世界就拿出性本事#2",
 5 |   "episode": 2,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 254000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 405000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 502000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 740500,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 914000,
26 |       "prompt": null
27 |     }
28 |   ]
29 | }
30 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/39468.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "39468",
 3 |   "group": "援助交配",
 4 |   "title": "援助交配#8",
 5 |   "episode": 8,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 223000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 324000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 608000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 848000,
22 |       "prompt": null
23 |     }
24 |   ]
25 | }
26 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/39811.json:
--------------------------------------------------------------------------------
 1 | 
 2 | {
 3 |   "videoCode": "39811",
 4 |   "group": "今泉家似乎變成辣妹的聚會所",
 5 |   "title": "今泉家似乎變成辣妹的聚會所#4",
 6 |   "episode": 4,
 7 |   "author": "NeKoOuO",
 8 |   "keyframes": [
 9 |     {
10 |       "position": 175000,
11 |       "prompt": null
12 |     },
13 |     {
14 |       "position": 425000,
15 |       "prompt": null
16 |     },
17 |     {
18 |       "position": 629000,
19 |       "prompt": null
20 |     },
21 |     {
22 |       "position": 825000,
23 |       "prompt": null
24 |     }
25 |   ]
26 | }
27 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/84717.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "84717",
 3 |   "group": "初戀時間",
 4 |   "title": "初戀時間#1",
 5 |   "episode": 1,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 72000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 427270,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 499500,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 650000,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 840500,
26 |       "prompt": null
27 |     }
28 |   ]
29 | }
30 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/84718.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "84718",
 3 |   "group": "初戀時間",
 4 |   "title": "初戀時間#2",
 5 |   "episode": 2,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 462000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 576500,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 588000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 678500,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 823430,
26 |       "prompt": null
27 |     }
28 |   ]
29 | }
30 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/85926.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "85926",
 3 |   "group": "初戀時間",
 4 |   "title": "初戀時間#3",
 5 |   "episode": 3,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 438000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 602500,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 822500,
18 |       "prompt": null
19 |     }
20 |   ]
21 | }
22 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/85927.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "85927",
 3 |   "group": "初戀時間",
 4 |   "title": "初戀時間#4",
 5 |   "episode": 4,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 376000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 474950,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 633500,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 715000,
22 |       "prompt": null
23 |     }
24 |   ]
25 | }
26 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/87968.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "87968",
 3 |   "group": "到了異世界就拿出性本事",
 4 |   "title": "到了異世界就拿出性本事#3",
 5 |   "episode": 3,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 229500,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 445500,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 637200,
18 |       "prompt": null
19 |     }
20 |   ]
21 | }
22 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/87969.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "87969",
 3 |   "group": "到了異世界就拿出性本事",
 4 |   "title": "到了異世界就拿出性本事#4",
 5 |   "episode": 4,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 474500,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 791000,
14 |       "prompt": null
15 |     }
16 |   ]
17 | }
18 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/89087.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "89087",
 3 |   "group": "初戀時間",
 4 |   "title": "初戀時間#5",
 5 |   "episode": 5,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 482500,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 500500,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 556000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 777300,
22 |       "prompt": null
23 |     }
24 |   ]
25 | }
26 | 
--------------------------------------------------------------------------------
/app/src/main/assets/h_keyframes/89088.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "videoCode": "89088",
 3 |   "group": "初戀時間",
 4 |   "title": "初戀時間#6",
 5 |   "episode": 6,
 6 |   "author": "NeKoOuO",
 7 |   "keyframes": [
 8 |     {
 9 |       "position": 304000,
10 |       "prompt": null
11 |     },
12 |     {
13 |       "position": 387000,
14 |       "prompt": null
15 |     },
16 |     {
17 |       "position": 546000,
18 |       "prompt": null
19 |     },
20 |     {
21 |       "position": 644000,
22 |       "prompt": null
23 |     },
24 |     {
25 |       "position": 710000,
26 |       "prompt": null
27 |     },
28 |     {
29 |       "position": 808000,
30 |       "prompt": null
31 |     }
32 |   ]
33 | }
34 | 
--------------------------------------------------------------------------------
/app/src/main/assets/report_reason.json:
--------------------------------------------------------------------------------
 1 | [
 2 |   {
 3 |     "lang": {
 4 |       "zh-rCN": "煽动仇恨或恶意内容",
 5 |       "en": "Inciting hatred or malicious content",
 6 |       "zh-rTW": "煽動仇恨或惡意內容"
 7 |     },
 8 |     "reason_key": "煽動仇恨或惡意內容"
 9 |   },
10 |   {
11 |     "lang": {
12 |       "zh-rCN": "暴力或令人反感的内容",
13 |       "en": "Violent or offensive content",
14 |       "zh-rTW": "暴力或令人反感的內容"
15 |     },
16 |     "reason_key": "暴力或令人反感的內容"
17 |   },
18 |   {
19 |     "lang": {
20 |       "zh-rCN": "广告内容或垃圾内容",
21 |       "en": "Advertising content or spam",
22 |       "zh-rTW": "廣告內容或垃圾內容"
23 |     },
24 |     "reason_key": "廣告內容或垃圾內容"
25 |   },
26 |   {
27 |     "lang": {
28 |       "zh-rCN": "其他检举理由",
29 |       "en": "Other reporting reasons",
30 |       "zh-rTW": "其他檢舉理由"
31 |     },
32 |     "reason_key": "其他檢舉理由"
33 |   }
34 | ]
--------------------------------------------------------------------------------
/app/src/main/assets/search_options/release_date.json:
--------------------------------------------------------------------------------
 1 | [
 2 |   {
 3 |     "lang": {
 4 |       "zh-rCN": "全部",
 5 |       "en": "All",
 6 |       "zh-rTW": "全部"
 7 |     },
 8 |     "search_key": null
 9 |   },
10 |   {
11 |     "lang": {
12 |       "zh-rCN": "过去24小时",
13 |       "en": "Last 24 hours",
14 |       "zh-rTW": "過去24小時"
15 |     },
16 |     "search_key": "過去 24 小時"
17 |   },
18 |   {
19 |     "lang": {
20 |       "zh-rCN": "过去2天",
21 |       "en": "Last 2 days",
22 |       "zh-rTW": "過去2天"
23 |     },
24 |     "search_key": "過去 2 天"
25 |   },
26 |   {
27 |     "lang": {
28 |       "zh-rCN": "过去1周",
29 |       "en": "Last week",
30 |       "zh-rTW": "過去1週"
31 |     },
32 |     "search_key": "過去 1 週"
33 |   },
34 |   {
35 |     "lang": {
36 |       "zh-rCN": "过去1个月",
37 |       "en": "Last month",
38 |       "zh-rTW": "過去1個月"
39 |     },
40 |     "search_key": "過去 1 個月"
41 |   },
42 |   {
43 |     "lang": {
44 |       "zh-rCN": "过去3个月",
45 |       "en": "Last 3 months",
46 |       "zh-rTW": "過去3個月"
47 |     },
48 |     "search_key": "過去 3 個月"
49 |   },
50 |   {
51 |     "lang": {
52 |       "zh-rCN": "过去1年",
53 |       "en": "Past year",
54 |       "zh-rTW": "過去1年"
55 |     },
56 |     "search_key": "過去 1 年"
57 |   }
58 | ]
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/HCrashHandler.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer
 2 | 
 3 | import com.yenaly.yenaly_libs.ActivityManager
 4 | 
 5 | object HCrashHandler : Thread.UncaughtExceptionHandler {
 6 |     override fun uncaughtException(t: Thread, e: Throwable) {
 7 |         e.printStackTrace()
 8 |         ActivityManager.restart(killProcess = true)
 9 |     }
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/HInitializer.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer
 2 | 
 3 | import android.content.Context
 4 | import com.yenaly.yenaly_libs.base.YenalyInitializer
 5 | 
 6 | class HInitializer : YenalyInitializer() {
 7 |     override fun create(context: Context) {
 8 |         super.create(context)
 9 |         // 用于处理 Firebase Crashlytics 初始化
10 |         Thread.setDefaultUncaughtExceptionHandler(HCrashHandler)
11 |     }
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/dao/CheckInRecordDao.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.dao
 2 | 
 3 | import androidx.room.Dao
 4 | import androidx.room.Insert
 5 | import androidx.room.OnConflictStrategy
 6 | import androidx.room.Query
 7 | import com.yenaly.han1meviewer.logic.entity.CheckInRecordEntity
 8 | 
 9 | @Dao
10 | interface CheckInRecordDao {
11 |     @Query("SELECT * FROM check_in_records WHERE date = :date")
12 |     suspend fun getRecord(date: String): CheckInRecordEntity?
13 | 
14 |     @Insert(onConflict = OnConflictStrategy.REPLACE)
15 |     suspend fun insertOrUpdate(record: CheckInRecordEntity)
16 | 
17 |     @Query("SELECT COUNT(*) FROM check_in_records WHERE count > 0 AND date LIKE :yearMonth || '%'")
18 |     suspend fun getMonthlyCheckedDays(yearMonth: String): Int
19 | 
20 |     @Query("SELECT * FROM check_in_records WHERE date BETWEEN :start AND :end")
21 |     suspend fun getRecordsBetween(start: String, end: String): List
22 | 
23 |     @Query("SELECT SUM(count) FROM check_in_records WHERE date LIKE :yearMonth || '%'")
24 |     suspend fun getMonthlyCheckInTotal(yearMonth: String): Int?
25 | 
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/dao/CheckInRecordDatabase.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.dao
 2 | 
 3 | import android.content.Context
 4 | import androidx.room.Database
 5 | import androidx.room.Room
 6 | import androidx.room.RoomDatabase
 7 | import com.yenaly.han1meviewer.logic.entity.CheckInRecordEntity
 8 | 
 9 | @Database(
10 |     entities = [CheckInRecordEntity::class],
11 |     version = 1,
12 |     exportSchema = false
13 | )
14 | abstract class CheckInRecordDatabase : RoomDatabase() {
15 |     abstract fun checkInDao(): CheckInRecordDao
16 | 
17 |     companion object {
18 |         @Volatile
19 |         private var INSTANCE: CheckInRecordDatabase? = null
20 | 
21 |         fun getDatabase(context: Context): CheckInRecordDatabase {
22 |             return INSTANCE ?: synchronized(this) {
23 |                 val instance = Room.databaseBuilder(
24 |                     context.applicationContext,
25 |                     CheckInRecordDatabase::class.java,
26 |                     "check_in_records"
27 |                 ).build()
28 |                 INSTANCE = instance
29 |                 instance
30 |             }
31 |         }
32 |     }
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/dao/MiscellanyDatabase.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.dao
 2 | 
 3 | import androidx.room.Database
 4 | import androidx.room.Room
 5 | import androidx.room.RoomDatabase
 6 | import com.yenaly.han1meviewer.logic.entity.HKeyframeEntity
 7 | import com.yenaly.yenaly_libs.utils.applicationContext
 8 | 
 9 | /**
10 |  * 这是各种 有数据库需求的小功能 的聚集地,
11 |  * 如果这个功能需要数据库就放到这里。
12 |  *
13 |  * @project Han1meViewer
14 |  * @author Yenaly Liew
15 |  * @time 2023/11/12 012 12:28
16 |  */
17 | @Database(
18 |     entities = [HKeyframeEntity::class],
19 |     version = 1, exportSchema = false
20 | )
21 | abstract class MiscellanyDatabase : RoomDatabase() {
22 | 
23 |     abstract val hKeyframeDao: HKeyframeDao
24 | 
25 |     companion object {
26 |         val instance by lazy {
27 |             Room.databaseBuilder(
28 |                 applicationContext,
29 |                 MiscellanyDatabase::class.java,
30 |                 "miscellany.db"
31 |             ).build()
32 |         }
33 |     }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/dao/download/DownloadCategoryDao.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.dao.download
 2 | 
 3 | import androidx.room.Dao
 4 | import androidx.room.Query
 5 | import androidx.room.RewriteQueriesToDropUnusedColumns
 6 | import androidx.room.Transaction
 7 | import com.yenaly.han1meviewer.logic.entity.download.DownloadCategoryEntity
 8 | import com.yenaly.han1meviewer.logic.entity.download.HanimeDownloadEntity
 9 | import kotlinx.coroutines.flow.Flow
10 | 
11 | @Dao
12 | abstract class DownloadCategoryDao {
13 |     @RewriteQueriesToDropUnusedColumns
14 |     @Transaction
15 |     @Query(
16 |         "SELECT * FROM HanimeDownloadEntity " +
17 |                 "INNER JOIN HanimeCategoryCrossRef ON HanimeDownloadEntity.id = HanimeCategoryCrossRef.videoId " +
18 |                 "WHERE HanimeCategoryCrossRef.categoryId = :categoryId AND HanimeDownloadEntity.downloadedLength == HanimeDownloadEntity.length"
19 |     )
20 |     abstract fun getVideosForCategory(categoryId: Int): Flow>
21 | 
22 |     @Query("SELECT * FROM DownloadCategoryEntity")
23 |     abstract fun getAllCategories(): Flow>
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/entity/CheckInRecordEntity.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.entity
 2 | 
 3 | import androidx.room.Entity
 4 | import androidx.room.PrimaryKey
 5 | 
 6 | @Entity(tableName = "check_in_records")
 7 | data class CheckInRecordEntity(
 8 |     @PrimaryKey val date: String,
 9 |     val count: Int
10 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/entity/SearchHistoryEntity.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.entity
 2 | 
 3 | import androidx.room.Entity
 4 | import androidx.room.PrimaryKey
 5 | 
 6 | /**
 7 |  * @project Hanime1
 8 |  * @author Yenaly Liew
 9 |  * @time 2022/06/22 022 18:16
10 |  */
11 | @Entity
12 | data class SearchHistoryEntity(
13 |     val query: String,
14 |     @PrimaryKey(autoGenerate = true)
15 |     val id: Int = 0
16 | )
17 | 
18 | @Entity(tableName = "HanimeAdvancedSearchHistory")
19 | data class HanimeAdvancedSearchHistoryEntity(
20 |     @PrimaryKey(autoGenerate = true) val id: Long = 0,
21 |     val query: String? = null,
22 |     val genre: String? = null,
23 |     val sort: String? = null,
24 |     val broad: Boolean? = null,
25 |     val date: String? = null,
26 |     val duration: String? = null,
27 |     val tags: String? = null,
28 |     val brands: String? = null,
29 |     val createdAt: Long = System.currentTimeMillis()
30 | )
31 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/entity/WatchHistoryEntity.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.entity
 2 | 
 3 | import androidx.room.Entity
 4 | import androidx.room.PrimaryKey
 5 | 
 6 | /**
 7 |  * @project Han1meViewer
 8 |  * @author Yenaly Liew
 9 |  * @time 2022/07/02 002 13:13
10 |  */
11 | @Entity
12 | data class WatchHistoryEntity(
13 |     val coverUrl: String,
14 |     val title: String,
15 |     val releaseDate: Long,
16 |     val watchDate: Long,
17 |     val videoCode: String,
18 |     val progress: Long = 0L,
19 |     @PrimaryKey(autoGenerate = true)
20 |     val id: Int = 0,
21 | ) {
22 | 
23 |     val releaseDateDays: Int
24 |         get() = (releaseDate / (24 * 60 * 60 * 1000)).toInt()
25 | }
26 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/entity/download/DownloadCategoryEntity.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.entity.download
 2 | 
 3 | import androidx.room.Entity
 4 | import androidx.room.PrimaryKey
 5 | 
 6 | @Entity
 7 | data class DownloadCategoryEntity(
 8 |     val name: String,
 9 |     @PrimaryKey(autoGenerate = true)
10 |     val id: Int = 0,
11 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/entity/download/HanimeCategoryCrossRef.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.entity.download
 2 | 
 3 | import androidx.room.Entity
 4 | import androidx.room.Index
 5 | 
 6 | @Entity(
 7 |     primaryKeys = ["videoId", "categoryId"],
 8 |     indices = [Index(value = ["categoryId"])],
 9 | )
10 | data class HanimeCategoryCrossRef(
11 |     val videoId: Int,
12 |     val categoryId: Int,
13 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/entity/download/VideoWithCategories.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.entity.download
 2 | 
 3 | import androidx.room.Embedded
 4 | import androidx.room.Junction
 5 | import androidx.room.Relation
 6 | 
 7 | data class VideoWithCategories(
 8 |     @Embedded
 9 |     val video: HanimeDownloadEntity,
10 |     @Relation(
11 |         parentColumn = "id",
12 |         entityColumn = "id",
13 |         associateBy = Junction(
14 |             value = HanimeCategoryCrossRef::class,
15 |             parentColumn = "videoId",
16 |             entityColumn = "categoryId"
17 |         )
18 |     )
19 |     val categories: List,
20 | )
21 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/exception/CloudFlareBlockedException.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.exception
 2 | 
 3 | import com.yenaly.han1meviewer.R
 4 | 
 5 | /**
 6 |  * 检测到爬虫被封鎖
 7 |  *
 8 |  * @project Han1meViewer
 9 |  * @author Yenaly Liew
10 |  * @time 2023/08/07 007 12:45
11 |  */
12 | open class CloudFlareBlockedException(reason: String) : RuntimeException(reason) {
13 |     companion object {
14 |         val localizedMessages = intArrayOf(
15 |             R.string.website_blocked_msg,
16 |             R.string.website_blocked_msg_2,
17 |             R.string.website_blocked_msg_3,
18 |         )
19 |     }
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/exception/HanimeNotFoundException.kt:
--------------------------------------------------------------------------------
1 | package com.yenaly.han1meviewer.logic.exception
2 | 
3 | /**
4 |  * @project Han1meViewer
5 |  * @author Yenaly Liew
6 |  * @time 2023/08/07 007 13:08
7 |  */
8 | class HanimeNotFoundException(reason: String) : RuntimeException(reason)
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/exception/IPBlockedException.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.exception
 2 | 
 3 | /**
 4 |  * IP被封鎖
 5 |  *
 6 |  * @project Han1meViewer
 7 |  * @author Yenaly Liew
 8 |  * @time 2023/08/07 007 12:40
 9 |  */
10 | class IPBlockedException(reason: String) : CloudFlareBlockedException(reason)
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/exception/ParseException.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.exception
 2 | 
 3 | /**
 4 |  * 解析錯誤
 5 |  *
 6 |  * @project Han1meViewer
 7 |  * @author Yenaly Liew
 8 |  * @time 2023/08/05 005 16:20
 9 |  */
10 | class ParseException : RuntimeException {
11 | 
12 |     constructor(
13 |         funcName: String,
14 |         varName: String
15 |     ) : super("[Parse::$funcName => $varName] parse error!")
16 | 
17 |     constructor(reason: String) : super(reason)
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/HanimeInfo.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model
 2 | 
 3 | /**
 4 |  * @project Han1meViewer
 5 |  * @author Yenaly Liew
 6 |  */
 7 | interface HanimeInfoType : MultiItemEntity
 8 | 
 9 | /**
10 |  * @project Han1meViewer
11 |  * @author Yenaly Liew
12 |  * @time 2022/06/08 008 22:56
13 |  */
14 | data class HanimeInfo(
15 |     override val title: String,
16 |     override val coverUrl: String,
17 |     override val videoCode: String,
18 |     override val duration: String? = null,
19 |     val artist: String? = null,
20 |     override val views: String? = null,
21 |     val uploadTime: String? = null,
22 |     val genre: String? = null,
23 | 
24 |     val isPlaying: Boolean = false, // for video playlist only.
25 | 
26 |     override var itemType: Int,
27 |     override val reviews: String? = "",
28 |     override val currentArtist: String? = "",
29 |     val watched: Boolean ?= false,
30 | ): VideoItemType , HanimeInfoType {
31 |     companion object {
32 |         const val NORMAL = 0
33 |         const val SIMPLIFIED = 1
34 |     }
35 | }
36 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/HanimePreview.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model
 2 | 
 3 | /**
 4 |  * @project Hanime1
 5 |  * @author Yenaly Liew
 6 |  * @time 2022/06/24 024 15:05
 7 |  */
 8 | data class HanimePreview(
 9 |     val headerPicUrl: String?,
10 |     val hasPrevious: Boolean = false,
11 |     val hasNext: Boolean = false,
12 |     val latestHanime: List,
13 |     val previewInfo: List,
14 | ) {
15 |     data class PreviewInfo(
16 |         val title: String?,
17 |         val videoTitle: String?,
18 |         val coverUrl: String?,
19 |         val introduction: String?,
20 |         val brand: String?,
21 |         val releaseDate: String?,
22 |         val videoCode: String?,
23 |         val tags: List,
24 |         val relatedPicsUrl: List,
25 |     )
26 | }
27 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/MultiItemEntity.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model
 2 | 
 3 | /**
 4 |  * @project Han1meViewer
 5 |  * @author Yenaly Liew
 6 |  * @time 2023/11/26 026 17:40
 7 |  */
 8 | interface MultiItemEntity {
 9 |     val itemType: Int
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/MyListItems.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model
 2 | 
 3 | /**
 4 |  * @project Han1meViewer
 5 |  * @author Yenaly Liew
 6 |  * @time 2022/07/05 005 15:30
 7 |  */
 8 | data class MyListItems(
 9 |     val hanimeInfo: List,
10 |     /**
11 |      * 清單的介紹,一般用於播放清單
12 |      */
13 |     var desc: String? = null,
14 |     val csrfToken: String? = null,
15 | )
16 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/MySubscriptions.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model
 2 | 
 3 | import android.os.Parcelable
 4 | import kotlinx.parcelize.Parcelize
 5 | 
 6 | @Parcelize
 7 | data class MySubscriptions(
 8 |     val subscriptions: List,
 9 |     val subscriptionsVideos: List,
10 |     val maxPage: Int
11 | ) : Parcelable
12 | 
13 | @Parcelize
14 | data class SubscriptionItem(
15 |     val artistName: String,
16 |     val avatar: String
17 | ) : Parcelable
18 | 
19 | @Parcelize
20 | data class SubscriptionVideosItem(
21 |     override val title: String,
22 |     override val coverUrl: String,
23 |     override val videoCode: String,
24 |     override val duration: String? = null,
25 |     override val views: String? = null,
26 |     override val reviews: String? = null,
27 |     override val currentArtist: String? = null
28 | ) : Parcelable, VideoItemType
29 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/ParamEnum.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model
 2 | 
 3 | import com.yenaly.han1meviewer.EMPTY_STRING
 4 | 
 5 | enum class MyListType(val value: String) {
 6 |     FAV_VIDEO("LL"),
 7 |     WATCH_LATER("WL"),
 8 |     SUBSCRIPTION("SL")
 9 | }
10 | 
11 | enum class FavStatus(val value: String) {
12 |     ADD_FAV(EMPTY_STRING),
13 |     CANCEL_FAV("1")
14 | }
15 | 
16 | enum class CommentPlace(val value: String) {
17 |     COMMENT("comment"), // 主評論
18 |     CHILD_COMMENT("reply") // 子評論
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/Playlists.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model
 2 | 
 3 | /**
 4 |  * @project Han1meViewer
 5 |  * @author Yenaly Liew
 6 |  * @time 2023/08/26 026 17:47
 7 |  */
 8 | data class Playlists(
 9 |     val playlists: List,
10 |     val csrfToken: String? = null,
11 | ) {
12 |     data class Playlist(
13 |         val listCode: String,
14 |         var title: String,
15 |         var total: Int,
16 |         val coverUrl: String? = null
17 |     )
18 | }
19 | 
20 | /**
21 |  * 用於 修改播放清單 Flow 的返回值
22 |  */
23 | data class ModifiedPlaylistArgs(
24 |     var title: String,
25 |     var desc: String,
26 |     var isDeleted: Boolean,
27 | )
28 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/SearchTag.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model
 2 | 
 3 | /**
 4 |  * @project Hanime1
 5 |  * @author Yenaly Liew
 6 |  * @time 2022/06/09 009 21:27
 7 |  */
 8 | data class SearchTag(
 9 |     val genres: List,
10 |     val tags: Map>,
11 |     val sortOptions: List,
12 |     val brands: List,
13 |     val releaseDates: ReleaseDate,
14 |     val durationOptions: List>,
15 | ) {
16 |     data class ReleaseDate(
17 |         val years: List>,
18 |         val months: List>,
19 |     )
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/VideoItemType.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model
 2 | 
 3 | interface VideoItemType {
 4 |     val title: String
 5 |     val coverUrl: String
 6 |     val videoCode: String
 7 |     val duration: String?
 8 |     val views: String?
 9 |     val reviews: String?
10 |     val currentArtist: String?
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/github/Commit.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model.github
 2 | 
 3 | import kotlinx.serialization.Serializable
 4 | 
 5 | @Serializable
 6 | data class CommitComparison(val commits: List) {
 7 |     @Serializable
 8 |     data class Commit(val commit: CommitDetail) {
 9 |         @Serializable
10 |         data class CommitDetail(val author: CommitAuthor, val message: String) {
11 |             @Serializable
12 |             data class CommitAuthor(val name: String)
13 |         }
14 |     }
15 | }
16 | 
17 | 
18 | 
19 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/github/Latest.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model.github
 2 | 
 3 | /**
 4 |  * @project Han1meViewer
 5 |  * @author Yenaly Liew
 6 |  * @time 2024/03/21 021 08:56
 7 |  */
 8 | data class Latest(
 9 |     val version: String,
10 |     val changelog: String,
11 |     val downloadLink: String,
12 |     /**
13 |      * Node ID for the download link
14 |      *
15 |      * 其实就是个变相的 md5 验证
16 |      */
17 |     val nodeId: String,
18 | )
19 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/model/github/Workflow.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.model.github
 2 | 
 3 | import kotlinx.serialization.SerialName
 4 | import kotlinx.serialization.Serializable
 5 | 
 6 | /**
 7 |  * @project Han1meViewer
 8 |  * @author Yenaly Liew
 9 |  * @time 2024/03/21 021 09:03
10 |  */
11 | @Serializable
12 | data class WorkflowRuns(
13 |     @SerialName("workflow_runs") val workflowRuns: List,
14 | ) {
15 |     @Serializable
16 |     data class WorkflowRun(
17 |         @SerialName("head_sha") val headSha: String,
18 |         @SerialName("display_title") val title: String,
19 |         @SerialName("artifacts_url") val artifactsUrl: String,
20 |     )
21 | }
22 | 
23 | 
24 | @Serializable
25 | data class Artifacts(
26 |     @SerialName("artifacts") val artifacts: List,
27 | ) {
28 |     val downloadLink: String get() = artifacts.first().downloadLink
29 |     val nodeId: String get() = artifacts.first().nodeId
30 | 
31 |     @Serializable
32 |     data class Artifact(
33 |         val name: String,
34 |         @SerialName("archive_download_url") val downloadLink: String,
35 |         @SerialName("node_id") val nodeId: String,
36 |     )
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/network/GitHubDns.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.network
 2 | 
 3 | import okhttp3.Dns
 4 | import java.net.InetAddress
 5 | 
 6 | /**
 7 |  * @project Han1meViewer
 8 |  * @author Yenaly Liew
 9 |  * @time 2024/03/29 029 17:14
10 |  */
11 | object GitHubDns : Dns {
12 |     override fun lookup(hostname: String): List {
13 |         return when (hostname) {
14 |             "api.github.com" -> listOf(
15 |                 InetAddress.getByName("140.82.116.6"),
16 |                 InetAddress.getByName("20.205.243.168"),
17 |                 InetAddress.getByName("140.82.121.6")
18 |             )
19 |             "github.com" -> listOf(
20 |                 InetAddress.getByName("20.205.243.166"),
21 |                 InetAddress.getByName("140.82.121.3"),
22 |                 InetAddress.getByName("140.82.116.4"),
23 |                 InetAddress.getByName("140.82.121.4")
24 |             )
25 |             else -> Dns.SYSTEM.lookup(hostname)
26 |         }
27 |     }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/network/interceptor/SpeedLimitInterceptor.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.network.interceptor
 2 | 
 3 | import okhttp3.Interceptor
 4 | import okhttp3.Response
 5 | 
 6 | class SpeedLimitInterceptor(var maxSpeed: Long) : Interceptor {
 7 | 
 8 |     companion object {
 9 |         const val NO_LIMIT = 0L
10 | 
11 |         const val NO_LIMIT_INDEX = 0
12 | 
13 |         @JvmField
14 |         val SPEED_BYTES = longArrayOf(
15 |             /* 不限速 */ 0L,
16 |             128 * 1024L, 256 * 1024L, 512 * 1024L,
17 |             1024 * 1024L, 2048 * 1024L, 4096 * 1024L,
18 |             8192 * 1024L, 10240 * 1024L
19 |         )
20 |     }
21 | 
22 |     override fun intercept(chain: Interceptor.Chain): Response {
23 |         val response = chain.proceed(chain.request())
24 |         return response.newBuilder()
25 |             .body(response.body?.let {
26 |                 SpeedLimitResponseBody(it, maxSpeed)
27 |             }).build()
28 |     }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/network/interceptor/SpeedLimitResponseBody.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.network.interceptor
 2 | 
 3 | import com.yenaly.yenaly_libs.utils.unsafeLazy
 4 | import okhttp3.ResponseBody
 5 | import okio.Throttler
 6 | import okio.buffer
 7 | 
 8 | class SpeedLimitResponseBody(
 9 |     private val responseBody: ResponseBody,
10 |     /**
11 |      * 0 means no limit
12 |      */
13 |     private val maxSpeed: Long
14 | ) : ResponseBody() {
15 | 
16 |     private val throttler by unsafeLazy {
17 |         Throttler().apply { bytesPerSecond(maxSpeed) }
18 |     }
19 | 
20 |     override fun contentLength(): Long = responseBody.contentLength()
21 | 
22 |     override fun contentType() = responseBody.contentType()
23 | 
24 |     override fun source() = throttler.source(responseBody.source()).buffer()
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/network/interceptor/UrlLoggingInterceptor.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.network.interceptor
 2 | 
 3 | import android.util.Log
 4 | import okhttp3.Interceptor
 5 | import okhttp3.Response
 6 | import java.net.URLDecoder
 7 | import java.nio.charset.StandardCharsets
 8 | 
 9 | class UrlLoggingInterceptor : Interceptor {
10 |     override fun intercept(chain: Interceptor.Chain): Response {
11 |         val request = chain.request()
12 |         val url = request.url.toString()
13 |         val decodedUrl = URLDecoder.decode(url, StandardCharsets.UTF_8.name())
14 |         Log.i("NetworkRequest",decodedUrl)
15 |         return chain.proceed(request)
16 |     }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/network/interceptor/UserAgentInterceptor.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.network.interceptor
 2 | 
 3 | import com.yenaly.han1meviewer.USER_AGENT
 4 | import okhttp3.Interceptor
 5 | import okhttp3.Response
 6 | 
 7 | object UserAgentInterceptor : Interceptor {
 8 |     override fun intercept(chain: Interceptor.Chain): Response {
 9 |         val request = chain.request().newBuilder().addHeader(
10 |             "User-Agent", USER_AGENT
11 |         ).build()
12 |         return chain.proceed(request)
13 |     }
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/network/service/HanimeSubscriptionService.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.network.service
 2 | 
 3 | import okhttp3.ResponseBody
 4 | import retrofit2.Response
 5 | import retrofit2.http.Field
 6 | import retrofit2.http.FormUrlEncoded
 7 | import retrofit2.http.Header
 8 | import retrofit2.http.POST
 9 | 
10 | interface HanimeSubscriptionService {
11 | 
12 |     @FormUrlEncoded
13 |     @POST("subscribe")
14 |     suspend fun subscribeArtist(
15 |         @Field("_token") csrfToken: String?,
16 |         @Field("subscribe-user-id") userId: String,
17 |         @Field("subscribe-artist-id") artistId: String,
18 |         // 如果当前未订阅会发送空字符串,否则发1
19 |         @Field("subscribe-status") status: String,
20 |         @Header("X-CSRF-TOKEN") csrfToken_1: String? = csrfToken,
21 |     ): Response
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/state/PageLoadingState.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.state
 2 | 
 3 | /**
 4 |  * @project Hanime1
 5 |  * @author Yenaly Liew
 6 |  * @time 2022/06/10 010 16:30
 7 |  */
 8 | sealed class PageLoadingState {
 9 |     data class Success(val info: T) : PageLoadingState()
10 |     data object Loading : PageLoadingState()
11 |     data object NoMoreData : PageLoadingState()
12 |     data class Error(val throwable: Throwable) : PageLoadingState()
13 | }
14 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/state/VideoLoadingState.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.state
 2 | 
 3 | /**
 4 |  * @project Hanime1
 5 |  * @author Yenaly Liew
 6 |  * @time 2022/06/18 018 18:14
 7 |  */
 8 | sealed class VideoLoadingState {
 9 |     data class Success(val info: T) : VideoLoadingState()
10 |     data class Error(val throwable: Throwable) : VideoLoadingState()
11 |     data object Loading : VideoLoadingState()
12 |     data object NoContent : VideoLoadingState()
13 | }
14 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/logic/state/WebsiteState.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.logic.state
 2 | 
 3 | /**
 4 |  * @project Hanime1
 5 |  * @author Yenaly Liew
 6 |  * @time 2022/06/08 008 22:20
 7 |  */
 8 | sealed class WebsiteState {
 9 |     data class Success(val info: T) : WebsiteState()
10 |     data object Loading : WebsiteState()
11 |     data class Error(val throwable: Throwable) : WebsiteState()
12 | }
13 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/StateLayoutMixin.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui
 2 | 
 3 | import android.annotation.SuppressLint
 4 | import android.widget.TextView
 5 | import com.drake.statelayout.StateLayout
 6 | import com.yenaly.han1meviewer.R
 7 | import com.yenaly.han1meviewer.pienization
 8 | 
 9 | /**
10 |  * 用於初始化 StateLayout。
11 |  *
12 |  * 但是不是説實現了這個接口就代表有 StateLayout 了,有些我還是直接用的 BRVAH 自帶的 StateLayoutVH,
13 |  * 因爲用 StateLayout 稍稍有點麻煩。
14 |  *
15 |  * @project Han1meViewer
16 |  * @author Yenaly Liew
17 |  * @time 2023/11/30 030 15:24
18 |  */
19 | @JvmDefaultWithoutCompatibility
20 | interface StateLayoutMixin {
21 | 
22 |     /**
23 |      * 初始化 StateLayout
24 |      */
25 |     @SuppressLint("SetTextI18n")
26 |     fun StateLayout.init(apply: StateLayout.() -> Unit = {}) {
27 |         errorLayout = R.layout.layout_empty_view
28 |         emptyLayout = R.layout.layout_empty_view
29 |         onError {
30 |             val err = it as Throwable
31 |             findViewById(R.id.tv_empty).text = err.pienization
32 |         }
33 |         apply()
34 |     }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/adapter/AdapterLikeDataBindingPage.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui.adapter
 2 | 
 3 | import androidx.databinding.ViewDataBinding
 4 | 
 5 | /**
 6 |  * 利用 Adapter 性质的页面,同时运用 DataBinding
 7 |  */
 8 | interface AdapterLikeDataBindingPage {
 9 |     var binding: DB?
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/adapter/FixedGridLayoutManager.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui.adapter
 2 | 
 3 | import android.content.Context
 4 | import androidx.recyclerview.widget.GridLayoutManager
 5 | 
 6 | /**
 7 |  * @project Han1meViewer
 8 |  * @author Yenaly Liew
 9 |  * @time 2022/09/10 010 00:24
10 |  */
11 | class FixedGridLayoutManager(
12 |     context: Context?,
13 |     spanCount: Int
14 | ) : GridLayoutManager(context, spanCount) {
15 |     override fun supportsPredictiveItemAnimations(): Boolean {
16 |         return false
17 |     }
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/fragment/IToolbarFragment.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui.fragment
 2 | 
 3 | import androidx.appcompat.app.AppCompatActivity
 4 | 
 5 | /**
 6 |  * 用於 Fragment 要求 Activity 實現 Toolbar 的接口
 7 |  *
 8 |  * @project Han1meViewer
 9 |  * @author Yenaly Liew
10 |  * @time 2023/08/27 027 16:29
11 |  */
12 | interface IToolbarFragment {
13 | 
14 |     /**
15 |      * 設置 Toolbar
16 |      */
17 |     fun T.setupToolbar()
18 | 
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/fragment/LoginNeededFragmentMixin.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui.fragment
 2 | 
 3 | import androidx.fragment.app.Fragment
 4 | import androidx.navigation.fragment.findNavController
 5 | import com.yenaly.han1meviewer.Preferences.isAlreadyLogin
 6 | 
 7 | /**
 8 |  * 用於需要登錄的 Fragment
 9 |  *
10 |  * @project Han1meViewer
11 |  * @author Yenaly Liew
12 |  * @time 2023/08/29 029 15:32
13 |  */
14 | @JvmDefaultWithoutCompatibility
15 | interface LoginNeededFragmentMixin {
16 |     /**
17 |      * 檢查是否已經登錄,如果沒有則返回上一個 Fragment
18 |      */
19 |     fun Fragment.checkLogin() {
20 |         if (!isAlreadyLogin) {
21 |             findNavController().navigateUp()
22 |         }
23 |     }
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/fragment/PermissionRequester.kt:
--------------------------------------------------------------------------------
1 | package com.yenaly.han1meviewer.ui.fragment
2 | 
3 | interface PermissionRequester {
4 |     fun requestStoragePermission(
5 |         onGranted: () -> Unit,
6 |         onDenied: () -> Unit,
7 |         onPermanentlyDenied: () -> Unit
8 |     )
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/fragment/ToolbarHost.kt:
--------------------------------------------------------------------------------
1 | package com.yenaly.han1meviewer.ui.fragment
2 | 
3 | interface ToolbarHost {
4 |     fun setupToolbar(title: CharSequence, canNavigateBack: Boolean = true)
5 |     fun hideToolbar()
6 |     fun showToolbar()
7 | }
8 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/fragment/funny/FunnyTouchListener.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui.fragment.funny
 2 | 
 3 | import android.annotation.SuppressLint
 4 | import android.content.Context
 5 | import android.view.MotionEvent
 6 | import android.view.View
 7 | 
 8 | class FunnyTouchListener (
 9 |     context: Context,
10 |     onTrigger: () -> Unit
11 | ) : View.OnTouchListener {
12 | 
13 |     private val detector = SomeFunny(context,onTrigger)
14 | 
15 |     @SuppressLint("ClickableViewAccessibility")
16 |     override fun onTouch(v: View, event: MotionEvent): Boolean {
17 |         return detector.handleMotionEvent(event)
18 |     }
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/view/LinearSmoothToStartScroller.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui.view
 2 | 
 3 | import android.content.Context
 4 | import androidx.recyclerview.widget.LinearSmoothScroller
 5 | 
 6 | /**
 7 |  * https://stackoverflow.com/questions/31235183
 8 |  *
 9 |  * @project Han1meViewer
10 |  * @author Yenaly Liew
11 |  * @time 2024/04/04 004 17:49
12 |  */
13 | class LinearSmoothToStartScroller(context: Context?) : LinearSmoothScroller(context) {
14 |     override fun getVerticalSnapPreference(): Int = SNAP_TO_START
15 | 
16 |     override fun getHorizontalSnapPreference(): Int = SNAP_TO_START
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/view/funcbar/Hanidokitem.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui.view.funcbar
 2 | 
 3 | import android.view.View.OnClickListener
 4 | import androidx.annotation.DrawableRes
 5 | import androidx.annotation.StringRes
 6 | 
 7 | /**
 8 |  * @project Han1meViewer
 9 |  * @author Yenaly Liew
10 |  * @since 2025/3/11 22:10
11 |  */
12 | data class Hanidokitem(
13 |     @param:DrawableRes var icon: Int = 0,
14 |     @param:StringRes var text: Int = 0,
15 |     var viewAction: OnClickListener? = null,
16 |     var subitems: List = emptyList(),
17 |     private val _isBack: Boolean = false,
18 | ) {
19 | 
20 |     val isBack: Boolean
21 |         get() = this._isBack
22 | 
23 |     infix fun contentEquals(other: Hanidokitem): Boolean = icon == other.icon && text == other.text
24 | 
25 |     companion object {
26 |         @JvmStatic
27 |         inline fun create(action: Hanidokitem.() -> Unit): Hanidokitem = Hanidokitem().apply(action)
28 |     }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/viewmodel/IHCsrfToken.kt:
--------------------------------------------------------------------------------
1 | package com.yenaly.han1meviewer.ui.viewmodel
2 | 
3 | interface IHCsrfToken {
4 |     var csrfToken: String?
5 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/viewmodel/MyListViewModel.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui.viewmodel
 2 | 
 3 | import android.app.Application
 4 | import com.yenaly.han1meviewer.ui.viewmodel.mylist.FavSubViewModel
 5 | import com.yenaly.han1meviewer.ui.viewmodel.mylist.PlaylistSubViewModel
 6 | import com.yenaly.han1meviewer.ui.viewmodel.mylist.WatchLaterSubViewModel
 7 | import com.yenaly.yenaly_libs.base.YenalyViewModel
 8 | 
 9 | /**
10 |  * @project Han1meViewer
11 |  * @author Yenaly Liew
12 |  * @time 2022/07/04 004 22:46
13 |  */
14 | class MyListViewModel(application: Application) : YenalyViewModel(application) {
15 | 
16 |     val playlist by sub()
17 |     val watchLater by sub()
18 |     val fav by sub()
19 | }
20 | 
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/ui/viewmodel/PreviewViewModel.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.ui.viewmodel
 2 | 
 3 | import android.app.Application
 4 | import androidx.lifecycle.viewModelScope
 5 | import com.yenaly.han1meviewer.logic.NetworkRepo
 6 | import com.yenaly.han1meviewer.logic.model.HanimePreview
 7 | import com.yenaly.han1meviewer.logic.state.WebsiteState
 8 | import com.yenaly.yenaly_libs.base.YenalyViewModel
 9 | import kotlinx.coroutines.flow.MutableStateFlow
10 | import kotlinx.coroutines.flow.asStateFlow
11 | import kotlinx.coroutines.launch
12 | 
13 | /**
14 |  * @project Hanime1
15 |  * @author Yenaly Liew
16 |  * @time 2022/06/23 023 16:47
17 |  */
18 | class PreviewViewModel(application: Application) : YenalyViewModel(application) {
19 | 
20 |     private val _previewFlow =
21 |         MutableStateFlow>(WebsiteState.Loading)
22 |     val previewFlow = _previewFlow.asStateFlow()
23 | 
24 |     fun getHanimePreview(date: String) {
25 |         viewModelScope.launch {
26 |             NetworkRepo.getHanimePreview(date).collect { preview ->
27 |                 _previewFlow.value = preview
28 |             }
29 |         }
30 |     }
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/util/Colors.kt:
--------------------------------------------------------------------------------
1 | package com.yenaly.han1meviewer.util
2 | 
3 | import android.content.res.ColorStateList
4 | import androidx.annotation.ColorInt
5 | 
6 | fun @receiver:ColorInt Int.toColorStateList() = ColorStateList.valueOf(this)
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/util/Firebases.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.util
 2 | 
 3 | import android.app.Activity
 4 | import android.util.Log
 5 | import androidx.fragment.app.Fragment
 6 | import com.google.firebase.Firebase
 7 | import com.google.firebase.analytics.FirebaseAnalytics
 8 | import com.google.firebase.analytics.analytics
 9 | import com.google.firebase.analytics.logEvent
10 | 
11 | fun Activity.logScreenViewEvent(fragment: Fragment) {
12 |     Firebase.analytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
13 |         // example: MainActivity-HomePageFragment
14 |         val screenName = this@logScreenViewEvent.javaClass.simpleName +
15 |                 "-" + fragment.javaClass.simpleName
16 |         Log.d("logScreenViewEvent", "screenName: $screenName")
17 |         param(FirebaseAnalytics.Param.SCREEN_NAME, screenName)
18 |         param(FirebaseAnalytics.Param.SCREEN_CLASS, fragment.javaClass.simpleName)
19 |     }
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/util/Parcels.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.util
 2 | 
 3 | import android.os.Parcel
 4 | 
 5 | @Suppress("NOTHING_TO_INLINE")
 6 | inline fun Parcel.readBooleanCompat(): Boolean {
 7 |     return readInt() != 0
 8 | }
 9 | 
10 | @Suppress("NOTHING_TO_INLINE")
11 | inline fun Parcel.writeBooleanCompat(value: Boolean) {
12 |     writeInt(if (value) 1 else 0)
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/util/Preferences.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.util
 2 | 
 3 | import androidx.preference.SeekBarPreference
 4 | 
 5 | fun SeekBarPreference.setSummaryConverter(
 6 |     defValue: Int,
 7 |     converter: (Int) -> CharSequence?,
 8 |     action: ((Int) -> Unit)? = null
 9 | ) {
10 |     setDefaultValue(defValue)
11 |     summary = converter(value)
12 |     setOnPreferenceChangeListener { _, newValue ->
13 |         summary = converter(newValue as Int)
14 |         action?.invoke(newValue)
15 |         true
16 |     }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yenaly/han1meviewer/worker/WorkerMixin.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer.worker
 2 | 
 3 | import androidx.work.ListenableWorker
 4 | import com.yenaly.yenaly_libs.utils.unsafeLazy
 5 | 
 6 | /**
 7 |  * @project Han1meViewer
 8 |  * @author Yenaly Liew
 9 |  * @time 2024/03/22 022 21:33
10 |  */
11 | @JvmDefaultWithoutCompatibility
12 | interface WorkerMixin {
13 |     @Suppress("UNCHECKED_CAST", "SameParameterValue")
14 |     fun  ListenableWorker.inputData(key: String, def: T): Lazy = unsafeLazy {
15 |         when (def) {
16 |             is String -> (inputData.getString(key) ?: def) as T
17 |             is Int -> inputData.getInt(key, def) as T
18 |             is Long -> inputData.getLong(key, def) as T
19 |             is Boolean -> inputData.getBoolean(key, def) as T
20 |             is Float -> inputData.getFloat(key, def) as T
21 |             else -> throw IllegalArgumentException("Unsupported type")
22 |         }
23 |     }
24 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_out.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_left.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
7 | 
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_right.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
7 | 
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_left.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
7 | 
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_right.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
7 | 
--------------------------------------------------------------------------------
/app/src/main/res/color/nav_item_icon_color.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     4 |
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/color/nav_item_text_color.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |
5 |     
6 |
7 | 
8 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/akarin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/drawable/akarin.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/apply_deep_links.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/drawable/apply_deep_links.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_add_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_add_link_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_arrow_forward_ios_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_bug_report_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_cert_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_count_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_data_usage_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_deband_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_decoder_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_delay_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |       
5 |     
6 |     
7 | 
8 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_edit_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_error_outline_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_export_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_format_list_bulleted_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_forum_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_frame_jump_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |       
5 |     
6 |     
7 | 
8 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_h_24.xml:
--------------------------------------------------------------------------------
1 | 
3 |     
4 | 
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_hosts_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_keyboard_arrow_down_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_keyboard_arrow_up_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_manage_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_more_horiz_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_overtime_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_player_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_prohibit_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_refresh_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_remove_circle_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_seek_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_share_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_share_first_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_sort_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_speed_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_vpn_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_default_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/drawable/bg_default_header.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/cookies_intro1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/drawable/cookies_intro1.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/frosted_glass.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |
- 
 4 |         
 5 |             
 6 |             
 7 |         
 8 |     9 |
- 
10 |         
11 |             
12 |             
13 |         
14 |     15 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/gradient_black_transparent_90.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 |     
10 | 
11 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_4k_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_access_time_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 |     
6 | 
7 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_arrow_back_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_arrow_forward_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_book.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |       
5 |     
6 |     
7 | 
8 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_cancel_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_check_circle_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_clear_all_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_close_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_comment_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_delete_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_disable_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_download_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_favorite_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_favorite_border_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_help_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_history_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_home_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_info_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_list_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_mask.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_moon_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_more_time_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 |     
6 |     
7 | 
8 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_newspaper_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_pause_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_pause_24_tintwhite.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_play_arrow_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_play_arrow_24_tintwhite.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_play_circle_outline_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_reply_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_report_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_scan_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_search_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_send_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_settings_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_share_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_skip_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_theme_24.xml:
--------------------------------------------------------------------------------
1 | 
2 |       
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_thumb_down_alt_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_thumb_down_off_alt_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_thumb_up_alt_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_thumb_up_off_alt_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_update_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_watch_later_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_clock.xml:
--------------------------------------------------------------------------------
 1 | 
 2 |       
 3 |     
 4 |       
 5 |     
 6 |       
 7 |     
 8 |     
 9 | 
10 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_ext_link.xml:
--------------------------------------------------------------------------------
 1 | 
 6 |   
 9 | 
10 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/drawable/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_calc.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/drawable/ic_launcher_calc.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_cornhub.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/drawable/ic_launcher_cornhub.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_xxt.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/drawable/ic_launcher_xxt.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_pip_mode.xml:
--------------------------------------------------------------------------------
 1 | 
 6 |   
 9 |   
12 | 
13 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_send_selector.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |
4 |
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_setting_applock.xml:
--------------------------------------------------------------------------------
 1 | 
 6 |   
 9 | 
10 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_setting_ci.xml:
--------------------------------------------------------------------------------
 1 | 
 6 |   
 9 | 
10 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_subscribtion.xml:
--------------------------------------------------------------------------------
 1 | 
 6 |   
 9 | 
10 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_circle_bg.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/indicator_active.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 | 
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/indicator_inactive.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 | 
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/linear_gradient_90.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 |     
10 | 
11 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/linear_gradient_90_notrans.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 |     
 9 | 
10 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/neuro_sad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/drawable/neuro_sad.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/outline_home_24.xml:
--------------------------------------------------------------------------------
1 | 
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/scaled_added_time.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 |     
 5 | 
 6 |
10 | 
11 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/search_bar_background.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 |     
5 |     
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_download_func_bar.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_preview_button_left.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
8 |     
9 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_preview_button_right.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
8 | 
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_title_mask.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
4 | 
5 |     
6 | 
7 |     
8 | 
9 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_video.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/base_column_title.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 4 | 
 5 |     
 6 | 
 7 |     
 8 | 
 9 |     
14 | 
15 |         
22 | 
23 |         
29 | 
30 |     
31 | 
32 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/delay_test_dialog.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 8 |     
16 | 
17 |     
21 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_list_only.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 |     
 5 | 
 6 |     
 7 | 
 8 |     
11 | 
12 |         
18 | 
19 |     
20 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_video_introduction.xml:
--------------------------------------------------------------------------------
 1 | 
 2 |     
 3 | 
 4 |     
 7 | 
 8 |         
12 |     
13 | 
14 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_hanidock.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_hanime_preview_news_pic.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
11 | 
12 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_preview_tour_simplified.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 7 | 
 8 |     
14 | 
15 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_rv_wrapper.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 6 | 
 7 |     
12 | 
13 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_simple_card.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
13 | 
14 |     
22 | 
23 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_video_column_title.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 9 | 
10 |     
15 | 
16 |         
17 | 
18 |     
19 | 
20 |     
27 | 
28 | 
29 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_video_tag_chip.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
7 | 
8 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/jz_layout_speed.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
12 | 
13 |     
17 | 
18 | 
19 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_empty_view.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 6 | 
 7 |     
18 | 
19 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_hanidock.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 5 | 
 6 |     
16 | 
17 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_rv_scrollbars.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
6 | 
7 | 
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_ability.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 9 | 
10 |     
16 | 
17 |     
24 | 
25 | 
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_comment_sort.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
19 | 
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_downloading_toolbar.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main_toolbar.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_my_list_toolbar.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_playlist_toolbar.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_preview_toolbar.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_watch_history_toolbar.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 |     
6 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_calc.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_calc_round.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_cornhub.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_cornhub_round.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_debug.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_debug_round.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_xxt.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_xxt_round.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
5 | 
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_calc.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_calc.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_calc_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_calc_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_cornhub.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_cornhub.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_cornhub_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_cornhub_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_debug.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_debug.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_debug_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_debug_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_xxt.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_xxt.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_xxt_background.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_xxt_background.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_xxt_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-hdpi/ic_launcher_xxt_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_calc.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_calc.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_calc_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_calc_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_cornhub.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_cornhub.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_cornhub_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_cornhub_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_debug.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_debug.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_debug_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_debug_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_xxt.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_xxt.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_xxt_background.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_xxt_background.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_xxt_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-mdpi/ic_launcher_xxt_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_calc.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_calc.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_calc_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_calc_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_cornhub.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_cornhub.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_cornhub_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_cornhub_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_debug.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_debug.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_debug_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_debug_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_xxt.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_xxt.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_xxt_background.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_xxt_background.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_xxt_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xhdpi/ic_launcher_xxt_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_calc.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_calc.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_calc_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_calc_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_calc_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_calc_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_cornhub.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_cornhub.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_cornhub_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_cornhub_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_cornhub_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_cornhub_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_debug.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_debug.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_debug_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_debug_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_debug_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_debug_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_xxt.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_xxt.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_xxt_background.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_xxt_background.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_xxt_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_xxt_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_xxt_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxhdpi/ic_launcher_xxt_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_calc.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_calc.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_calc_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_calc_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_calc_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_calc_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_cornhub.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_cornhub.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_cornhub_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_cornhub_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_cornhub_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_cornhub_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_debug.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_debug.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_debug_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_debug_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_debug_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_debug_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xxt.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xxt.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xxt_background.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xxt_background.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xxt_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xxt_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xxt_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/mipmap-xxxhdpi/ic_launcher_xxt_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/raw/akarin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/app/src/main/res/raw/akarin.png
--------------------------------------------------------------------------------
/app/src/main/res/values-land/dimens.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     30dp
4 | 
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 | 
--------------------------------------------------------------------------------
/app/src/main/res/values/bools.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     false
4 | 
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     #212121
4 | 
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_calc_background.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     #FFBFD4
4 | 
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_cornhub_background.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     #000000
4 | 
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |
4 | 
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
 1 | 
 8 | 
 9 |     
13 | 
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
 1 | 
 6 | 
 7 |     
 8 |         
12 |     
13 |     
19 | 
--------------------------------------------------------------------------------
/app/src/main/res/xml/file_paths.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |     
 6 |     
 9 |     
12 |     
15 |     
18 |     
21 | 
--------------------------------------------------------------------------------
/app/src/test/java/com/yenaly/han1meviewer/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.han1meviewer
 2 | 
 3 | import org.junit.Assert.assertEquals
 4 | import org.junit.Test
 5 | 
 6 | /**
 7 |  * Example local unit test, which will execute on the development machine (host).
 8 |  *
 9 |  * See [testing documentation](http://d.android.com/tools/testing).
10 |  */
11 | class ExampleUnitTest {
12 |     @Test
13 |     fun addition_isCorrect() {
14 |         assertEquals(4, 2 + 2)
15 |     }
16 | }
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
 2 | plugins {
 3 |     alias(libs.plugins.com.android.application) apply false
 4 |     alias(libs.plugins.com.android.library) apply false
 5 |     alias(libs.plugins.org.jetbrains.kotlin.android) apply false
 6 |     alias(libs.plugins.org.jetbrains.kotlin.plugin.serialization) apply false
 7 |     alias(libs.plugins.org.jetbrains.kotlin.plugin.parcelize) apply false
 8 |     alias(libs.plugins.com.google.gms.google.services) apply false
 9 |     alias(libs.plugins.com.google.firebase.crashlytics) apply false
10 |     alias(libs.plugins.com.google.firebase.firebase.pref) apply false
11 |     alias(libs.plugins.compose.compiler) apply false
12 | }
13 | 
14 | tasks.register("clean") {
15 |     delete(rootProject.layout.buildDirectory)
16 | }
--------------------------------------------------------------------------------
/buildSrc/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 |     `kotlin-dsl`
3 | }
4 | 
5 | repositories {
6 |     mavenCentral()
7 |     google()
8 |     maven("https://jitpack.io")
9 | }
--------------------------------------------------------------------------------
/develop:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/develop
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon May 13 16:01:02 CST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | #distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
5 | distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.13-bin.zip
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 | 
--------------------------------------------------------------------------------
/icon/icon_han1me_viewer-rurires.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/icon/icon_han1me_viewer-rurires.png
--------------------------------------------------------------------------------
/icon/icon_transparent_han1me_viewer-rurires.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/icon/icon_transparent_han1me_viewer-rurires.png
--------------------------------------------------------------------------------
/readme_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/readme_01.png
--------------------------------------------------------------------------------
/readme_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/readme_02.png
--------------------------------------------------------------------------------
/readme_03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/readme_03.png
--------------------------------------------------------------------------------
/readme_04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/readme_04.png
--------------------------------------------------------------------------------
/readme_05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/readme_05.png
--------------------------------------------------------------------------------
/readme_06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/readme_06.png
--------------------------------------------------------------------------------
/readme_07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/readme_07.png
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
 1 | pluginManagement {
 2 |     repositories {
 3 |         gradlePluginPortal()
 4 |         google()
 5 |         mavenCentral()
 6 |     }
 7 | }
 8 | dependencyResolutionManagement {
 9 |     repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 |     repositories {
11 |         google()
12 |         mavenCentral()
13 |         maven { url = uri("https://jitpack.io/") }
14 |     }
15 | }
16 | rootProject.name = "Han1meViewer"
17 | include(":app", ":yenaly_libs")
18 | 
--------------------------------------------------------------------------------
/yenaly_libs/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/yenaly_libs/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/misaka10032w/Han1meViewer/47abe9f788babdc823132525b67306f78e0cca55/yenaly_libs/consumer-rules.pro
--------------------------------------------------------------------------------
/yenaly_libs/proguard-rules.pro:
--------------------------------------------------------------------------------
 1 | # Add project specific ProGuard rules here.
 2 | # You can control the set of applied configuration files using the
 3 | # proguardFiles setting in build.gradle.kts.
 4 | #
 5 | # For more details, see
 6 | #   http://developer.android.com/guide/developing/tools/proguard.html
 7 | 
 8 | # If your project uses WebView with JS, uncomment the following
 9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | #   public *;
13 | #}
14 | 
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 | 
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 | 
23 | -keepattributes SourceFile, LineNumberTable
24 | -dontwarn java.lang.invoke.StringConcatFactory
25 | -keep class com.yenaly.yenaly_libs.** { *; }
--------------------------------------------------------------------------------
/yenaly_libs/src/androidTest/java/com/yenaly/yenaly_libs/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.yenaly_libs
 2 | 
 3 | import androidx.test.platform.app.InstrumentationRegistry
 4 | import androidx.test.ext.junit.runners.AndroidJUnit4
 5 | 
 6 | import org.junit.Test
 7 | import org.junit.runner.RunWith
 8 | 
 9 | import org.junit.Assert.*
10 | 
11 | /**
12 |  * Instrumented test, which will execute on an Android device.
13 |  *
14 |  * See [testing documentation](http://d.android.com/tools/testing).
15 |  */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 |     @Test
19 |     fun useAppContext() {
20 |         // Context of the app under test.
21 |         val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 |         assertEquals("com.yenaly.yenaly_module.test", appContext.packageName)
23 |     }
24 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 4 | 
 5 |     
 8 |         
19 |         
22 | 
23 |         
24 |     
25 | 
26 | 
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/SingletonHolder.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.yenaly_libs
 2 | 
 3 | /**
 4 |  * @author Yenaly Liew
 5 |  * @time 2023/08/29 029 13:58
 6 |  */
 7 | abstract class SingleArgSingletonHolder(private var constructor: ((A) -> T)?) {
 8 |     @Volatile
 9 |     private var instance: T? = null
10 |     fun getInstance(arg: A): T = instance ?: synchronized(this) {
11 |         instance ?: constructor!!(arg).also {
12 |             instance = it
13 |             constructor = null
14 |         }
15 |     }
16 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/base/IViewBinding.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.yenaly_libs.base
 2 | 
 3 | import android.view.LayoutInflater
 4 | import android.view.ViewGroup
 5 | import androidx.databinding.ViewDataBinding
 6 | 
 7 | interface IViewBinding {
 8 | 
 9 |     val binding: DB
10 | 
11 |     fun getViewBinding(inflater: LayoutInflater, container: ViewGroup?): DB
12 | 
13 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/base/YenalyInitializer.kt:
--------------------------------------------------------------------------------
 1 | @file:Suppress("unused")
 2 | 
 3 | package com.yenaly.yenaly_libs.base
 4 | 
 5 | import android.content.Context
 6 | import androidx.annotation.CallSuper
 7 | import androidx.startup.Initializer
 8 | import com.yenaly.yenaly_libs.utils.applicationContext
 9 | 
10 | /**
11 |  * @ProjectName : YenalyModule
12 |  * @Author : Yenaly Liew
13 |  * @Time : 2022/04/21 021 14:04
14 |  * @Description : Description...
15 |  */
16 | open class YenalyInitializer : Initializer {
17 | 
18 |     @CallSuper
19 |     override fun create(context: Context) {
20 |         applicationContext = context
21 |     }
22 | 
23 |     override fun dependencies(): MutableList>> {
24 |         return mutableListOf()
25 |     }
26 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/base/YenalyViewModel.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.yenaly_libs.base
 2 | 
 3 | import android.app.Application
 4 | import androidx.lifecycle.AndroidViewModel
 5 | import com.yenaly.yenaly_libs.utils.unsafeLazy
 6 | 
 7 | /**
 8 |  * @ProjectName : YenalyModule
 9 |  * @Author : Yenaly Liew
10 |  * @Time : 2022/04/20 020 11:37
11 |  * @Description : Description...
12 |  */
13 | open class YenalyViewModel(
14 |     @JvmField protected val application: Application
15 | ) : AndroidViewModel(application) {
16 | 
17 |     var parent: YenalyViewModel? = null
18 |         private set
19 | 
20 |     @Suppress("UNCHECKED_CAST")
21 |     fun  parent(): YVM? = parent as? YVM
22 | 
23 |     fun  requireParent(): YVM = parent() ?: error("Parent not found")
24 | 
25 |     inline fun  sub() = sub(YVM::class.java)
26 | 
27 |     fun  sub(clazz: Class): Lazy = unsafeLazy {
28 |         clazz.getConstructor(Application::class.java).newInstance(application).also {
29 |             it.parent = this
30 |         }
31 |     }
32 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/base/preference/MaterialSwitchPreference.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.yenaly_libs.base.preference
 2 | 
 3 | import android.content.Context
 4 | import android.util.AttributeSet
 5 | import androidx.preference.SwitchPreferenceCompat
 6 | import com.yenaly.yenaly_libs.R
 7 | 
 8 | open class MaterialSwitchPreference @JvmOverloads constructor(
 9 |     context: Context, attrs: AttributeSet? = null,
10 | ) : SwitchPreferenceCompat(context, attrs) {
11 |     init {
12 |         widgetLayoutResource = R.layout.yenaly_preference_switch_widget
13 |     }
14 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/utils/Base64Util.kt:
--------------------------------------------------------------------------------
 1 | @file:Suppress("unused")
 2 | @file:JvmName("Base64Util")
 3 | 
 4 | package com.yenaly.yenaly_libs.utils
 5 | 
 6 | import android.util.Base64
 7 | 
 8 | /**
 9 |  * Base64加密
10 |  */
11 | @JvmName("encodeToString")
12 | fun String.encodeToStringByBase64(flag: Int = Base64.DEFAULT): String {
13 |     return Base64.encodeToString(this.toByteArray(), flag)
14 | }
15 | 
16 | /**
17 |  * Base64解密
18 |  */
19 | @JvmName("decodeFromString")
20 | fun String.decodeFromStringByBase64(flag: Int = Base64.DEFAULT): String {
21 |     return String(Base64.decode(this.toByteArray(), flag))
22 | }
23 | 
24 | /**
25 |  * Base64解密
26 |  */
27 | @JvmName("decodeFromByteArray")
28 | fun ByteArray.decodeFromByteArrayByBase64(flag: Int = Base64.DEFAULT): ByteArray {
29 |     return Base64.decode(this, flag)
30 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/utils/LanguageHelper.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.yenaly_libs.utils
 2 | 
 3 | import android.annotation.SuppressLint
 4 | import android.os.Build
 5 | import android.os.LocaleList
 6 | import java.util.Locale
 7 | 
 8 | @SuppressLint("ObsoleteSdkInt")
 9 | object LanguageHelper {
10 | 
11 |     val preferredLanguage: Locale
12 |         get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
13 |             LocaleList.getDefault()[0]
14 |         } else {
15 |             Locale.getDefault()
16 |         }
17 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/utils/LogUtil.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.yenaly_libs.utils
 2 | 
 3 | import android.util.Log
 4 | import com.yenaly.yenaly_libs.BuildConfig
 5 | 
 6 | fun  logFieldsChange(tag: String, oldItem: T, newItem: T) {
 7 |     if (!BuildConfig.DEBUG) return
 8 | 
 9 |     val oldFields = oldItem::class.java.declaredFields
10 |     val newFields = newItem::class.java.declaredFields
11 | 
12 |     for (i in oldFields.indices) {
13 |         oldFields[i].isAccessible = true
14 |         newFields[i].isAccessible = true
15 |         val oldValue = oldFields[i].get(oldItem)
16 |         val newValue = newFields[i].get(newItem)
17 |         if (oldValue != newValue) {
18 |             Log.i(tag, "Field ${oldFields[i].name} changed from $oldValue to $newValue")
19 |         }
20 |     }
21 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/utils/ToastUtil.kt:
--------------------------------------------------------------------------------
 1 | @file:JvmName("ToastUtil")
 2 | 
 3 | package com.yenaly.yenaly_libs.utils
 4 | 
 5 | import android.widget.Toast
 6 | import androidx.annotation.StringRes
 7 | import androidx.fragment.app.Fragment
 8 | 
 9 | fun showShortToast(text: String?) {
10 |     Toast.makeText(applicationContext, "$text", Toast.LENGTH_SHORT).show()
11 | }
12 | 
13 | fun showLongToast(text: String?) {
14 |     Toast.makeText(applicationContext, "$text", Toast.LENGTH_LONG).show()
15 | }
16 | 
17 | fun showShortToast(@StringRes text: Int) {
18 |     Toast.makeText(
19 |         applicationContext,
20 |         applicationContext.getString(text),
21 |         Toast.LENGTH_SHORT
22 |     ).show()
23 | }
24 | 
25 | fun showLongToast(@StringRes text: Int) {
26 |     Toast.makeText(
27 |         applicationContext,
28 |         applicationContext.getString(text),
29 |         Toast.LENGTH_LONG
30 |     ).show()
31 | }
32 | fun Fragment.showShortToast(text: CharSequence) {
33 |     Toast.makeText(requireContext(), text, Toast.LENGTH_SHORT).show()
34 | }
35 | 
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/utils/UriUtil.kt:
--------------------------------------------------------------------------------
 1 | @file:JvmName("UriUtil")
 2 | 
 3 | package com.yenaly.yenaly_libs.utils
 4 | 
 5 | import android.net.Uri
 6 | import android.webkit.MimeTypeMap
 7 | 
 8 | inline val Uri.fileExtension get() = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType)
 9 | 
10 | inline val Uri.mimeType get() = application.contentResolver.getType(this)
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/utils/_GsonUtil.kt:
--------------------------------------------------------------------------------
 1 | package com.yenaly.yenaly_libs.utils
 2 | 
 3 | import com.google.gson.GsonBuilder
 4 | import kotlin.reflect.javaType
 5 | import kotlin.reflect.typeOf
 6 | 
 7 | val gson by unsafeLazy {
 8 |     GsonBuilder().create()!!
 9 | }
10 | 
11 | @OptIn(ExperimentalStdlibApi::class)
12 | inline fun  String.fromJson(): T {
13 |     return gson.fromJson(this, typeOf().javaType)
14 | }
15 | 
16 | fun Any?.toJson(): String {
17 |     return gson.toJson(this)
18 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/utils/_LazyUtil.kt:
--------------------------------------------------------------------------------
1 | package com.yenaly.yenaly_libs.utils
2 | 
3 | /**
4 |  * Android一般用不到[LazyThreadSafetyMode.SYNCHRONIZED]的lazy,
5 |  * 使用[LazyThreadSafetyMode.NONE]更合适。
6 |  */
7 | fun  unsafeLazy(initializer: () -> T) = lazy(LazyThreadSafetyMode.NONE, initializer)
--------------------------------------------------------------------------------
/yenaly_libs/src/main/java/com/yenaly/yenaly_libs/utils/view/EditTextUtil.kt:
--------------------------------------------------------------------------------
 1 | @file:JvmName("EditTextUtil")
 2 | 
 3 | package com.yenaly.yenaly_libs.utils.view
 4 | 
 5 | import android.view.Window
 6 | import android.widget.EditText
 7 | import com.yenaly.yenaly_libs.utils.showIme
 8 | 
 9 | /**
10 |  * 在EditText上聚焦并显示软键盘
11 |  *
12 |  * @param window window
13 |  */
14 | fun EditText.showIme(window: Window) = this.let {
15 |     it.isFocusable = true
16 |     it.isFocusableInTouchMode = true
17 |     if (it.hasFocus()) {
18 |         window.showIme(true)
19 |     } else {
20 |         it.requestFocus()
21 |         repeat(2) {
22 |             window.showIme(true)
23 |         }
24 |     }
25 | }
26 | 
27 | /**
28 |  * 在EditText上解除聚焦并隐藏软键盘
29 |  *
30 |  * @param window window
31 |  */
32 | fun EditText.hideIme(window: Window) = this.let {
33 |     it.clearFocus()
34 |     window.showIme(false)
35 | }
--------------------------------------------------------------------------------
/yenaly_libs/src/main/res/layout/yenaly_activity_crash_dialog.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
7 | 
8 | 
--------------------------------------------------------------------------------
/yenaly_libs/src/main/res/layout/yenaly_activity_settings.xml:
--------------------------------------------------------------------------------
 1 | 
 3 | 
 4 |     
 5 | 
 6 |     
 7 | 
 8 |     
12 | 
13 |         
21 | 
22 |         
26 | 
27 |     
28 | 
29 | 
--------------------------------------------------------------------------------
/yenaly_libs/src/main/res/layout/yenaly_preference_switch_widget.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
--------------------------------------------------------------------------------
/yenaly_libs/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 |
5 |
6 | 
7 | 
--------------------------------------------------------------------------------
/yenaly_libs/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     设置
4 |     如果可以,给开发者反馈一下!
5 |     重启软件
6 |     关闭软件
7 |     复制
8 | 
--------------------------------------------------------------------------------
/yenaly_libs/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 |     
14 | 
15 |     
18 | 
19 |     
22 | 
23 | 
--------------------------------------------------------------------------------
/yenaly_libs/src/main/res/xml/http_network_config.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
4 |     
7 | 
--------------------------------------------------------------------------------