├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── dbnavigator.xml ├── deploymentTargetSelector.xml ├── git_toolbox_blame.xml ├── git_toolbox_prj.xml ├── inspectionProfiles │ └── Project_Default.xml ├── kotlinc.xml ├── other.xml ├── render.experimental.xml └── runConfigurations.xml ├── LICENSE ├── NOTE.md ├── README.md ├── Screenshot ├── s1.webp ├── s2.webp ├── s3.webp ├── s4.webp ├── s5.webp ├── s6.webp ├── s7.webp ├── s8.webp └── s9.webp ├── Update └── updateinfo.json ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro ├── retrofit2.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── shizq │ │ └── bika │ │ ├── BIKAApplication.kt │ │ ├── adapter │ │ ├── CategoriesAdapter.kt │ │ ├── ChatMessageMultiAdapter.kt │ │ ├── ChatMessageOldAdapter.kt │ │ ├── ChatRoomBlackListAdapter.kt │ │ ├── ChatRoomListAdapter.kt │ │ ├── ChatRoomListOldAdapter.kt │ │ ├── CollectionsAdapter.kt │ │ ├── CollectionsItemAdapter.kt │ │ ├── ComicListAdapter.kt │ │ ├── ComicListAdapter2.kt │ │ ├── CommentsAdapter.kt │ │ ├── EpisodeAdapter.kt │ │ ├── GameScreenshotAdapter.kt │ │ ├── GamesAdapter.kt │ │ ├── HistoryAdapter.kt │ │ ├── KnightAdapter.kt │ │ ├── MyCommentsAdapter.kt │ │ ├── NotificationsAdapter.kt │ │ ├── PicaAppsAdapter.kt │ │ ├── ReaderAdapter.kt │ │ ├── RecommendAdapter.kt │ │ ├── ViewPagerAdapter.kt │ │ └── holder │ │ │ ├── ChatMessageReceiveHolder.kt │ │ │ ├── ChatMessageSendHolder.kt │ │ │ └── ChatMessageSystemHolder.kt │ │ ├── base │ │ ├── BaseActivity.kt │ │ ├── BaseBindingAdapter.java │ │ ├── BaseBindingHolder.java │ │ ├── BaseFragment.kt │ │ ├── BaseViewModel.kt │ │ └── IBaseView.kt │ │ ├── bean │ │ ├── ActionBean.kt │ │ ├── CategoriesBean.kt │ │ ├── ChatMessageBean.kt │ │ ├── ChatMessageOldBean.kt │ │ ├── ChatRoomBlackListBean.kt │ │ ├── ChatRoomBlackListDeleteBean.kt │ │ ├── ChatRoomBlockUserBean.kt │ │ ├── ChatRoomListBean.kt │ │ ├── ChatRoomListOldBean.kt │ │ ├── ChatRoomProfileBean.kt │ │ ├── ChatRoomSignInBean.kt │ │ ├── CollectionsBean.kt │ │ ├── ComicInfoBean.kt │ │ ├── ComicListBean.kt │ │ ├── ComicListBean2.kt │ │ ├── ComicsPictureBean.kt │ │ ├── CommentsBean.kt │ │ ├── EpisodeBean.kt │ │ ├── GameInfoBean.kt │ │ ├── GamesBean.kt │ │ ├── InitBean.kt │ │ ├── KeywordsBean.kt │ │ ├── KnightBean.kt │ │ ├── MyCommentsBean.kt │ │ ├── NotificationsBean.kt │ │ ├── PicaAppsBean.kt │ │ ├── PicaInitBean.kt │ │ ├── ProfileBean.kt │ │ ├── PunchInBean.kt │ │ ├── RecommendBean.kt │ │ ├── ReportBean.kt │ │ ├── SignInBean.kt │ │ └── UpdateBean.kt │ │ ├── database │ │ ├── BikaDatabase.kt │ │ ├── dao │ │ │ ├── HistoryDao.kt │ │ │ └── SearchDao.kt │ │ └── model │ │ │ ├── HistoryEntity.kt │ │ │ └── SearchEntity.kt │ │ ├── network │ │ ├── ApiService.kt │ │ ├── HmacSHA256Util.java │ │ ├── HttpDns.kt │ │ ├── JsonUtil.kt │ │ ├── Result.kt │ │ ├── RetrofitUtil.kt │ │ ├── base │ │ │ ├── BaseHeaders.kt │ │ │ ├── BaseObserver.kt │ │ │ └── BaseResponse.java │ │ └── websocket │ │ │ ├── ChatWebSocketManager.java │ │ │ ├── IReceiveMessage.java │ │ │ └── WebSocketManager.java │ │ ├── service │ │ ├── ChatWebSocketService.kt │ │ └── ChatWebSocketServiceOld.kt │ │ ├── ui │ │ ├── account │ │ │ ├── AccountActivity.kt │ │ │ └── AccountViewModel.kt │ │ ├── apps │ │ │ ├── AppsActivity.kt │ │ │ ├── AppsFragment.kt │ │ │ ├── AppsFragmentViewModel.kt │ │ │ ├── AppsRepository.kt │ │ │ └── AppsViewModel.kt │ │ ├── chatroom │ │ │ ├── current │ │ │ │ ├── ChatRoomActivity.kt │ │ │ │ ├── ChatRoomViewModel.kt │ │ │ │ ├── blacklist │ │ │ │ │ ├── ChatBlacklistActivity.kt │ │ │ │ │ ├── ChatBlacklistRepository.kt │ │ │ │ │ └── ChatBlacklistViewModel.kt │ │ │ │ └── roomlist │ │ │ │ │ ├── ChatRoomListActivity.kt │ │ │ │ │ ├── ChatRoomListRepository.kt │ │ │ │ │ └── ChatRoomListViewModel.kt │ │ │ └── old │ │ │ │ ├── ChatRoomActivity.kt │ │ │ │ └── ChatRoomViewModel.kt │ │ ├── collections │ │ │ ├── CollectionsActivity.kt │ │ │ ├── CollectionsRepository.kt │ │ │ └── CollectionsViewModel.kt │ │ ├── comicinfo │ │ │ ├── ComicInfoActivity.kt │ │ │ ├── ComicInfoRepository.kt │ │ │ └── ComicInfoViewModel.kt │ │ ├── comiclist │ │ │ ├── ComicListActivity.kt │ │ │ ├── ComicListRepository.kt │ │ │ └── ComicListViewModel.kt │ │ ├── comment │ │ │ ├── CommentsActivity.kt │ │ │ ├── CommentsRepository.kt │ │ │ └── CommentsViewModel.kt │ │ ├── games │ │ │ ├── GameInfoActivity.kt │ │ │ ├── GameInfoViewModel.kt │ │ │ ├── GamesActivity.kt │ │ │ └── GamesViewModel.kt │ │ ├── history │ │ │ ├── HistoryActivity.kt │ │ │ └── HistoryViewModel.kt │ │ ├── image │ │ │ ├── ImageActivity.kt │ │ │ └── ImageViewModel.kt │ │ ├── leaderboard │ │ │ ├── LeaderboardActivity.kt │ │ │ ├── LeaderboardDayFragment.kt │ │ │ ├── LeaderboardDayViewModel.kt │ │ │ ├── LeaderboardKnightFragment.kt │ │ │ ├── LeaderboardKnightViewModel.kt │ │ │ └── LeaderboardViewModel.kt │ │ ├── main │ │ │ ├── MainActivity.kt │ │ │ └── MainViewModel.kt │ │ ├── mycomments │ │ │ ├── MyCommentsActivity.kt │ │ │ └── MyCommentsViewModel.kt │ │ ├── notifications │ │ │ ├── NotificationsActivity.kt │ │ │ └── NotificationsViewModel.kt │ │ ├── reader │ │ │ ├── ReaderActivity.kt │ │ │ └── ReaderViewModel.kt │ │ ├── search │ │ │ ├── SearchActivity.kt │ │ │ └── SearchViewModel.kt │ │ ├── settings │ │ │ ├── SettingsActivity.kt │ │ │ ├── SettingsPreferenceFragment.kt │ │ │ └── SettingsViewModel.kt │ │ ├── signin │ │ │ ├── SignInFragment.kt │ │ │ └── SignInViewModel.kt │ │ ├── signup │ │ │ ├── SignUpFragment.kt │ │ │ └── SignUpViewModel.kt │ │ ├── splash │ │ │ ├── SplashActivity.kt │ │ │ └── SplashViewModel.kt │ │ └── user │ │ │ ├── UserActivity.kt │ │ │ └── UserViewModel.kt │ │ ├── utils │ │ ├── AndroidBug5497Workaround.java │ │ ├── AppVersion.kt │ │ ├── Base64Util.kt │ │ ├── Dimension.kt │ │ ├── GlideCacheUtil.java │ │ ├── GlideEngine.java │ │ ├── GlideModuleOkHttp.kt │ │ ├── GlideUrlNewKey.kt │ │ ├── SPUtil.kt │ │ ├── StatusBarUtil.java │ │ └── TimeUtil.kt │ │ └── widget │ │ ├── IconTextSpan.java │ │ ├── InputTextMsgDialog.java │ │ ├── OutlineSpan.kt │ │ ├── PageIndicatorTextView.kt │ │ ├── SpacesItemDecoration.java │ │ ├── TouchImageView.java │ │ └── UserViewDialog.kt │ └── res │ ├── anim │ ├── anim_enter_from_bottom.xml │ └── anim_exit_from_bottom.xml │ ├── drawable │ ├── bika.webp │ ├── cat_forum.webp │ ├── cat_game.webp │ ├── cat_latest.webp │ ├── cat_leaderboard.webp │ ├── cat_love_pica.webp │ ├── cat_random.webp │ ├── ic_applications.xml │ ├── ic_arrow_down.xml │ ├── ic_arrow_drop_down.xml │ ├── ic_arrow_forward.xml │ ├── ic_arrow_up.xml │ ├── ic_back.xml │ ├── ic_bookmark_add.xml │ ├── ic_bookmark_check.xml │ ├── ic_bookmarks.xml │ ├── ic_chat.webp │ ├── ic_chat_24.xml │ ├── ic_close.xml │ ├── ic_delete.xml │ ├── ic_delete_sweep.xml │ ├── ic_edit.xml │ ├── ic_error.xml │ ├── ic_exit.xml │ ├── ic_favorite_24.xml │ ├── ic_favorite_border_24.xml │ ├── ic_github.xml │ ├── ic_group_work.xml │ ├── ic_history.xml │ ├── ic_home.xml │ ├── ic_hotel_class.xml │ ├── ic_key.xml │ ├── ic_keyboard.xml │ ├── ic_keyboard_voice.xml │ ├── ic_launcher_foreground.xml │ ├── ic_list.xml │ ├── ic_mail.xml │ ├── ic_menu.xml │ ├── ic_night.xml │ ├── ic_photo_camera.xml │ ├── ic_punch.xml │ ├── ic_search.xml │ ├── ic_security.xml │ ├── ic_settings_24.xml │ ├── ic_sort.xml │ ├── ic_voice_1.xml │ ├── ic_voice_2.xml │ ├── ic_widgets.xml │ ├── p.webp │ ├── placeholder_avatar.png │ ├── placeholder_avatar_2.webp │ ├── placeholder_transparent.webp │ ├── placeholder_transparent_low.png │ ├── shape_chat_bg.xml │ ├── shape_chat_notification_bg.xml │ ├── shape_chat_reply_bg.xml │ ├── shape_chat_send_bg.xml │ ├── shape_title_bg.xml │ ├── verified_icon.webp │ └── voice.xml │ ├── layout │ ├── activity_account.xml │ ├── activity_apps.xml │ ├── activity_chat_room.xml │ ├── activity_chat_room_blacklist.xml │ ├── activity_chat_room_list.xml │ ├── activity_chat_room_old.xml │ ├── activity_collections.xml │ ├── activity_comicinfo.xml │ ├── activity_comiclist.xml │ ├── activity_comments.xml │ ├── activity_game_info.xml │ ├── activity_games.xml │ ├── activity_history.xml │ ├── activity_image.xml │ ├── activity_leaderboard.xml │ ├── activity_main.xml │ ├── activity_my_comments.xml │ ├── activity_notifications.xml │ ├── activity_reader.xml │ ├── activity_search.xml │ ├── activity_settings.xml │ ├── activity_splash.xml │ ├── activity_user.xml │ ├── dialog_input_text_msg.xml │ ├── fragment_apps.xml │ ├── fragment_leaderboard_day.xml │ ├── fragment_leaderboard_knight.xml │ ├── fragment_signin.xml │ ├── fragment_signup.xml │ ├── item_categories.xml │ ├── item_categories_skeleton.xml │ ├── item_chat_message_old.xml │ ├── item_chat_message_receive.xml │ ├── item_chat_message_send.xml │ ├── item_chat_message_system.xml │ ├── item_chat_room_blacklist.xml │ ├── item_chat_room_list.xml │ ├── item_chat_room_list_old.xml │ ├── item_chip_at.xml │ ├── item_collections.xml │ ├── item_comiclist.xml │ ├── item_comiclist2.xml │ ├── item_comiclist_skeleton.xml │ ├── item_comments.xml │ ├── item_episode.xml │ ├── item_episode_footer_view.xml │ ├── item_game_screenshot.xml │ ├── item_games.xml │ ├── item_games_skeleton.xml │ ├── item_histroy.xml │ ├── item_knight.xml │ ├── item_knight_skeleton.xml │ ├── item_main_drawer_header.xml │ ├── item_my_comments.xml │ ├── item_notifications.xml │ ├── item_picaapps.xml │ ├── item_picture.xml │ ├── item_recommend.xml │ ├── view_bottom_sub_comments.xml │ ├── view_chip.xml │ ├── view_dialog_edit_text.xml │ ├── view_dialog_edit_text_answer.xml │ ├── view_dialog_edit_text_change_password.xml │ ├── view_dialog_edit_text_change_password_old.xml │ ├── view_dialog_edit_text_slogan.xml │ ├── view_dialog_user.xml │ ├── view_load.xml │ ├── view_popup_image.xml │ ├── view_preference_switch.xml │ └── view_toolbar.xml │ ├── menu │ ├── activity_main_drawer.xml │ ├── activity_sigup_gender.xml │ ├── toolbar_menu_chat.xml │ ├── toolbar_menu_chat2.xml │ ├── toolbar_menu_comicinfo.xml │ ├── toolbar_menu_comiclist.xml │ ├── toolbar_menu_comiclist_sort.xml │ ├── toolbar_menu_comiclist_sort2.xml │ ├── toolbar_menu_gameinfo.xml │ ├── toolbar_menu_history.xml │ ├── toolbar_menu_main.xml │ └── toolbar_menu_reader.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── navigation │ └── nav_login.xml │ ├── transition │ └── change_bounds.xml │ ├── values-land │ └── dimens.xml │ ├── values-night-v31 │ └── themes.xml │ ├── values-night │ └── themes.xml │ ├── values-v31 │ └── themes.xml │ ├── values-v34 │ └── dimens.xml │ ├── values │ ├── array.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── themes.xml │ └── xml │ ├── backup_rules.xml │ ├── data_extraction_rules.xml │ ├── network_security_config.xml │ └── settings_preferences.xml ├── build.gradle.kts ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | /detekt.xml 5 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/deploymentTargetSelector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/git_toolbox_blame.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/git_toolbox_prj.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/other.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/render.experimental.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | -------------------------------------------------------------------------------- /NOTE.md: -------------------------------------------------------------------------------- 1 | #未完成 2 | 3 | 漫画详情章节观看记录 4 | 漫画详情章节图片观看记录 5 | 漫画阅读器 6 | 聊天室发送语音 7 | 子评论页加进度条 8 | 哔咔新的聊天室 9 | 10 | 未来适配平板 11 | 未来添加漫画下载 12 | 添加转场动画 13 | 14 | #待优化 15 | 16 | 注册页面 需要优化 跳转到登录页要显示注册的账号密码 17 | 回退键 18 | 设置页太乱 19 | 历史记录需要优化 20 | 更改密码 需要添加进度条 21 | 优化activity 转成fragment 22 | 图片修剪工具不是很好用 23 | 上传头像的锯齿较多不清晰 24 | 主题切换livedata会重复加载 25 | 26 | #服务器状态 27 | 28 | 400 1019 cannot comment 无法发表评论 29 | 400 1031 higher level is required 评论等级不够 30 | 400 1002 avatar invalid base64 image 无效的base64图像 31 | 400 1004 账号密码错误 32 | 400 1008 email is already exist 邮箱已存在 33 | 400 1009 name is already exist 名称已存在 34 | 400 1014 漫画审核中 35 | 401 1005 unauthorized token过期 36 | 404 1007 not found 找不到数据 37 | 413 request entity too large 图片上传太大 38 | 500 :( -- 39 | 40 | #旧聊天室 webSocket 41 | 42 | 0 连接成功 43 | 2 心跳包 服务器会回复 3 44 | 40 连接成功 45 | 41 关闭聊天 46 | 42 消息 47 | 1000 超时 48 | -------------------------------------------------------------------------------- /Screenshot/s1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/Screenshot/s1.webp -------------------------------------------------------------------------------- /Screenshot/s2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/Screenshot/s2.webp -------------------------------------------------------------------------------- /Screenshot/s3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/Screenshot/s3.webp -------------------------------------------------------------------------------- /Screenshot/s4.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/Screenshot/s4.webp -------------------------------------------------------------------------------- /Screenshot/s5.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/Screenshot/s5.webp -------------------------------------------------------------------------------- /Screenshot/s6.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/Screenshot/s6.webp -------------------------------------------------------------------------------- /Screenshot/s7.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/Screenshot/s7.webp -------------------------------------------------------------------------------- /Screenshot/s8.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/Screenshot/s8.webp -------------------------------------------------------------------------------- /Screenshot/s9.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/Screenshot/s9.webp -------------------------------------------------------------------------------- /Update/updateinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 6, 3 | "name": "1.0.5", 4 | "url": "https://zquan.lanzoue.com/b00zguxje", 5 | "des": "", 6 | "size": "0" 7 | } -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -keep class com.luck.picture.lib.** { *; } 2 | -dontwarn com.yalantis.ucrop** 3 | -keep class com.yalantis.ucrop** { *; } 4 | -keep interface com.yalantis.ucrop** { *; } 5 | 6 | -keep class com.shizq.bika.network.base.BaseResponse {*;} 7 | -keep class com.shizq.bika.bean.** {*;} 8 | -keep class com.shizq.bika.base.** {*;} 9 | -------------------------------------------------------------------------------- /app/retrofit2.pro: -------------------------------------------------------------------------------- 1 | # Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and 2 | # EnclosingMethod is required to use InnerClasses. 3 | -keepattributes Signature, InnerClasses, EnclosingMethod 4 | 5 | # Retrofit does reflection on method and parameter annotations. 6 | -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations 7 | 8 | # Keep annotation default values (e.g., retrofit2.http.Field.encoded). 9 | -keepattributes AnnotationDefault 10 | 11 | # Retain service method parameters when optimizing. 12 | -keepclassmembers,allowshrinking,allowobfuscation interface * { 13 | @retrofit2.http.* ; 14 | } 15 | 16 | # Ignore annotation used for build tooling. 17 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 18 | 19 | # Ignore JSR 305 annotations for embedding nullability information. 20 | -dontwarn javax.annotation.** 21 | 22 | # Guarded by a NoClassDefFoundError try/catch and only used when on the classpath. 23 | -dontwarn kotlin.Unit 24 | 25 | # Top-level functions that can only be used by Kotlin. 26 | -dontwarn retrofit2.KotlinExtensions 27 | -dontwarn retrofit2.KotlinExtensions$* 28 | 29 | # With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy 30 | # and replaces all potential values with null. Explicitly keeping the interfaces prevents this. 31 | -if interface * { @retrofit2.http.* ; } 32 | -keep,allowobfuscation interface <1> 33 | 34 | # Keep inherited services. 35 | -if interface * { @retrofit2.http.* ; } 36 | -keep,allowobfuscation interface * extends <1> 37 | 38 | # With R8 full mode generic signatures are stripped for classes that are not 39 | # kept. Suspend functions are wrapped in continuations where the type argument 40 | # is used. 41 | -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation 42 | 43 | # R8 full mode strips generic signatures from return types if not kept. 44 | -if interface * { @retrofit2.http.* public *** *(...); } 45 | -keep,allowoptimization,allowshrinking,allowobfuscation class <3> 46 | 47 | # With R8 full mode generic signatures are stripped for classes that are not kept. 48 | -keep,allowobfuscation,allowshrinking class retrofit2.Response 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/BIKAApplication.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika 2 | 3 | import android.annotation.SuppressLint 4 | import android.app.Application 5 | import androidx.appcompat.app.AppCompatDelegate 6 | import com.google.android.material.color.DynamicColors 7 | import com.shizq.bika.utils.SPUtil 8 | 9 | class BIKAApplication : Application() { 10 | 11 | companion object { 12 | @SuppressLint("StaticFieldLeak") 13 | lateinit var contextBase: Application 14 | } 15 | 16 | override fun onCreate() { 17 | super.onCreate() 18 | contextBase = this 19 | DynamicColors.applyToActivitiesIfAvailable(this)//根据壁纸修改App主题颜色 20 | 21 | SPUtil.init(this) 22 | val nightMode = SPUtil.get("setting_night", "跟随系统") as String 23 | AppCompatDelegate.setDefaultNightMode( 24 | when (nightMode) { 25 | "开启" -> AppCompatDelegate.MODE_NIGHT_YES 26 | "关闭" -> AppCompatDelegate.MODE_NIGHT_NO 27 | "跟随系统" -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM 28 | else -> AppCompatDelegate.MODE_NIGHT_NO 29 | } 30 | ) 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/CategoriesAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | import com.shizq.bika.R 3 | import com.shizq.bika.base.BaseBindingAdapter 4 | import com.shizq.bika.base.BaseBindingHolder 5 | import com.shizq.bika.bean.CategoriesBean 6 | import com.shizq.bika.databinding.ItemCategoriesBinding 7 | import com.bumptech.glide.Glide 8 | import com.shizq.bika.utils.GlideUrlNewKey 9 | 10 | //分类 11 | class CategoriesAdapter : 12 | BaseBindingAdapter(R.layout.item_categories) { 13 | 14 | override fun bindView( 15 | holder: BaseBindingHolder<*, *>, 16 | bean: CategoriesBean.Category, 17 | binding: ItemCategoriesBinding, 18 | position: Int 19 | ) { 20 | Glide.with(holder.itemView) 21 | .load( 22 | //判断是否是手动添加的数据 23 | if (bean.imageRes == null) { 24 | //哔咔服务器问题 需自行修改图片请求路径 25 | GlideUrlNewKey("https://s3.picacomic.com", bean.thumb.path) 26 | } else { 27 | bean.imageRes 28 | } 29 | ) 30 | .centerCrop() 31 | .placeholder(R.drawable.placeholder_transparent) 32 | .into(binding.categoriesItemImage) 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/ChatRoomBlackListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | 3 | import com.shizq.bika.R 4 | import com.shizq.bika.base.BaseBindingAdapter 5 | import com.shizq.bika.base.BaseBindingHolder 6 | import com.shizq.bika.bean.ChatRoomBlackListBean 7 | import com.shizq.bika.databinding.ItemChatRoomBlacklistBinding 8 | import com.bumptech.glide.Glide 9 | 10 | //新聊天室黑名单 11 | class ChatRoomBlackListAdapter : 12 | BaseBindingAdapter(R.layout.item_chat_room_blacklist) { 13 | 14 | override fun bindView( 15 | holder: BaseBindingHolder<*, *>, 16 | bean: ChatRoomBlackListBean.Doc, 17 | binding: ItemChatRoomBlacklistBinding, 18 | position: Int 19 | ) { 20 | 21 | Glide.with(holder.itemView) 22 | .load(bean.user.avatarUrl) 23 | .placeholder(R.drawable.placeholder_avatar_2) 24 | .into(binding.chatBlacklistAvatar) 25 | 26 | holder.addOnClickListener(R.id.chat_blacklist_delete) 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/ChatRoomListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | 3 | import com.shizq.bika.R 4 | import com.shizq.bika.base.BaseBindingAdapter 5 | import com.shizq.bika.base.BaseBindingHolder 6 | import com.shizq.bika.bean.ChatRoomListBean 7 | import com.shizq.bika.databinding.ItemChatRoomListBinding 8 | import com.bumptech.glide.Glide 9 | 10 | //新聊天室列表 11 | class ChatRoomListAdapter : 12 | BaseBindingAdapter(R.layout.item_chat_room_list) { 13 | 14 | override fun bindView( 15 | holder: BaseBindingHolder<*, *>, 16 | bean: ChatRoomListBean.Room, 17 | binding: ItemChatRoomListBinding, 18 | position: Int 19 | ) { 20 | 21 | Glide.with(holder.itemView) 22 | .load(bean.icon) 23 | .placeholder(R.drawable.placeholder_avatar_2) 24 | .into(binding.chatRoomsImage) 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/ChatRoomListOldAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | 3 | import com.shizq.bika.R 4 | import com.shizq.bika.base.BaseBindingAdapter 5 | import com.shizq.bika.base.BaseBindingHolder 6 | import com.shizq.bika.bean.ChatRoomListOldBean 7 | import com.shizq.bika.databinding.ItemChatRoomListOldBinding 8 | import com.bumptech.glide.Glide 9 | 10 | //旧聊天室列表 11 | class ChatRoomListOldAdapter : 12 | BaseBindingAdapter(R.layout.item_chat_room_list_old) { 13 | 14 | override fun bindView( 15 | holder: BaseBindingHolder<*, *>, 16 | bean: ChatRoomListOldBean.Chat, 17 | binding: ItemChatRoomListOldBinding, 18 | position: Int 19 | ) { 20 | 21 | Glide.with(holder.itemView) 22 | .load(bean.avatar) 23 | .placeholder(R.drawable.placeholder_avatar_2) 24 | .into(binding.chatListImage) 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/EpisodeAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | 3 | import com.shizq.bika.R 4 | import com.shizq.bika.base.BaseBindingAdapter 5 | import com.shizq.bika.base.BaseBindingHolder 6 | import com.shizq.bika.bean.EpisodeBean 7 | import com.shizq.bika.databinding.ItemEpisodeBinding 8 | import com.shizq.bika.utils.TimeUtil 9 | 10 | //漫画片段或章节adapter 11 | class EpisodeAdapter : BaseBindingAdapter(R.layout.item_episode) { 12 | 13 | override fun bindView( 14 | holder: BaseBindingHolder<*, *>, 15 | bean: EpisodeBean.Eps.Doc, 16 | binding: ItemEpisodeBinding, 17 | position: Int 18 | ) { 19 | binding.episodeTitle.text = bean.title 20 | binding.episodeTime.text = TimeUtil().time(bean.updated_at) 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/GamesAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | 3 | import com.shizq.bika.R 4 | import com.shizq.bika.base.BaseBindingAdapter 5 | import com.shizq.bika.base.BaseBindingHolder 6 | import com.shizq.bika.bean.GamesBean 7 | import com.shizq.bika.databinding.ItemGamesBinding 8 | import com.bumptech.glide.Glide 9 | import com.shizq.bika.utils.GlideUrlNewKey 10 | 11 | class GamesAdapter : 12 | BaseBindingAdapter(R.layout.item_games) { 13 | 14 | override fun bindView( 15 | holder: BaseBindingHolder<*, *>, 16 | bean: GamesBean.Games.Docs, 17 | binding: ItemGamesBinding, 18 | position: Int 19 | ) { 20 | Glide.with(holder.itemView) 21 | .load(GlideUrlNewKey(bean.icon.fileServer, bean.icon.path)) 22 | .placeholder(R.drawable.placeholder_avatar_2) 23 | .into(binding.gamesItemImage) 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/HistoryAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | 3 | import com.shizq.bika.R 4 | import com.shizq.bika.base.BaseBindingAdapter 5 | import com.shizq.bika.base.BaseBindingHolder 6 | import com.shizq.bika.databinding.ItemHistroyBinding 7 | import com.shizq.bika.database.model.HistoryEntity 8 | import com.bumptech.glide.Glide 9 | import com.shizq.bika.utils.GlideUrlNewKey 10 | import com.shizq.bika.utils.TimeUtil 11 | 12 | class HistoryAdapter : 13 | BaseBindingAdapter(R.layout.item_histroy) { 14 | 15 | override fun bindView( 16 | holder: BaseBindingHolder<*, *>, 17 | bean: HistoryEntity, 18 | binding: ItemHistroyBinding, 19 | position: Int 20 | ) { 21 | Glide.with(holder.itemView) 22 | .load(GlideUrlNewKey(bean.fileServer, bean.path)) 23 | .placeholder(R.drawable.placeholder_avatar_2) 24 | .into(binding.historyItemImage) 25 | binding.historyItemTime.text = TimeUtil().getDate(bean.time) 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/KnightAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | 3 | import com.shizq.bika.R 4 | import com.shizq.bika.base.BaseBindingAdapter 5 | import com.shizq.bika.base.BaseBindingHolder 6 | import com.shizq.bika.bean.KnightBean 7 | import com.shizq.bika.databinding.ItemKnightBinding 8 | import com.bumptech.glide.Glide 9 | import com.shizq.bika.utils.GlideUrlNewKey 10 | 11 | class KnightAdapter : BaseBindingAdapter(R.layout.item_knight) { 12 | 13 | override fun bindView( 14 | holder: BaseBindingHolder<*, *>, 15 | bean: KnightBean.Users, 16 | binding: ItemKnightBinding, 17 | position: Int 18 | ) { 19 | //头像 20 | Glide.with(holder.itemView) 21 | .load( 22 | if (bean.avatar != null) 23 | GlideUrlNewKey(bean.avatar.fileServer, bean.avatar.path) 24 | else 25 | R.drawable.placeholder_avatar_2 26 | ) 27 | .placeholder(R.drawable.placeholder_avatar_2) 28 | .into(binding.knightUserImage) 29 | //头像框 30 | Glide.with(holder.itemView) 31 | .load(if (bean.character.isNullOrEmpty()) "" else bean.character) 32 | .into(binding.knightUserCharacter) 33 | 34 | holder.addOnClickListener(R.id.knight_user_image_layout) 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/PicaAppsAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | 3 | import com.shizq.bika.R 4 | import com.shizq.bika.base.BaseBindingAdapter 5 | import com.shizq.bika.base.BaseBindingHolder 6 | import com.shizq.bika.bean.PicaAppsBean 7 | import com.shizq.bika.databinding.ItemPicaappsBinding 8 | import com.bumptech.glide.Glide 9 | 10 | class PicaAppsAdapter : 11 | BaseBindingAdapter(R.layout.item_picaapps) { 12 | 13 | override fun bindView( 14 | holder: BaseBindingHolder<*, *>, 15 | bean: PicaAppsBean.App, 16 | binding: ItemPicaappsBinding, 17 | position: Int 18 | ) { 19 | 20 | Glide.with(holder.itemView) 21 | .load(bean.icon) 22 | .placeholder(R.drawable.placeholder_avatar_2) 23 | .into(binding.picaAppsImage) 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/ViewPagerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentManager 5 | import androidx.lifecycle.Lifecycle 6 | import androidx.viewpager2.adapter.FragmentStateAdapter 7 | 8 | class ViewPagerAdapter( 9 | private val list: List, 10 | fragmentManager: FragmentManager, 11 | lifecycle: Lifecycle, 12 | ) : FragmentStateAdapter(fragmentManager, lifecycle) { 13 | override fun createFragment(position: Int): Fragment = list[position] 14 | override fun getItemCount(): Int = list.size 15 | 16 | 17 | 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/adapter/holder/ChatMessageSystemHolder.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.adapter.holder 2 | 3 | import android.view.ViewGroup 4 | import com.shizq.bika.base.BaseBindingHolder 5 | import com.shizq.bika.bean.ChatMessageBean 6 | import com.shizq.bika.databinding.ItemChatMessageSystemBinding 7 | import com.shizq.bika.utils.TimeUtil 8 | 9 | //新聊天室 一些通知 10 | class ChatMessageSystemHolder(viewGroup: ViewGroup, layoutId: Int) : 11 | BaseBindingHolder(viewGroup, layoutId) { 12 | 13 | override fun onBindingView( 14 | holder: BaseBindingHolder<*, *>, 15 | bean: ChatMessageBean, 16 | position: Int 17 | ) { 18 | binding.chatNotification.text = when (bean.type) { 19 | "CONNECTED" -> { 20 | TimeUtil().getDate(bean.data.data) 21 | } 22 | 23 | "SYSTEM_MESSAGE" -> { 24 | bean.data.message.message 25 | } 26 | 27 | "TEXT_MESSAGE" -> { 28 | "黑名单消息" 29 | } 30 | 31 | "IMAGE_MESSAGE" -> { 32 | "黑名单消息" 33 | } 34 | 35 | else -> { 36 | "未知消息类型" 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/base/BaseBindingHolder.java: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.base; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.ViewGroup; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.databinding.DataBindingUtil; 8 | import androidx.databinding.ViewDataBinding; 9 | 10 | import java.util.List; 11 | 12 | import me.jingbin.library.adapter.BaseByViewHolder; 13 | 14 | /** 15 | * https://github.com/youlookwhat/ByRecyclerView 16 | */ 17 | public abstract class BaseBindingHolder extends BaseByViewHolder { 18 | 19 | public final B binding; 20 | 21 | public BaseBindingHolder(ViewGroup viewGroup, int layoutId) { 22 | super(DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()), layoutId, viewGroup, false).getRoot()); 23 | binding = DataBindingUtil.getBinding(this.itemView); 24 | } 25 | 26 | @Override 27 | protected void onBaseBindView(BaseByViewHolder holder, T bean, int position) { 28 | onBindingView(this, bean, position); 29 | binding.executePendingBindings(); 30 | } 31 | 32 | @Override 33 | protected void onBaseBindViewPayloads(BaseByViewHolder holder, T bean, int position, @NonNull List payloads) { 34 | onBindingViewPayloads(this, bean, position, payloads); 35 | binding.executePendingBindings(); 36 | } 37 | 38 | protected abstract void onBindingView(BaseBindingHolder holder, T bean, int position); 39 | 40 | protected void onBindingViewPayloads(BaseBindingHolder holder, T bean, int position, @NonNull List payloads) { 41 | /* 42 | * fallback to onBindingViewPayloads(holder, bean,position) if app does not override this method. 43 | * 如果不覆盖 bindViewPayloads() 方法,就走 onBindingView() 44 | */ 45 | onBindingView(holder, bean, position); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/base/BaseViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.base 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.AndroidViewModel 5 | import androidx.lifecycle.DefaultLifecycleObserver 6 | import io.reactivex.rxjava3.disposables.CompositeDisposable 7 | import io.reactivex.rxjava3.disposables.Disposable 8 | import io.reactivex.rxjava3.functions.Consumer 9 | 10 | open class BaseViewModel(application: Application) : AndroidViewModel(application), 11 | DefaultLifecycleObserver, Consumer { 12 | 13 | //管理RxJava,主要针对RxJava异步操作造成的内存泄漏 14 | private val mCompositeDisposable: CompositeDisposable = CompositeDisposable() 15 | private fun addSubscribe(disposable: Disposable?) { 16 | mCompositeDisposable.add(disposable!!) 17 | } 18 | 19 | override fun onCleared() { 20 | super.onCleared() 21 | //ViewModel销毁时会执行,同时取消所有异步任务 22 | mCompositeDisposable.clear() 23 | } 24 | 25 | @Throws(Exception::class) 26 | override fun accept(disposable: Disposable) { 27 | addSubscribe(disposable) 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/base/IBaseView.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.base 2 | 3 | interface IBaseView { 4 | /** 5 | * 初始化界面传递参数 6 | */ 7 | fun initParam() 8 | 9 | /** 10 | * 初始化数据 11 | */ 12 | fun initData() 13 | 14 | /** 15 | * 初始化界面观察者的监听 16 | */ 17 | fun initViewObservable() 18 | 19 | /** 20 | * 列表无数据点击加载网络功能 21 | */ 22 | fun onContentReload() 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ActionBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | 4 | data class ActionBean( 5 | val action: String 6 | ) 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/CategoriesBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class CategoriesBean( 4 | val categories: List 5 | ) { 6 | 7 | data class Category( 8 | val _id: String, 9 | val active: Boolean, 10 | val description: String, 11 | val isWeb: Boolean, 12 | val link: String, 13 | val thumb: Thumb, 14 | var title: String, 15 | var imageRes: Int? 16 | ) { 17 | 18 | data class Thumb( 19 | val fileServer: String, 20 | val originalName: String, 21 | val path: String 22 | ) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ChatMessageBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ChatMessageBean( 4 | val `data`: Data, 5 | val isBlocked: Boolean, 6 | val type: String, 7 | val referenceId: String, 8 | val id: String 9 | ){ 10 | data class Data( 11 | val `data`: String, 12 | val action: String,//"action":"MUTE_USER" 13 | val userMentions: List, 14 | val message: Message, 15 | val profile: Profile, 16 | val reply: Reply 17 | ){ 18 | data class Message( 19 | val caption: String, 20 | val date: String, 21 | val id: String, 22 | val medias: List, 23 | val message: String 24 | ) 25 | 26 | data class Profile( 27 | val avatarUrl: String, 28 | val birthday: String, 29 | val characters: List, 30 | val created_at: String, 31 | val email: String, 32 | val exp: Int, 33 | val gender: String, 34 | val id: String, 35 | val level: Int, 36 | val name: String, 37 | val role: String, 38 | val slogan: String, 39 | val title: String 40 | ) 41 | 42 | data class Reply( 43 | val id: String, 44 | val image: String, 45 | val message: String, 46 | val name: String, 47 | val type: String 48 | ) 49 | } 50 | } 51 | data class UserMention( 52 | val id: String, 53 | val name: String 54 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ChatMessageOldBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | 4 | data class ChatMessageOldBean( 5 | val at: String, 6 | val audio: String, 7 | val avatar: String, 8 | val block_user_id: String, 9 | val character: String, 10 | val event_colors: List, 11 | val gender: String, 12 | val image: String, 13 | val level: Int, 14 | val message: String, 15 | val name: String, 16 | val platform: String, 17 | val reply: String, 18 | val reply_name: String, 19 | val title: String, 20 | val type: Any, 21 | val unique_id: String, 22 | val user_id: String, 23 | val verified: Boolean 24 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ChatRoomBlackListBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ChatRoomBlackListBean( 4 | val error: String, 5 | val message: String, 6 | val statusCode: Int, 7 | val docs: List, 8 | var limit: Int = 0, 9 | val offset: Int, 10 | val total: Int 11 | ) { 12 | data class Doc( 13 | val id: String, 14 | val user: User 15 | ) { 16 | data class User( 17 | val avatarUrl: String, 18 | val birthday: String, 19 | val characters: List, 20 | val created_at: String, 21 | val email: String, 22 | val exp: Int, 23 | val gender: String, 24 | val id: String, 25 | val level: Int, 26 | val name: String, 27 | val role: String, 28 | val slogan: String, 29 | val title: String 30 | ) 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ChatRoomBlackListDeleteBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ChatRoomBlackListDeleteBean( 4 | val error: String, 5 | val message: String, 6 | val statusCode: Int, 7 | val id: String 8 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ChatRoomBlockUserBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ChatRoomBlockUserBean( 4 | val error: String, 5 | val message: String, 6 | val statusCode: Int, 7 | val userId: String 8 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ChatRoomListBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ChatRoomListBean( 4 | val error: String, 5 | val message: String, 6 | val statusCode: Int, 7 | val rooms: List? 8 | ) { 9 | data class Room( 10 | val allowedCharacters: List, 11 | val description: String, 12 | val icon: String, 13 | val id: String, 14 | val isAvailable: Boolean, 15 | val isPublic: Boolean, 16 | val minLevel: Int, 17 | val minRegisterDays: Int, 18 | val title: String 19 | ) 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ChatRoomListOldBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ChatRoomListOldBean( 4 | val chatList: List 5 | ){ 6 | data class Chat( 7 | val avatar: String, 8 | val description: String, 9 | val title: String, 10 | val url: String 11 | ) 12 | } 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ChatRoomProfileBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ChatRoomProfileBean( 4 | val error: String, 5 | val message: String, 6 | val statusCode: Int, 7 | val profile: Profile 8 | ) { 9 | data class Profile( 10 | val avatarUrl: String, 11 | val birthday: String, 12 | val characters: List, 13 | val created_at: String, 14 | val email: String, 15 | val exp: Int, 16 | val gender: String, 17 | val id: String, 18 | val level: Int, 19 | val name: String, 20 | val role: String, 21 | val slogan: String, 22 | val title: String 23 | ) 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ChatRoomSignInBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ChatRoomSignInBean( 4 | var token: String="", 5 | val error: String, 6 | val message: String, 7 | val statusCode: Int 8 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/CollectionsBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class CollectionsBean( 4 | val collections: List 5 | ) { 6 | 7 | data class Collection( 8 | val comics: List, 9 | val title: String 10 | ) { 11 | 12 | data class Comic( 13 | val _id: String, 14 | val author: String, 15 | val categories: List, 16 | val epsCount: Int, 17 | val finished: Boolean, 18 | val pagesCount: Int, 19 | val thumb: Thumb, 20 | val title: String, 21 | val totalLikes: Int, 22 | val totalViews: Int 23 | ) { 24 | 25 | data class Thumb( 26 | val fileServer: String, 27 | val originalName: String, 28 | val path: String 29 | ) 30 | } 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ComicInfoBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ComicInfoBean( 4 | val comic: Comic 5 | ) { 6 | 7 | data class Comic( 8 | val _creator: Creator, 9 | val _id: String, 10 | val allowComment: Boolean, 11 | val allowDownload: Boolean, 12 | val author: String, 13 | val categories: List, 14 | val chineseTeam: String, 15 | val commentsCount: Int, 16 | val created_at: String, 17 | val description: String, 18 | val epsCount: Int, 19 | val finished: Boolean, 20 | val isFavourite: Boolean, 21 | val isLiked: Boolean, 22 | val likesCount: Int, 23 | val pagesCount: Int, 24 | val tags: List, 25 | val thumb: Thumb, 26 | val title: String, 27 | val totalComments: Int, 28 | val totalLikes: Int, 29 | val totalViews: Int, 30 | val updated_at: String, 31 | val viewsCount: Int 32 | ) { 33 | data class Creator( 34 | val _id: String, 35 | val avatar: Avatar, 36 | val characters: List, 37 | val exp: Int, 38 | val gender: String, 39 | val level: Int, 40 | val name: String, 41 | val role: String, 42 | val slogan: String, 43 | val title: String, 44 | val character: String, 45 | val verified: Boolean 46 | ) 47 | 48 | data class Thumb( 49 | val fileServer: String, 50 | val originalName: String, 51 | val path: String 52 | ) 53 | 54 | data class Avatar( 55 | val fileServer: String, 56 | val originalName: String, 57 | val path: String 58 | ) 59 | 60 | 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ComicListBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ComicListBean( 4 | val comics: Comics 5 | ) { 6 | 7 | data class Comics( 8 | val docs: List, 9 | val limit: Int, 10 | val page: Int, 11 | val pages: Int, 12 | val total: Int 13 | ) { 14 | data class Doc( 15 | val _id: String, 16 | val author: String, 17 | val categories: List, 18 | val epsCount: Int, 19 | val finished: Boolean, 20 | val id: String, 21 | val likesCount: Int, 22 | val pagesCount: Int, 23 | val thumb: Thumb, 24 | val title: String, 25 | val totalLikes: Int, 26 | val totalViews: Int 27 | ) { 28 | 29 | data class Thumb( 30 | val fileServer: String, 31 | val originalName: String, 32 | val path: String 33 | ) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ComicListBean2.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | //漫画列表第二种数据类型 4 | data class ComicListBean2( 5 | val comics: List 6 | ){ 7 | 8 | data class Comics( 9 | val _id: String, 10 | val title: String, 11 | val author: String, 12 | val pagesCount: Int, 13 | val epsCount: Int, 14 | val finished: Boolean, 15 | val thumb: Thumb, 16 | val totalViews: Int, 17 | val totalLikes: Int, 18 | val likesCount: Int, 19 | val viewsCount: Int, 20 | val leaderboardCount: Int, 21 | val categories: List 22 | ){ 23 | 24 | data class Thumb( 25 | val fileServer: String, 26 | val path: String, 27 | val originalName: String 28 | ) 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ComicsPictureBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ComicsPictureBean( 4 | val pages: Pages, 5 | val ep: Ep 6 | ) { 7 | data class Pages( 8 | val total: Int, 9 | val limit: Int, 10 | val page: Int, 11 | val pages: Int, 12 | val docs: List 13 | ) { 14 | data class Docs( 15 | val _id: String, 16 | val media: Media, 17 | val id: String 18 | ) { 19 | data class Media( 20 | val originalName: String, 21 | val path: String, 22 | val fileServer: String 23 | ) 24 | } 25 | } 26 | 27 | data class Ep( 28 | val _id: String, 29 | val title: String 30 | ) 31 | } 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/CommentsBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class CommentsBean( 4 | val comments: Comments, 5 | val topComments: List 6 | ) { 7 | data class Comments( 8 | var docs: List, 9 | val limit: Int, 10 | val page: Int, 11 | val pages: Int, 12 | val total: Int 13 | ) { 14 | data class Doc( 15 | var _id: String, 16 | var _user: User, 17 | var commentsCount: Int, 18 | var content: String, 19 | var created_at: String, 20 | var hide: Boolean, 21 | var id: String, 22 | var isLiked: Boolean, 23 | var isTop: Boolean, 24 | var likesCount: Int, 25 | var totalComments: Int, 26 | var isMainComment: Boolean 27 | ) 28 | } 29 | 30 | data class TopComment( 31 | val _id: String, 32 | val _user: User, 33 | val commentsCount: Int, 34 | val content: String, 35 | val created_at: String, 36 | val hide: Boolean, 37 | val isLiked: Boolean, 38 | val isTop: Boolean, 39 | val likesCount: Int, 40 | val totalComments: Int 41 | ) 42 | data class User( 43 | val _id: String, 44 | val avatar: Avatar, 45 | val character: String, 46 | val characters: List, 47 | val exp: Int, 48 | val gender: String, 49 | val level: Int, 50 | val name: String, 51 | val role: String, 52 | val slogan: String, 53 | val title: String, 54 | val verified: Boolean 55 | ) { 56 | data class Avatar( 57 | val fileServer: String, 58 | val originalName: String, 59 | val path: String 60 | ) 61 | } 62 | } 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/EpisodeBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class EpisodeBean( 4 | val eps: Eps 5 | ) { 6 | 7 | data class Eps( 8 | val docs: List, 9 | val limit: Int, 10 | val page: Int, 11 | val pages: Int, 12 | val total: Int 13 | ) { 14 | 15 | data class Doc( 16 | val _id: String, 17 | val id: String, 18 | val order: Int, 19 | val title: String, 20 | val updated_at: String 21 | ) 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/GameInfoBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | 4 | data class GameInfoBean( 5 | val game: Game 6 | ) { 7 | data class Game( 8 | val adult: Boolean, 9 | val android: Boolean, 10 | val androidLinks: List, 11 | val androidSize: Float, 12 | val commentsCount: Int, 13 | val createdAt: String, 14 | val description: String, 15 | val downloadsCount: Int, 16 | val icon: Icon, 17 | val id: String, 18 | val ios: Boolean, 19 | val iosLinks: List, 20 | val iosSize: Float, 21 | val isLiked: Boolean, 22 | val likesCount: Int, 23 | val publisher: String, 24 | val screenshots: List, 25 | val suggest: Boolean, 26 | val title: String, 27 | val updatedAt: String, 28 | val version: String, 29 | val videoLink: String, 30 | val updateContent: String 31 | ) { 32 | data class Icon( 33 | val fileServer: String, 34 | val originalName: String, 35 | val path: String 36 | ) 37 | 38 | data class Screenshot( 39 | val fileServer: String, 40 | val originalName: String, 41 | val path: String 42 | ) 43 | } 44 | 45 | } 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/GamesBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | 4 | data class GamesBean( 5 | val games: Games 6 | ) { 7 | data class Games( 8 | val docs: List, 9 | val limit: Int, 10 | val page: Int, 11 | val pages: Int, 12 | val total: Int 13 | ) { 14 | data class Docs( 15 | val adult: Boolean, 16 | val android: Boolean, 17 | val icon: Icon, 18 | val _id: String, 19 | val ios: Boolean, 20 | val publisher: String, 21 | val suggest: Boolean, 22 | val title: String, 23 | val version: String 24 | ) { 25 | data class Icon( 26 | val fileServer: String, 27 | val originalName: String, 28 | val path: String 29 | ) 30 | } 31 | } 32 | } 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/InitBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class InitBean( 8 | @SerialName("addresses") 9 | val addresses: List = listOf(), 10 | @SerialName("status") 11 | val status: String = "", 12 | ) 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/KeywordsBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class KeywordsBean( 4 | val keywords: List 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/KnightBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class KnightBean( 4 | val users: List 5 | ) { 6 | data class Users( 7 | /** 8 | * _id : 593019d53f532059f297efa7 9 | * gender : m 10 | * name : 黎欧 11 | * slogan : emmm。。。二八七六八七八三九二(QQ代传邮箱,请标注来意不然我只能无视了) 12 | * title : 萌新 13 | * verified : false 14 | * exp : 1742339 15 | * level : 132 16 | * characters : ["knight"] 17 | * role : knight 18 | * avatar : {"fileServer":"https://storage1.picacomic.com","path":"6b6b7a4a-4485-4e6b-aca8-2796ad3d06dd.jpg","originalName":"avatar.jpg"} 19 | * comicsUploaded : 12051 20 | * character : https://pica-web.wakamoment.tk/special/frame-456.png 21 | */ 22 | val _id: String, 23 | val gender: String, 24 | val name: String, 25 | val slogan: String, 26 | val title: String, 27 | val isVerified: Boolean, 28 | val exp: Int, 29 | val level: Int, 30 | val role: String, 31 | val avatar: Avatar, 32 | val comicsUploaded: Int, 33 | val character: String, 34 | val characters: List 35 | ) { 36 | data class Avatar( 37 | /** 38 | * fileServer : https://storage1.picacomic.com 39 | * path : 6b6b7a4a-4485-4e6b-aca8-2796ad3d06dd.jpg 40 | * originalName : avatar.jpg 41 | */ 42 | val fileServer: String, 43 | val path: String, 44 | val originalName: String 45 | ) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/MyCommentsBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class MyCommentsBean( 4 | val comments: Comments 5 | ) { 6 | data class Comments( 7 | val docs: List, 8 | val limit: Int, 9 | val page: String, 10 | val pages: Int, 11 | val total: Int 12 | ) { 13 | data class Doc( 14 | val _comic: Comic, 15 | val commentsCount: Int, 16 | val content: String, 17 | val created_at: String, 18 | val _game: Game, 19 | val hide: Boolean, 20 | val _id: String, 21 | val id: String, 22 | var isLiked: Boolean, 23 | var likesCount: Int, 24 | val totalComments: Int 25 | ) { 26 | data class Comic( 27 | val _id: String, 28 | val title: String 29 | ) 30 | 31 | data class Game( 32 | val _id: String, 33 | val title: String 34 | ) 35 | } 36 | } 37 | } 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/NotificationsBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | //通知 4 | data class NotificationsBean( 5 | val notifications: Notifications 6 | ) { 7 | data class Notifications( 8 | val docs: List, 9 | val limit: Int, 10 | val page: Int, 11 | val pages: Int, 12 | val total: Int 13 | ){ 14 | data class Doc( 15 | val content: String, 16 | val cover: Cover, 17 | val created_at: String, 18 | val _id: String, 19 | val id: String, 20 | val _redirectId: String, 21 | val redirectType: String, 22 | val _sender: Sender, 23 | val system: Boolean, 24 | val title: String, 25 | val updated_at: String, 26 | val _user: String 27 | ){ 28 | data class Cover( 29 | val fileServer: String, 30 | val originalName: String, 31 | val path: String 32 | ) 33 | data class Sender( 34 | val character: String, 35 | val characters: List, 36 | val exp: Int, 37 | val gender: String, 38 | val _id: String, 39 | val level: Int, 40 | val name: String, 41 | val role: String, 42 | val slogan: String, 43 | val title: String, 44 | val avatar: Avatar, 45 | val verified: Boolean 46 | ){ 47 | data class Avatar( 48 | val fileServer: String, 49 | val originalName: String, 50 | val path: String 51 | ) 52 | } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/PicaAppsBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class PicaAppsBean( 4 | val apps: List 5 | ){ 6 | data class App( 7 | val description: String, 8 | val icon: String, 9 | val showTitleBar: Boolean, 10 | val title: String, 11 | val url: String 12 | ) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/PicaInitBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class PicaInitBean( 4 | val code: Int, 5 | val `data`: Data, 6 | val error: String, 7 | val message: String 8 | ) { 9 | data class Data( 10 | val apiLevel: Int, 11 | val categories: List, 12 | val imageServer: String, 13 | val isIdUpdated: Boolean, 14 | val isPunched: Boolean, 15 | val latestApplication: LatestApplication, 16 | val minApiLevel: Int, 17 | val notification: Any 18 | ) { 19 | data class Category( 20 | val _id: String, 21 | val title: String 22 | ) 23 | 24 | data class LatestApplication( 25 | val _id: String, 26 | val apk: Apk, 27 | val created_at: String, 28 | val downloadUrl: String, 29 | val updateContent: String, 30 | val updated_at: String, 31 | val version: String 32 | ) { 33 | data class Apk( 34 | val fileServer: String, 35 | val originalName: String, 36 | val path: String 37 | ) 38 | } 39 | } 40 | 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ProfileBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ProfileBean( 4 | val user: User 5 | ) { 6 | data class User( 7 | val _id: String, 8 | val avatar: Avatar, 9 | val birthday: String, 10 | val character: String, 11 | val characters: List, 12 | val created_at: String, 13 | val email: String, 14 | val exp: Int, 15 | val gender: String, 16 | val isPunched: Boolean, 17 | val level: Int, 18 | val name: String, 19 | val slogan: String, 20 | val title: String, 21 | val verified: Boolean 22 | ) { 23 | data class Avatar( 24 | val fileServer: String, 25 | val originalName: String, 26 | val path: String 27 | ) 28 | } 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/PunchInBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class PunchInBean( 4 | val res: Res 5 | ) { 6 | 7 | data class Res( 8 | val punchInLastDay: String, 9 | val status: String 10 | ) 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/RecommendBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class RecommendBean( 4 | val comics: List 5 | ) { 6 | 7 | data class Comic( 8 | val _id: String, 9 | val author: String, 10 | val categories: List, 11 | val epsCount: Int, 12 | val finished: Boolean, 13 | val likesCount: Int, 14 | val pagesCount: Int, 15 | val thumb: Thumb, 16 | val title: String 17 | ) { 18 | 19 | data class Thumb( 20 | val fileServer: String, 21 | val originalName: String, 22 | val path: String 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/ReportBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class ReportBean( 4 | val commentId: String, 5 | val message: String 6 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/SignInBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | data class SignInBean( 4 | val token: String, 5 | val question1: String, 6 | val question2: String, 7 | val question3: String, 8 | val password: String 9 | ) 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/bean/UpdateBean.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.bean 2 | 3 | 4 | data class UpdateBean( 5 | val android_min_api_level: String, 6 | val app_display_name: String, 7 | val app_icon_url: String, 8 | val app_name: String, 9 | val app_os: String, 10 | val bundle_identifier: String, 11 | val can_resign: Any, 12 | val destination_type: String, 13 | val device_family: Any, 14 | val distribution_group_id: String, 15 | val distribution_groups: List, 16 | val download_url: String,//下载地址 17 | val enabled: Boolean, 18 | val fileExtension: String, 19 | val fingerprint: String, 20 | val id: Int, 21 | val install_url: String, 22 | val is_external_build: Boolean, 23 | val is_latest: Boolean, 24 | val is_udid_provisioned: Any, 25 | val mandatory_update: Boolean, 26 | val min_os: String, 27 | val origin: String, 28 | val owner: Owner, 29 | val package_hashes: List, 30 | val release_notes: String,//描述 31 | val short_version: String, 32 | val size: Int, 33 | val status: String, 34 | val uploaded_at: String, 35 | val version: String//版本 36 | ){ 37 | data class DistributionGroup( 38 | val display_name: String, 39 | val id: String, 40 | val is_public: Boolean, 41 | val name: String, 42 | val origin: String 43 | ) 44 | 45 | data class Owner( 46 | val display_name: String, 47 | val name: String 48 | ) 49 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/database/BikaDatabase.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.database 2 | 3 | import android.content.Context 4 | import androidx.room.Database 5 | import androidx.room.Room 6 | import androidx.room.RoomDatabase 7 | import com.shizq.bika.database.dao.HistoryDao 8 | import com.shizq.bika.database.dao.SearchDao 9 | import com.shizq.bika.database.model.HistoryEntity 10 | import com.shizq.bika.database.model.SearchEntity 11 | 12 | @Database( 13 | entities = [HistoryEntity::class, SearchEntity::class], 14 | version = 1, 15 | exportSchema = false, 16 | ) 17 | internal abstract class BikaDatabase : RoomDatabase() { 18 | abstract fun historyDao(): HistoryDao 19 | abstract fun searchDao(): SearchDao 20 | 21 | companion object { 22 | @Volatile 23 | private var instance: BikaDatabase? = null 24 | private val LOCK = Any() 25 | 26 | operator fun invoke(context: Context) = instance ?: synchronized(LOCK) { 27 | instance ?: buildDatabase(context).also { instance = it } 28 | } 29 | 30 | private fun buildDatabase(context: Context) = 31 | Room.databaseBuilder( 32 | context.applicationContext, 33 | BikaDatabase::class.java, 34 | "bika-database" 35 | ).build() 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/database/dao/HistoryDao.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.database.dao 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.Dao 5 | import androidx.room.Delete 6 | import androidx.room.Insert 7 | import androidx.room.OnConflictStrategy 8 | import androidx.room.Query 9 | import androidx.room.Update 10 | import com.shizq.bika.database.model.HistoryEntity 11 | 12 | @Dao 13 | interface HistoryDao { 14 | @Insert(onConflict = OnConflictStrategy.REPLACE) 15 | suspend fun insertHistory(vararg historyEntity: HistoryEntity) 16 | 17 | @Update 18 | suspend fun updateHistory(vararg historyEntity: HistoryEntity) 19 | 20 | @Delete 21 | suspend fun deleteHistory(vararg historyEntity: HistoryEntity) 22 | 23 | @Query("DELETE FROM HISTORY") 24 | suspend fun deleteAllHistory() 25 | 26 | //查询全部 27 | @get:Query("SELECT * FROM HISTORY ORDER BY TIME DESC") 28 | val allHistoryEntityLive: LiveData> 29 | 30 | //查询第一页 31 | @get:Query("SELECT * FROM HISTORY ORDER BY TIME DESC LIMIT 0, 20") 32 | val firstPageHistoryEntityLive: LiveData> 33 | 34 | //分页查询 35 | @Query("SELECT * FROM HISTORY ORDER BY TIME DESC LIMIT :page, 20") 36 | suspend fun gatAllHistory(page: Int): List 37 | 38 | //根据漫画id查询数据 39 | @Query("SELECT * FROM HISTORY WHERE COMIC_OR_GAME_ID = :id LIMIT 1") 40 | suspend fun gatHistory(vararg id: String): List 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/database/dao/SearchDao.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.database.dao 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.Dao 5 | import androidx.room.Delete 6 | import androidx.room.Insert 7 | import androidx.room.OnConflictStrategy 8 | import androidx.room.Query 9 | import com.shizq.bika.database.model.SearchEntity 10 | 11 | @Dao 12 | interface SearchDao { 13 | @Insert(onConflict = OnConflictStrategy.REPLACE) 14 | suspend fun insertSearch(vararg searchEntities: SearchEntity) 15 | 16 | @Delete 17 | suspend fun deleteSearch(vararg searchEntities: SearchEntity) 18 | 19 | @Query("DELETE FROM SEARCH") 20 | suspend fun deleteAllSearch() 21 | 22 | @get:Query("SELECT DISTINCT TEXT FROM SEARCH ORDER BY ID DESC") 23 | val allSearchLive: LiveData> 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/database/model/HistoryEntity.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.database.model 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | 7 | @Entity(tableName = "HISTORY") 8 | data class HistoryEntity( 9 | @ColumnInfo(name = "time") 10 | val time: Long = 0, 11 | 12 | @ColumnInfo(name = "title") 13 | val title: String, 14 | 15 | @ColumnInfo(name = "fileServer") 16 | val fileServer: String, 17 | 18 | @ColumnInfo(name = "path") 19 | val path: String, 20 | 21 | @ColumnInfo(name = "comic_or_game") 22 | val comic_or_game: String, 23 | 24 | @ColumnInfo(name = "author") 25 | val author: String, 26 | 27 | @ColumnInfo(name = "comic_or_game_id") 28 | val comic_or_game_id: String, 29 | 30 | @ColumnInfo(name = "sort")//分类 31 | val sort: String, 32 | 33 | @ColumnInfo(name = "epsCount")//总章 34 | val epsCount: String, 35 | 36 | @ColumnInfo(name = "pagesCount")//总页 37 | val pagesCount: String, 38 | 39 | @ColumnInfo(name = "finished")//是否完结 40 | val finished: Boolean, 41 | 42 | @ColumnInfo(name = "likeCount")//爱心数 43 | val likeCount: String, 44 | 45 | @ColumnInfo(name = "ep")//观看到第几章 46 | val ep: String, 47 | 48 | @ColumnInfo(name = "page")//观看到第几页 49 | val page: String, 50 | @PrimaryKey(autoGenerate = true) 51 | var id: Long = 0 52 | ) 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/database/model/SearchEntity.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.database.model 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | 7 | @Entity(tableName = "Search") 8 | data class SearchEntity( 9 | @ColumnInfo(name = "text") 10 | val text: String, 11 | @PrimaryKey(autoGenerate = true) 12 | val id: Long = 0 13 | ) 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/network/HmacSHA256Util.java: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.network; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | 5 | import javax.crypto.Mac; 6 | import javax.crypto.spec.SecretKeySpec; 7 | 8 | /** 9 | * Created by shizq on 2020/7/30. 10 | * 反编译源码 11 | */ 12 | public class HmacSHA256Util { 13 | protected static final char[] uq = "0123456789abcdef".toCharArray(); 14 | String uo; 15 | 16 | public static String a(byte[] bArr) { 17 | char[] var4 = new char[bArr.length * 2]; 18 | for(int i = 0; i < bArr.length; i++) { 19 | int var2 = bArr[i] & 255; 20 | var4[i * 2] = (char)uq[var2 >>> 4]; 21 | var4[i * 2 + 1] = (char)uq[var2 & 15]; 22 | } 23 | return new String(var4); 24 | } 25 | 26 | public synchronized String C(String str){ 27 | String keyString = "~d}$Q7$eIni=V)9\\RK/P.RM4;9[7|@/CA}b~OW!3?EV`:<>M7pddUBL5n|0/*Cn"; 28 | byte[] keybyte; 29 | keybyte = keyString.getBytes(StandardCharsets.UTF_8); 30 | String lowerCase = str.toLowerCase(); 31 | uo = a(lowerCase, keybyte); 32 | return uo; 33 | } 34 | 35 | protected String a(String str, byte[] var2) { 36 | try { 37 | Mac mac = Mac.getInstance("HmacSHA256"); 38 | mac.init(new SecretKeySpec(var2, "HmacSHA256")); 39 | str = a(mac.doFinal(str.getBytes(StandardCharsets.UTF_8))); 40 | } catch (Exception e) { 41 | e.printStackTrace(); 42 | str = null; 43 | } 44 | return str; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/network/HttpDns.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.network 2 | 3 | import com.shizq.bika.utils.SPUtil 4 | import okhttp3.Dns 5 | import java.net.InetAddress 6 | 7 | class HttpDns : Dns { 8 | override fun lookup(hostname: String): List { 9 | //这个sp影响加载速度 以后再说 //直接默认走第一个ip不改了 10 | val host = SPUtil.get("addresses1", hostname) as String //获得分流对应的hostname 11 | return Dns.SYSTEM.lookup(host) 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/network/JsonUtil.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.network 2 | 3 | import kotlinx.serialization.json.Json 4 | 5 | val json = Json { ignoreUnknownKeys = true } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/network/Result.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.network 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | import kotlinx.coroutines.flow.catch 5 | import kotlinx.coroutines.flow.map 6 | import kotlinx.coroutines.flow.onStart 7 | 8 | sealed interface Result { 9 | data class Success(val data: T) : Result 10 | data class Error( 11 | val code: Int = 0, 12 | val error: String = "", 13 | val message: String = "", 14 | val exception: Throwable? = null, 15 | ) : Result 16 | 17 | data object Loading : Result 18 | } 19 | 20 | fun Flow.asResult(): Flow> = map> { Result.Success(it) } 21 | .onStart { emit(Result.Loading) } 22 | .catch { emit(Result.Error(exception = it)) } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/network/base/BaseHeaders.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.network.base 2 | 3 | import com.shizq.bika.network.HmacSHA256Util 4 | import com.shizq.bika.utils.SPUtil 5 | import java.util.* 6 | 7 | class BaseHeaders(private val urlEnd: String = "", val type: String = "") { 8 | 9 | fun getHeaders(): MutableMap { 10 | val apikey = "C69BAF41DA5ABD1FFEDC6D2FEA56B" 11 | val nonce = UUID.randomUUID().toString().replace("-", "") 12 | val time = (System.currentTimeMillis() / 1000).toString() 13 | val signature = HmacSHA256Util().C((urlEnd + time + nonce + type + apikey)) 14 | val map: MutableMap = HashMap() 15 | map["api-key"] = apikey 16 | map["accept"] = "application/vnd.picacomic.com.v1+json" 17 | map["app-channel"] = SPUtil.get("setting_app_channel", "2") as String 18 | map["time"] = time 19 | map["nonce"] = nonce 20 | map["signature"] = signature 21 | map["app-version"] = "2.2.1.3.3.4" 22 | map["app-uuid"] = "defaultUuid" 23 | map["image-quality"] = "original" 24 | map["app-platform"] = "android" 25 | map["app-build-version"] = "45" 26 | map["user-agent"] = "okhttp/3.8.1" 27 | return map 28 | } 29 | 30 | fun getHeaderMapAndToken(): Map { 31 | val map = getHeaders() 32 | map["authorization"] = SPUtil.get("token", "") as String 33 | return map 34 | } 35 | 36 | fun getChatHeaders(): MutableMap { 37 | val map: MutableMap = HashMap() 38 | map["user-agent"] = "Dart/2.19 (dart:io)" 39 | map["api-version"] = "1.0.3" 40 | map["content-type"] = "application/json; charset=UTF-8" 41 | return map 42 | } 43 | 44 | fun getChatHeaderMapAndToken(): MutableMap { 45 | val map = getChatHeaders() 46 | map["authorization"] = "Bearer " + SPUtil.get("chat_token", "") as String 47 | return map 48 | } 49 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/network/base/BaseResponse.java: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.network.base; 2 | 3 | public class BaseResponse { 4 | 5 | private int code; // 服务器返回的状态码 6 | private String message; // 服务器返回的状态信息 7 | private String error; // 服务器返回的异常code信息 8 | private T data; // 服务器返回的数据封装 9 | //val detail: String 10 | 11 | /* 12 | * 不同公司是否代表成功的code不同, 也许变量名也不同,这里用isOK来封装,根据自己公司情况进行判断 13 | */ 14 | private boolean isOk; 15 | 16 | public int getCode() { 17 | return code; 18 | } 19 | 20 | public void setCode(int code) { 21 | this.code = code; 22 | } 23 | 24 | public String getMessage() { 25 | return message; 26 | } 27 | 28 | public void setMessage(String message) { 29 | this.message = message; 30 | } 31 | 32 | public String getError() { 33 | return error; 34 | } 35 | 36 | public void setError(String error) { 37 | this.error = error; 38 | } 39 | 40 | public T getData() { 41 | return data; 42 | } 43 | 44 | public void setData(T data) { 45 | this.data = data; 46 | } 47 | 48 | /** 49 | * 网络返回 50 | * 51 | * @return 自己公司服务器代表成功返回的唯一字段, 我们用isOk来封装 52 | */ 53 | public boolean isOk() { 54 | return code == 200&&data!=null; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/network/websocket/IReceiveMessage.java: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.network.websocket; 2 | 3 | public interface IReceiveMessage { 4 | void onConnectSuccess();// 连接成功 5 | 6 | void onConnectFailed();// 连接失败 7 | 8 | void onClose(); // 关闭 9 | 10 | void onMessage(String text); 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/account/AccountActivity.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.account 2 | 3 | import android.os.Bundle 4 | import android.view.MenuItem 5 | import androidx.activity.addCallback 6 | import com.shizq.bika.BR 7 | import com.shizq.bika.R 8 | import com.shizq.bika.base.BaseActivity 9 | import com.shizq.bika.databinding.ActivityAccountBinding 10 | 11 | //登录注册 12 | class AccountActivity : BaseActivity() { 13 | 14 | override fun initContentView(savedInstanceState: Bundle?): Int { 15 | return R.layout.activity_account 16 | } 17 | 18 | override fun initVariableId(): Int { 19 | return BR.viewModel 20 | } 21 | 22 | override fun initData() { 23 | setSupportActionBar(binding.loginInclude.toolbar) 24 | } 25 | 26 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 27 | when (item.itemId) { 28 | android.R.id.home -> { 29 | //只有注册页有返回键 所以回退到登录页 30 | onBackPressedDispatcher.onBackPressed() 31 | } 32 | } 33 | return super.onOptionsItemSelected(item) 34 | } 35 | 36 | //返回键执行home键 //TODO 需要优化 添加到 fragment中 37 | @Deprecated("Deprecated in Java") 38 | override fun onBackPressed() { 39 | super.onBackPressed() 40 | //只有一级所以就不判断了 只有注册页面会返回到登录页 登录页返回是退出应用 41 | supportActionBar?.title = "登录" 42 | supportActionBar?.setDisplayHomeAsUpEnabled(false) 43 | } 44 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/account/AccountViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.account 2 | 3 | import android.app.Application 4 | import com.shizq.bika.base.BaseViewModel 5 | 6 | class AccountViewModel(application: Application) : BaseViewModel(application) { 7 | 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/apps/AppsActivity.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.apps 2 | 3 | import android.os.Bundle 4 | import android.view.MenuItem 5 | import com.google.android.material.tabs.TabLayoutMediator 6 | import com.shizq.bika.BR 7 | import com.shizq.bika.R 8 | import com.shizq.bika.adapter.ViewPagerAdapter 9 | import com.shizq.bika.base.BaseActivity 10 | import com.shizq.bika.databinding.ActivityAppsBinding 11 | 12 | //小程序 13 | class AppsActivity : BaseActivity() { 14 | 15 | override fun initContentView(savedInstanceState: Bundle?): Int { 16 | return R.layout.activity_apps 17 | } 18 | 19 | override fun initVariableId(): Int { 20 | return BR.viewModel 21 | } 22 | 23 | override fun initData() { 24 | binding.toolbar.title = "哔咔小程序" 25 | setSupportActionBar(binding.toolbar) 26 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 27 | 28 | 29 | val chat = AppsFragment() 30 | val apps = AppsFragment() 31 | 32 | val chatBundle = Bundle() 33 | chatBundle.putString("key", "chat") 34 | chat.arguments = chatBundle 35 | 36 | val appsBundle = Bundle() 37 | appsBundle.putString("key", "apps") 38 | apps.arguments = appsBundle 39 | 40 | val tabText = listOf("聊天室", "小程序") 41 | val tabList = listOf(chat, apps) 42 | val tabAdapter = ViewPagerAdapter(tabList, supportFragmentManager, this.lifecycle) 43 | binding.appsVp.apply { 44 | adapter = tabAdapter 45 | offscreenPageLimit = 1 46 | } 47 | TabLayoutMediator(binding.appsTab, binding.appsVp) { tab, position -> 48 | tab.text = tabText[position] 49 | }.attach() 50 | } 51 | 52 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 53 | when (item.itemId) { 54 | android.R.id.home -> { 55 | finish() 56 | } 57 | 58 | } 59 | return super.onOptionsItemSelected(item) 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/apps/AppsFragmentViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.apps 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.viewModelScope 5 | import com.shizq.bika.base.BaseViewModel 6 | import com.shizq.bika.bean.ChatRoomListOldBean 7 | import com.shizq.bika.bean.PicaAppsBean 8 | import com.shizq.bika.network.Result 9 | import kotlinx.coroutines.flow.MutableStateFlow 10 | import kotlinx.coroutines.flow.StateFlow 11 | import kotlinx.coroutines.launch 12 | 13 | class AppsFragmentViewModel(application: Application) : BaseViewModel(application) { 14 | private val repository = AppsRepository() 15 | 16 | private val _roomList = MutableStateFlow?>(null) 17 | val roomList: StateFlow?> = _roomList 18 | private val _appsFlow = MutableStateFlow?>(null) 19 | val appsFlow: StateFlow?> = _appsFlow 20 | 21 | fun getChatList() { 22 | viewModelScope.launch { 23 | repository.getRoomListFlow().collect { 24 | _roomList.value = it 25 | } 26 | } 27 | } 28 | 29 | fun getPicaApps() { 30 | viewModelScope.launch { 31 | repository.getAppsFlow().collect { apps -> 32 | _appsFlow.value = apps 33 | } 34 | } 35 | 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/apps/AppsRepository.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.apps 2 | 3 | import com.shizq.bika.bean.ChatRoomListOldBean 4 | import com.shizq.bika.bean.PicaAppsBean 5 | import com.shizq.bika.network.Result 6 | import com.shizq.bika.network.RetrofitUtil 7 | import com.shizq.bika.network.base.BaseHeaders 8 | import kotlinx.coroutines.Dispatchers 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.catch 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.flow.flowOn 13 | 14 | class AppsRepository { 15 | 16 | suspend fun getRoomListFlow(): Flow> = flow { 17 | emit(Result.Loading) 18 | val response = RetrofitUtil.service.oldChatRoomListGet(BaseHeaders("chat", "GET").getHeaderMapAndToken()) 19 | if (response.code==200) { 20 | val data = response.data 21 | if (data != null) { 22 | emit(Result.Success(data)) 23 | } else { 24 | emit(Result.Error(response.code,"","请求结果为空")) 25 | } 26 | } else { 27 | emit(Result.Error(response.code,response.error,response.message)) 28 | } 29 | }.catch{ 30 | emit(Result.Error(-1,"","请求结果异常")) 31 | }.flowOn(Dispatchers.IO) 32 | 33 | suspend fun getAppsFlow(): Flow> = flow { 34 | emit(Result.Loading) 35 | val response = RetrofitUtil.service.picaAppsGet(BaseHeaders("pica-apps", "GET").getHeaderMapAndToken()) 36 | if (response.code==200) { 37 | val data = response.data 38 | if (data != null) { 39 | emit(Result.Success(data)) 40 | } else { 41 | emit(Result.Error(response.code,"","请求结果为空")) 42 | } 43 | } else { 44 | emit(Result.Error(response.code,response.error,response.message)) 45 | } 46 | }.catch{ 47 | emit(Result.Error(-1,"","请求结果异常")) 48 | }.flowOn(Dispatchers.IO) 49 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/apps/AppsViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.apps 2 | 3 | import android.app.Application 4 | import com.shizq.bika.base.BaseViewModel 5 | 6 | class AppsViewModel(application: Application) : BaseViewModel(application) { 7 | 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/chatroom/current/blacklist/ChatBlacklistRepository.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.chatroom.current.blacklist 2 | 3 | import com.shizq.bika.bean.ChatRoomBlackListBean 4 | import com.shizq.bika.bean.ChatRoomBlackListDeleteBean 5 | import com.shizq.bika.network.Result 6 | import com.shizq.bika.network.RetrofitUtil 7 | import com.shizq.bika.network.base.BaseHeaders 8 | import kotlinx.coroutines.Dispatchers 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.catch 11 | import kotlinx.coroutines.flow.flow 12 | import kotlinx.coroutines.flow.flowOn 13 | 14 | class ChatBlacklistRepository {suspend fun getBlackListFlow(pageNum: Int): Flow> = flow { 15 | emit(Result.Loading) 16 | val response = RetrofitUtil.service_live.chatBlackListGet(pageNum, BaseHeaders().getChatHeaderMapAndToken()) 17 | 18 | if (response.limit != 0) { 19 | emit(Result.Success(response)) 20 | } else { 21 | emit(Result.Error(response.statusCode, response.error, response.message)) 22 | } 23 | 24 | }.catch { 25 | // TODO 需要补充异常处理(code error message) 26 | emit(Result.Error(-1, "请求结果异常", it.message.toString())) 27 | }.flowOn(Dispatchers.IO) 28 | 29 | suspend fun deleteBlackListFlow(id: String): Flow> = flow { 30 | emit(Result.Loading) 31 | val response = RetrofitUtil.service_live.chatBlackListDelete(id, BaseHeaders().getChatHeaderMapAndToken()) 32 | 33 | if (response.id != null&&response.id != "") { 34 | emit(Result.Success(response)) 35 | } else { 36 | emit(Result.Error(response.statusCode, response.error, response.message)) 37 | } 38 | 39 | }.catch { 40 | // TODO 需要补充异常处理(code error message) 41 | emit(Result.Error(-1, "请求结果异常", it.message.toString())) 42 | }.flowOn(Dispatchers.IO) 43 | 44 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/chatroom/old/ChatRoomViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.chatroom.old 2 | 3 | import android.app.Application 4 | import android.graphics.drawable.AnimationDrawable 5 | import android.media.MediaPlayer 6 | import android.util.Base64 7 | import android.view.View 8 | import android.widget.ImageView 9 | import com.shizq.bika.base.BaseViewModel 10 | import java.io.File 11 | import java.io.FileInputStream 12 | import java.io.FileOutputStream 13 | 14 | class ChatRoomViewModel(application: Application) : BaseViewModel(application) { 15 | var url = "" 16 | 17 | var reply: String = "" 18 | var reply_name: String = "" 19 | var atname: String = "" 20 | 21 | fun playAudio(audio: String, imageview: View) { 22 | val voiceImage = imageview as ImageView 23 | val animationDrawable = voiceImage.background as AnimationDrawable 24 | if (!animationDrawable.isRunning) { 25 | // TODO 有bug 会有不播放的情况 26 | val mp3SoundByteArray: ByteArray = 27 | Base64.decode(audio.replace("\n", ""), Base64.DEFAULT) 28 | 29 | val tempMp3: File = File.createTempFile("audio", ".mp3") 30 | val fos = FileOutputStream(tempMp3) 31 | fos.write(mp3SoundByteArray) 32 | fos.close() 33 | val fis = FileInputStream(tempMp3) 34 | 35 | val mediaPlayer = MediaPlayer() 36 | mediaPlayer.setDataSource(fis.fd) 37 | mediaPlayer.prepareAsync() 38 | mediaPlayer.isLooping = false 39 | 40 | mediaPlayer.setOnPreparedListener { player -> 41 | player.start() 42 | animationDrawable.start() 43 | } 44 | 45 | mediaPlayer.setOnCompletionListener { mp -> 46 | mp.stop() 47 | mp.release() 48 | tempMp3.delete() 49 | animationDrawable.stop() 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/collections/CollectionsRepository.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.collections 2 | 3 | import com.shizq.bika.bean.CollectionsBean 4 | import com.shizq.bika.network.Result 5 | import com.shizq.bika.network.RetrofitUtil 6 | import com.shizq.bika.network.base.BaseHeaders 7 | import kotlinx.coroutines.Dispatchers 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.catch 10 | import kotlinx.coroutines.flow.flow 11 | import kotlinx.coroutines.flow.flowOn 12 | 13 | class CollectionsRepository { 14 | suspend fun getDataFlow(): Flow> = flow { 15 | emit(Result.Loading) 16 | val response = RetrofitUtil.service.collectionsGet(BaseHeaders("collections","GET").getHeaderMapAndToken()) 17 | if (response.code==200) { 18 | val data = response.data 19 | if (data != null) { 20 | emit(Result.Success(data)) 21 | } else { 22 | emit(Result.Error(response.code,"","请求结果为空")) 23 | } 24 | } else { 25 | emit(Result.Error(response.code,response.error,response.message)) 26 | } 27 | }.catch{ 28 | emit(Result.Error(-1,"","请求结果异常")) 29 | }.flowOn(Dispatchers.IO) 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/collections/CollectionsViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.collections 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.viewModelScope 5 | import com.shizq.bika.base.BaseViewModel 6 | import com.shizq.bika.bean.CollectionsBean 7 | import com.shizq.bika.network.Result 8 | import kotlinx.coroutines.flow.MutableStateFlow 9 | import kotlinx.coroutines.flow.StateFlow 10 | import kotlinx.coroutines.launch 11 | 12 | class CollectionsViewModel(application: Application) : BaseViewModel(application) { 13 | 14 | private val repository =CollectionsRepository() 15 | private val _collections = MutableStateFlow?>(null) 16 | val collections: StateFlow?> = _collections 17 | 18 | fun getData() { 19 | viewModelScope.launch { 20 | repository.getDataFlow().collect { 21 | _collections.value = it 22 | } 23 | } 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/games/GamesViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.games 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.MutableLiveData 5 | import com.shizq.bika.base.BaseViewModel 6 | import com.shizq.bika.bean.GamesBean 7 | import com.shizq.bika.network.RetrofitUtil 8 | import com.shizq.bika.network.base.BaseHeaders 9 | import com.shizq.bika.network.base.BaseObserver 10 | import com.shizq.bika.network.base.BaseResponse 11 | 12 | class GamesViewModel(application: Application) : BaseViewModel(application) { 13 | var page = 0//当前页数 14 | 15 | val liveData: MutableLiveData> by lazy { 16 | MutableLiveData>() 17 | } 18 | 19 | fun getGames() { 20 | page++//每次请求加1 21 | RetrofitUtil.service.gamesGet( 22 | page.toString(), 23 | BaseHeaders("games?page=$page", "GET").getHeaderMapAndToken() 24 | ) 25 | .doOnSubscribe(this) 26 | .subscribe(object : BaseObserver(){ 27 | override fun onSuccess(baseResponse: BaseResponse) { 28 | liveData.postValue(baseResponse) 29 | } 30 | 31 | override fun onCodeError(baseResponse: BaseResponse) { 32 | page-- 33 | liveData.postValue(baseResponse ) 34 | } 35 | }) 36 | } 37 | 38 | } 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/history/HistoryViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.history 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.LiveData 5 | import androidx.lifecycle.viewModelScope 6 | import com.shizq.bika.base.BaseViewModel 7 | import com.shizq.bika.database.BikaDatabase 8 | import com.shizq.bika.database.model.HistoryEntity 9 | import kotlinx.coroutines.launch 10 | 11 | class HistoryViewModel (application: Application) : BaseViewModel(application) { 12 | var page=0 13 | 14 | private val historyDao = BikaDatabase(application).historyDao() 15 | 16 | //查询第一页 17 | val firstPageHistoryEntityLive: LiveData> 18 | get() = historyDao.firstPageHistoryEntityLive 19 | 20 | //分页查询 (未验证能不能用) 21 | suspend fun getAllHistory(): List{ 22 | page += 20 23 | return historyDao.gatAllHistory(page) 24 | } 25 | 26 | fun deleteHistory(vararg historyEntity: HistoryEntity) { 27 | viewModelScope.launch { 28 | historyDao.deleteHistory(*historyEntity) 29 | } 30 | } 31 | 32 | fun deleteAllHistory() { 33 | viewModelScope.launch { 34 | historyDao.deleteAllHistory() 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/image/ImageActivity.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.image 2 | 3 | import android.os.Bundle 4 | import androidx.core.view.ViewCompat 5 | import com.shizq.bika.BR 6 | import com.shizq.bika.R 7 | import com.shizq.bika.base.BaseActivity 8 | import com.shizq.bika.databinding.ActivityImageBinding 9 | import com.bumptech.glide.Glide 10 | import com.shizq.bika.utils.GlideUrlNewKey 11 | 12 | //图片展示 13 | class ImageActivity : BaseActivity() { 14 | 15 | override fun initContentView(savedInstanceState: Bundle?): Int { 16 | return R.layout.activity_image 17 | } 18 | 19 | override fun initVariableId(): Int { 20 | return BR.viewModel 21 | } 22 | 23 | override fun initData() { 24 | ViewCompat.setTransitionName(binding.touchImageView,"image") 25 | val fileserver = intent.getStringExtra("fileserver") as String 26 | val imageurl = intent.getStringExtra("imageurl") as String 27 | 28 | Glide 29 | .with(this) 30 | .load( 31 | if (imageurl != "") { 32 | GlideUrlNewKey(fileserver, imageurl) 33 | } else { 34 | R.drawable.placeholder_transparent_low 35 | } 36 | ) 37 | // .placeholder(R.drawable.placeholder_transparent_low) 38 | .into(binding.touchImageView) 39 | 40 | binding.touchImageView.setOnClickListener { 41 | finishAfterTransition() 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/image/ImageViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.image 2 | 3 | import android.app.Application 4 | import com.shizq.bika.base.BaseViewModel 5 | 6 | class ImageViewModel(application: Application) : BaseViewModel(application) { 7 | 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/leaderboard/LeaderboardDayViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.leaderboard 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.MutableLiveData 5 | import com.shizq.bika.base.BaseViewModel 6 | import com.shizq.bika.bean.ComicListBean2 7 | import com.shizq.bika.network.RetrofitUtil 8 | import com.shizq.bika.network.base.BaseHeaders 9 | import com.shizq.bika.network.base.BaseObserver 10 | import com.shizq.bika.network.base.BaseResponse 11 | 12 | class LeaderboardDayViewModel(application: Application) : BaseViewModel(application) { 13 | var tt: String? =null 14 | val liveData: MutableLiveData> by lazy { 15 | MutableLiveData>() 16 | } 17 | 18 | 19 | fun getLeaderboard() { 20 | RetrofitUtil.service.leaderboardGet(tt.toString(), "VC", BaseHeaders("comics/leaderboard?tt=${tt}&ct=VC", "GET").getHeaderMapAndToken() 21 | ) 22 | .doOnSubscribe(this@LeaderboardDayViewModel) 23 | .subscribe(object : BaseObserver() { 24 | override fun onSuccess(baseResponse: BaseResponse) { 25 | // 请求成功 26 | liveData.postValue(baseResponse) 27 | } 28 | 29 | override fun onCodeError(baseResponse: BaseResponse) { 30 | liveData.postValue(baseResponse) 31 | } 32 | }) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/leaderboard/LeaderboardKnightViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.leaderboard 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.MutableLiveData 5 | import com.shizq.bika.base.BaseViewModel 6 | import com.shizq.bika.bean.KnightBean 7 | import com.shizq.bika.network.RetrofitUtil 8 | import com.shizq.bika.network.base.BaseHeaders 9 | import com.shizq.bika.network.base.BaseObserver 10 | import com.shizq.bika.network.base.BaseResponse 11 | 12 | class LeaderboardKnightViewModel(application: Application) : BaseViewModel(application) { 13 | val liveData: MutableLiveData> by lazy { 14 | MutableLiveData>() 15 | } 16 | 17 | fun getKnight() { 18 | RetrofitUtil.service.knightGet( 19 | BaseHeaders("comics/knight-leaderboard", "GET").getHeaderMapAndToken() 20 | ) 21 | .doOnSubscribe(this@LeaderboardKnightViewModel) 22 | .subscribe(object : BaseObserver() { 23 | override fun onSuccess(baseResponse: BaseResponse) { 24 | // 请求成功 25 | liveData.postValue(baseResponse) 26 | } 27 | 28 | override fun onCodeError(baseResponse: BaseResponse) { 29 | liveData.postValue(baseResponse) 30 | } 31 | 32 | }) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/leaderboard/LeaderboardViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.leaderboard 2 | 3 | import android.app.Application 4 | import com.shizq.bika.base.BaseViewModel 5 | 6 | class LeaderboardViewModel(application: Application) : BaseViewModel(application) { 7 | 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/notifications/NotificationsViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.notifications 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.MutableLiveData 5 | import com.shizq.bika.base.BaseViewModel 6 | import com.shizq.bika.bean.NotificationsBean 7 | import com.shizq.bika.network.RetrofitUtil 8 | import com.shizq.bika.network.base.BaseHeaders 9 | import com.shizq.bika.network.base.BaseObserver 10 | import com.shizq.bika.network.base.BaseResponse 11 | 12 | class NotificationsViewModel (application: Application) : BaseViewModel(application) { 13 | var page = 0 14 | 15 | val liveData: MutableLiveData> by lazy { 16 | MutableLiveData>() 17 | } 18 | 19 | fun getNotifications() { 20 | page++ 21 | RetrofitUtil.service.notificationsGet( 22 | page.toString(), 23 | BaseHeaders("users/notifications?page=$page", "GET").getHeaderMapAndToken() 24 | ) 25 | .doOnSubscribe(this) 26 | .subscribe(object : BaseObserver() { 27 | override fun onSuccess(baseResponse: BaseResponse) { 28 | liveData.postValue(baseResponse) 29 | } 30 | 31 | override fun onCodeError(baseResponse: BaseResponse) { 32 | page-- 33 | liveData.postValue(baseResponse) 34 | } 35 | 36 | }) 37 | } 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/settings/SettingsActivity.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.settings 2 | 3 | import android.os.Bundle 4 | import android.view.MenuItem 5 | import com.shizq.bika.BR 6 | import com.shizq.bika.R 7 | import com.shizq.bika.base.BaseActivity 8 | import com.shizq.bika.databinding.ActivitySettingsBinding 9 | 10 | class SettingsActivity : BaseActivity() { 11 | 12 | override fun initContentView(savedInstanceState: Bundle?): Int { 13 | if (savedInstanceState == null) { 14 | supportFragmentManager 15 | .beginTransaction() 16 | .replace(R.id.cat_topappbar_preferences_container, SettingsPreferenceFragment()) 17 | .commit() 18 | } 19 | return R.layout.activity_settings 20 | } 21 | 22 | override fun initVariableId(): Int { 23 | return BR.viewModel 24 | } 25 | 26 | override fun initData() { 27 | binding.comiclistInclude.toolbar.title = "设置" 28 | setSupportActionBar(binding.comiclistInclude.toolbar) 29 | supportActionBar?.setDisplayHomeAsUpEnabled(true); 30 | } 31 | 32 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 33 | 34 | when (item.itemId) { 35 | //Toolbar的事件---返回 36 | android.R.id.home -> { 37 | finish() 38 | } 39 | } 40 | 41 | return super.onOptionsItemSelected(item) 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/settings/SettingsViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.settings 2 | 3 | import android.app.Application 4 | import com.shizq.bika.base.BaseViewModel 5 | 6 | class SettingsViewModel(application: Application) : BaseViewModel(application) { 7 | 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/ui/splash/SplashViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.ui.splash 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.MutableLiveData 5 | import com.shizq.bika.base.BaseViewModel 6 | import com.shizq.bika.bean.InitBean 7 | import com.shizq.bika.bean.UpdateBean 8 | import com.shizq.bika.network.RetrofitUtil 9 | import io.reactivex.rxjava3.core.Observer 10 | import io.reactivex.rxjava3.disposables.Disposable 11 | import io.reactivex.rxjava3.observers.DefaultObserver 12 | 13 | class SplashViewModel(application: Application) : BaseViewModel(application) { 14 | val liveData_latest_version: MutableLiveData by lazy { 15 | MutableLiveData() 16 | } 17 | 18 | val liveData_init: MutableLiveData by lazy { 19 | MutableLiveData() 20 | } 21 | val liveData_init_error: MutableLiveData by lazy { 22 | MutableLiveData() 23 | } 24 | 25 | fun getLatestVersion() { 26 | RetrofitUtil.service_update.updateGet() 27 | .doOnSubscribe(this@SplashViewModel) 28 | .subscribe(object : Observer { 29 | override fun onNext(t: UpdateBean) { 30 | liveData_latest_version.postValue(t) 31 | } 32 | 33 | override fun onError(e: Throwable) {} 34 | override fun onSubscribe(d: Disposable) {} 35 | override fun onComplete() {} 36 | 37 | }) 38 | } 39 | 40 | fun getInit() { 41 | RetrofitUtil.service_init.initGet() 42 | .doOnSubscribe(this@SplashViewModel) 43 | .subscribe(object : DefaultObserver() { 44 | 45 | override fun onNext(bean: InitBean) { 46 | // 请求成功 47 | liveData_init.postValue(bean) 48 | 49 | } 50 | 51 | override fun onError(throwable: Throwable) { 52 | //请求失败 53 | liveData_init_error.postValue(throwable.message) 54 | } 55 | 56 | override fun onComplete() {} 57 | 58 | }) 59 | } 60 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/utils/AndroidBug5497Workaround.java: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.utils; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Rect; 5 | import android.view.View; 6 | import android.widget.FrameLayout; 7 | 8 | //https://www.jianshu.com/p/306482e17080 9 | //软键盘挡住输入框问题的解决方案 10 | public class AndroidBug5497Workaround { 11 | 12 | public static void assistActivity (Activity activity) { 13 | new AndroidBug5497Workaround(activity); 14 | } 15 | 16 | private final View mChildOfContent; 17 | private int usableHeightPrevious; 18 | private final FrameLayout.LayoutParams frameLayoutParams; 19 | 20 | private AndroidBug5497Workaround(Activity activity) { 21 | FrameLayout content =activity.findViewById(android.R.id.content); 22 | mChildOfContent = content.getChildAt(0); 23 | mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(this::possiblyResizeChildOfContent); 24 | frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams(); 25 | } 26 | 27 | private void possiblyResizeChildOfContent() { 28 | int usableHeightNow = computeUsableHeight(); 29 | if (usableHeightNow != usableHeightPrevious) { 30 | int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight(); 31 | int heightDifference = usableHeightSansKeyboard - usableHeightNow; 32 | if (heightDifference > (usableHeightSansKeyboard/4)) { 33 | 34 | frameLayoutParams.height = usableHeightSansKeyboard - heightDifference; 35 | } else { 36 | frameLayoutParams.height = usableHeightSansKeyboard; 37 | } 38 | mChildOfContent.requestLayout(); 39 | usableHeightPrevious = usableHeightNow; 40 | } 41 | } 42 | 43 | private int computeUsableHeight() { 44 | Rect r = new Rect(); 45 | mChildOfContent.getWindowVisibleDisplayFrame(r); 46 | return r.bottom; 47 | // return (r.bottom - r.top);// 全屏模式下: return r.bottom 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/utils/AppVersion.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.utils 2 | 3 | import android.content.pm.PackageInfo 4 | import android.content.pm.PackageManager 5 | import android.os.Build 6 | import com.shizq.bika.BIKAApplication 7 | 8 | class AppVersion { 9 | fun code(): Long { 10 | return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { 11 | getPackageInfo().longVersionCode 12 | } else { 13 | @Suppress("DEPRECATION") 14 | getPackageInfo().versionCode.toLong() 15 | } 16 | } 17 | 18 | fun name(): String? { 19 | return getPackageInfo().versionName 20 | } 21 | 22 | private fun getPackageInfo(): PackageInfo { 23 | val packageManager = BIKAApplication.contextBase.packageManager 24 | val packageName = BIKAApplication.contextBase.packageName 25 | return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 26 | packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0)) 27 | } else { 28 | @Suppress("DEPRECATION") 29 | packageManager.getPackageInfo(packageName, 0) 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/utils/Base64Util.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.utils 2 | 3 | import android.graphics.Bitmap 4 | import android.graphics.BitmapFactory 5 | import android.util.Base64 6 | import java.io.ByteArrayOutputStream 7 | 8 | class Base64Util { 9 | fun base64ToBitmap(base64Data: String): Bitmap { 10 | val bytes = Base64.decode(base64Data.split(",").toTypedArray()[1], Base64.DEFAULT) 11 | return BitmapFactory.decodeByteArray(bytes, 0, bytes.size) 12 | } 13 | 14 | fun getBase64(path: String): String { 15 | val baos = ByteArrayOutputStream() 16 | BitmapFactory.decodeFile(path).compress(Bitmap.CompressFormat.JPEG, 100, baos) 17 | baos.flush() 18 | baos.close() 19 | return "data:image/jpeg;base64," + Base64.encodeToString(baos.toByteArray(), Base64.NO_WRAP) 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/utils/Dimension.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.utils 2 | 3 | import android.content.res.Resources 4 | 5 | val Float.dp: Float 6 | get() = android.util.TypedValue.applyDimension( 7 | android.util.TypedValue.COMPLEX_UNIT_DIP, this, Resources.getSystem().displayMetrics) 8 | 9 | val Int.dp: Int 10 | get() = android.util.TypedValue.applyDimension( 11 | android.util.TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), Resources.getSystem().displayMetrics).toInt() 12 | 13 | val Float.sp: Float 14 | get() = android.util.TypedValue.applyDimension( 15 | android.util.TypedValue.COMPLEX_UNIT_SP, this, Resources.getSystem().displayMetrics) 16 | 17 | val Int.sp: Int 18 | get() = android.util.TypedValue.applyDimension( 19 | android.util.TypedValue.COMPLEX_UNIT_SP, this.toFloat(), Resources.getSystem().displayMetrics).toInt() -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/utils/GlideModuleOkHttp.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.utils 2 | 3 | import android.content.Context 4 | import com.bumptech.glide.Glide 5 | import com.bumptech.glide.Registry 6 | import com.bumptech.glide.annotation.GlideModule 7 | import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader 8 | import com.bumptech.glide.load.model.GlideUrl 9 | import com.bumptech.glide.module.AppGlideModule 10 | import com.shizq.bika.network.HttpDns 11 | import okhttp3.OkHttpClient 12 | import java.io.InputStream 13 | 14 | /** 15 | * 修改Glide的DNS 16 | */ 17 | 18 | @GlideModule 19 | class GlideModuleOkHttp : AppGlideModule() { 20 | override fun registerComponents(context: Context, glide: Glide, registry: Registry) { 21 | // 自定义OkHttpClient 22 | val okHttpClient = OkHttpClient.Builder() 23 | .dns(HttpDns()) 24 | .build() 25 | // 采用自定义的CustomOkHttpUrlLoader 26 | registry.replace( 27 | GlideUrl::class.java, 28 | InputStream::class.java, OkHttpUrlLoader.Factory(okHttpClient) 29 | ) 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/utils/GlideUrlNewKey.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.utils 2 | 3 | import com.bumptech.glide.load.model.GlideUrl 4 | 5 | //因为图片的ip地址经常改变,会占用手机存储空间和浪费手机流量,所以改变Glide缓存的key,来减少占用,Glide默认缓存的key是用图片的url,现在改成url后面的参数作为缓存key 6 | class GlideUrlNewKey(baseUrl: String, private val key: String) : GlideUrl( 7 | "${baseUrl.replace("/static/","")}/static/$key") { 8 | 9 | //再通过重写getCacheKey() 来改变本地缓存的key 10 | override fun getCacheKey(): String { 11 | //返回进行缓存的key 12 | return key 13 | } 14 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/utils/StatusBarUtil.java: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.res.Configuration; 5 | import android.os.Build; 6 | import android.view.View; 7 | import android.view.Window; 8 | import android.view.WindowManager; 9 | 10 | import androidx.core.view.WindowInsetsControllerCompat; 11 | 12 | public class StatusBarUtil { 13 | public static void hide(Activity activity) { 14 | if (activity == null) return; 15 | Window window = activity.getWindow(); 16 | if (window == null) return; 17 | window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 18 | WindowManager.LayoutParams.FLAG_FULLSCREEN); 19 | window.getDecorView() 20 | .setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 21 | WindowManager.LayoutParams lp = window.getAttributes(); 22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { 23 | lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; 24 | } 25 | window.setAttributes(lp); 26 | } 27 | 28 | public static void show(Activity activity) { 29 | if (activity == null) return; 30 | Window window = activity.getWindow(); 31 | if (window == null) return; 32 | window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 33 | window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE|View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 34 | WindowManager.LayoutParams lp = window.getAttributes(); 35 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { 36 | lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT ; 37 | } 38 | WindowInsetsControllerCompat wic = new WindowInsetsControllerCompat(window, window.getDecorView()); 39 | int currentNightMode = activity.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; 40 | wic.setAppearanceLightStatusBars(currentNightMode == Configuration.UI_MODE_NIGHT_NO);//状态栏高亮文字 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/widget/OutlineSpan.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.widget 2 | 3 | import android.graphics.Canvas 4 | import android.graphics.Paint 5 | import android.text.style.ReplacementSpan 6 | import androidx.annotation.ColorInt 7 | import androidx.annotation.Dimension 8 | 9 | /** 10 | * Source: https://github.com/santaevpavel 11 | * 12 | * A class that draws the outlines of a text when given a stroke color and stroke width. 13 | */ 14 | class OutlineSpan( 15 | @ColorInt private val strokeColor: Int, 16 | @Dimension private val strokeWidth: Float, 17 | ) : ReplacementSpan() { 18 | 19 | override fun getSize( 20 | paint: Paint, 21 | text: CharSequence, 22 | start: Int, 23 | end: Int, 24 | fm: Paint.FontMetricsInt?, 25 | ): Int { 26 | return paint.measureText(text.toString().substring(start until end)).toInt() 27 | } 28 | 29 | override fun draw( 30 | canvas: Canvas, 31 | text: CharSequence, 32 | start: Int, 33 | end: Int, 34 | x: Float, 35 | top: Int, 36 | y: Int, 37 | bottom: Int, 38 | paint: Paint, 39 | ) { 40 | val originTextColor = paint.color 41 | 42 | paint.apply { 43 | color = strokeColor 44 | style = Paint.Style.STROKE 45 | this.strokeWidth = this@OutlineSpan.strokeWidth 46 | } 47 | canvas.drawText(text, start, end, x, y.toFloat(), paint) 48 | 49 | paint.apply { 50 | color = originTextColor 51 | style = Paint.Style.FILL 52 | } 53 | 54 | canvas.drawText(text, start, end, x, y.toFloat(), paint) 55 | } 56 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/widget/PageIndicatorTextView.kt: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.widget 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.graphics.Color 6 | import android.text.Spannable 7 | import android.text.SpannableString 8 | import android.text.style.ScaleXSpan 9 | import android.util.AttributeSet 10 | import androidx.appcompat.widget.AppCompatTextView 11 | 12 | /** 13 | * https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorTextView.kt 14 | * Page indicator found at the bottom of the reader 15 | */ 16 | class PageIndicatorTextView( 17 | context: Context, 18 | attrs: AttributeSet? = null, 19 | ) : AppCompatTextView(context, attrs) { 20 | 21 | init { 22 | setTextColor(fillColor) 23 | } 24 | 25 | @SuppressLint("SetTextI18n") 26 | override fun setText(text: CharSequence?, type: BufferType?) { 27 | // Add spaces at the start & end of the text, otherwise the stroke is cut-off because it's 28 | // not taken into account when measuring the text (view's padding doesn't help). 29 | val currText = " $text " 30 | 31 | // Also add a bit of spacing between each character, as the stroke overlaps them 32 | val finalText = SpannableString(currText.asIterable().joinToString("\u00A0")).apply { 33 | // Apply text outline 34 | setSpan(spanOutline, 1, length - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 35 | 36 | for (i in 1..lastIndex step 2) { 37 | setSpan(ScaleXSpan(0.2f), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 38 | } 39 | } 40 | 41 | super.setText(finalText, BufferType.SPANNABLE) 42 | } 43 | } 44 | 45 | private val fillColor = Color.rgb(235, 235, 235) 46 | private val strokeColor = Color.rgb(45, 45, 45) 47 | 48 | // A span object with text outlining properties 49 | private val spanOutline = OutlineSpan( 50 | strokeColor = strokeColor, 51 | strokeWidth = 4f, 52 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/shizq/bika/widget/SpacesItemDecoration.java: -------------------------------------------------------------------------------- 1 | package com.shizq.bika.widget; 2 | 3 | import android.content.res.Resources; 4 | import android.graphics.Rect; 5 | import android.view.View; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.recyclerview.widget.RecyclerView; 9 | 10 | import java.util.List; 11 | 12 | //给RecyclerView设置左右边距 13 | public class SpacesItemDecoration extends RecyclerView.ItemDecoration { 14 | private final int space; 15 | private final List list; 16 | 17 | 18 | public SpacesItemDecoration(int space, List list) { 19 | this.space = space; 20 | this.list = list; 21 | } 22 | 23 | @Override 24 | public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, RecyclerView parent, @NonNull RecyclerView.State state) { 25 | if (parent.getChildLayoutPosition(view) == 0) outRect.left = space;//设置第一个item左边距 26 | if (parent.getChildAdapterPosition(view) == list.size() - 1) outRect.right = space;//设置最后一个item右边距 27 | } 28 | 29 | //将像素转换成dp 30 | public static int px2dp(float dpValue) { 31 | return (int) (0.5f + dpValue * Resources.getSystem().getDisplayMetrics().density); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_enter_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_exit_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bika.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/bika.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/cat_forum.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/cat_forum.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/cat_game.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/cat_game.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/cat_latest.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/cat_latest.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/cat_leaderboard.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/cat_leaderboard.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/cat_love_pica.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/cat_love_pica.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/cat_random.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/cat_random.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_applications.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_down.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_drop_down.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_forward.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_up.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_back.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bookmark_add.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 14 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bookmark_check.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bookmarks.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_chat.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/ic_chat.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_chat_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_close.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete_sweep.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_edit.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_error.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_exit.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_favorite_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_favorite_border_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_github.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_group_work.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_history.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_hotel_class.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_key.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard_voice.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_list.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_mail.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_night.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_photo_camera.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_punch.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_security.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sort.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_voice_1.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_voice_2.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_widgets.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/p.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/p.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/placeholder_avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/placeholder_avatar.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/placeholder_avatar_2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/placeholder_avatar_2.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/placeholder_transparent.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/placeholder_transparent.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/placeholder_transparent_low.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/placeholder_transparent_low.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_chat_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_chat_notification_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_chat_reply_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_chat_send_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_title_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/verified_icon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizq123/BIKA/e2931812ebcc07f17871396a1ddd86aabb9f77e8/app/src/main/res/drawable/verified_icon.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/voice.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_account.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | 14 | 15 | 20 | 21 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_apps.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 16 | 17 | 23 | 24 | 30 | 31 | 36 | 37 | 38 | 39 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_games.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | 14 | 15 | 20 | 21 | 28 | 29 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_history.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 16 | 17 | 22 | 23 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 16 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_my_comments.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 17 | 18 | 23 | 24 | 30 | 31 | 37 | 38 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_notifications.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 17 | 18 | 23 | 24 | 30 | 31 | 37 | 38 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 10 | 11 | 15 | 16 | 21 | 22 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 14 | 15 | 20 | 27 | 28 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_input_text_msg.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | 31 | 32 |