├── art ├── logo │ ├── play-logo.png │ ├── github-logo.png │ ├── proxer-logo.png │ └── proxer-logo-title.png └── screenshot │ ├── news.png │ ├── profile.png │ ├── ucp-list.png │ ├── anime-list.png │ ├── anime-play.png │ ├── manga-reader.png │ ├── media-detail.png │ ├── public-chat.png │ ├── ucp-topten.png │ ├── anime-streams.png │ └── conference-list.png ├── src ├── main │ ├── ic_launcher-web.png │ ├── res │ │ ├── drawable-nodpi │ │ │ ├── o_gj.gif │ │ │ ├── o_hi.gif │ │ │ ├── o_lw.gif │ │ │ ├── o_xd.gif │ │ │ ├── kanna.webp │ │ │ ├── o_aua.gif │ │ │ ├── o_brav.gif │ │ │ ├── o_bye.gif │ │ │ ├── o_cool.gif │ │ │ ├── o_dx1.gif │ │ │ ├── o_dx2.gif │ │ │ ├── o_emo.gif │ │ │ ├── o_ero1.gif │ │ │ ├── o_ero2.gif │ │ │ ├── o_fuu.gif │ │ │ ├── o_haha.gif │ │ │ ├── o_hero.gif │ │ │ ├── o_heul.gif │ │ │ ├── o_kiss.gif │ │ │ ├── o_like.gif │ │ │ ├── o_oehm.gif │ │ │ ├── o_omg.gif │ │ │ ├── o_puh.gif │ │ │ ├── o_pwn.gif │ │ │ ├── o_roll.gif │ │ │ ├── o_run.gif │ │ │ ├── o_wet.gif │ │ │ ├── o_what.gif │ │ │ ├── o_yay.gif │ │ │ ├── o_angst.gif │ │ │ ├── o_blush.gif │ │ │ ├── o_buede.gif │ │ │ ├── o_cryrun.gif │ │ │ ├── o_gomen.gif │ │ │ ├── o_kihihi.gif │ │ │ ├── o_love1.gif │ │ │ ├── o_love2.gif │ │ │ ├── o_noooo1.gif │ │ │ ├── o_noooo2.gif │ │ │ ├── o_pfeif.gif │ │ │ ├── o_sayajin.gif │ │ │ ├── o_schrei.gif │ │ │ ├── o_stop1.gif │ │ │ ├── o_stop2.gif │ │ │ ├── o_stress.gif │ │ │ ├── o_verwirr.gif │ │ │ ├── o_wahaha.gif │ │ │ ├── o_schleich.gif │ │ │ ├── o_schluerf.gif │ │ │ ├── o_toohappy.gif │ │ │ ├── widget_news_preview.webp │ │ │ ├── widget_schedule_preview.webp │ │ │ ├── widget_news_dark_preview.webp │ │ │ └── widget_schedule_dark_preview.webp │ │ ├── drawable-hdpi │ │ │ ├── ic_fsk_0.webp │ │ │ ├── ic_fsk_12.webp │ │ │ ├── ic_fsk_16.webp │ │ │ ├── ic_fsk_18.webp │ │ │ ├── ic_fsk_6.webp │ │ │ ├── ic_fsk_fear.webp │ │ │ ├── ic_fsk_sex.webp │ │ │ ├── ic_stat_check.webp │ │ │ ├── ic_stat_proxer.webp │ │ │ ├── ic_fsk_violence.webp │ │ │ ├── ic_shortcut_chat.webp │ │ │ ├── ic_shortcut_news.webp │ │ │ ├── ic_fsk_bad_language.webp │ │ │ ├── ic_shortcut_bookmarks.webp │ │ │ ├── ic_shortcut_messenger_group.webp │ │ │ └── ic_shortcut_messenger_person.webp │ │ ├── drawable-mdpi │ │ │ ├── ic_fsk_0.webp │ │ │ ├── ic_fsk_12.webp │ │ │ ├── ic_fsk_16.webp │ │ │ ├── ic_fsk_18.webp │ │ │ ├── ic_fsk_6.webp │ │ │ ├── ic_fsk_fear.webp │ │ │ ├── ic_fsk_sex.webp │ │ │ ├── ic_stat_check.webp │ │ │ ├── ic_stat_proxer.webp │ │ │ ├── ic_fsk_violence.webp │ │ │ ├── ic_shortcut_chat.webp │ │ │ ├── ic_shortcut_news.webp │ │ │ ├── ic_fsk_bad_language.webp │ │ │ ├── ic_shortcut_bookmarks.webp │ │ │ ├── ic_shortcut_messenger_group.webp │ │ │ └── ic_shortcut_messenger_person.webp │ │ ├── drawable-xhdpi │ │ │ ├── ic_fsk_0.webp │ │ │ ├── ic_fsk_6.webp │ │ │ ├── ic_fsk_12.webp │ │ │ ├── ic_fsk_16.webp │ │ │ ├── ic_fsk_18.webp │ │ │ ├── ic_fsk_sex.webp │ │ │ ├── ic_fsk_fear.webp │ │ │ ├── ic_stat_check.webp │ │ │ ├── ic_fsk_violence.webp │ │ │ ├── ic_stat_proxer.webp │ │ │ ├── ic_shortcut_chat.webp │ │ │ ├── ic_shortcut_news.webp │ │ │ ├── ic_fsk_bad_language.webp │ │ │ ├── ic_shortcut_bookmarks.webp │ │ │ ├── ic_shortcut_messenger_group.webp │ │ │ └── ic_shortcut_messenger_person.webp │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_foreground.webp │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_foreground.webp │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_foreground.webp │ │ ├── drawable-xxhdpi │ │ │ ├── ic_fsk_0.webp │ │ │ ├── ic_fsk_12.webp │ │ │ ├── ic_fsk_16.webp │ │ │ ├── ic_fsk_18.webp │ │ │ ├── ic_fsk_6.webp │ │ │ ├── ic_fsk_fear.webp │ │ │ ├── ic_fsk_sex.webp │ │ │ ├── ic_stat_check.webp │ │ │ ├── ic_stat_proxer.webp │ │ │ ├── ic_fsk_violence.webp │ │ │ ├── ic_shortcut_chat.webp │ │ │ ├── ic_shortcut_news.webp │ │ │ ├── ic_fsk_bad_language.webp │ │ │ ├── ic_shortcut_bookmarks.webp │ │ │ ├── ic_shortcut_messenger_group.webp │ │ │ └── ic_shortcut_messenger_person.webp │ │ ├── drawable-xxxhdpi │ │ │ ├── ic_fsk_0.webp │ │ │ ├── ic_fsk_6.webp │ │ │ ├── ic_fsk_12.webp │ │ │ ├── ic_fsk_16.webp │ │ │ ├── ic_fsk_18.webp │ │ │ ├── ic_fsk_fear.webp │ │ │ ├── ic_fsk_sex.webp │ │ │ ├── ic_fsk_violence.webp │ │ │ ├── ic_shortcut_chat.webp │ │ │ ├── ic_shortcut_news.webp │ │ │ ├── ic_stat_proxer.webp │ │ │ ├── ic_fsk_bad_language.webp │ │ │ ├── ic_shortcut_bookmarks.webp │ │ │ ├── ic_shortcut_messenger_group.webp │ │ │ └── ic_shortcut_messenger_person.webp │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_foreground.webp │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_foreground.webp │ │ ├── values-land │ │ │ └── dimens.xml │ │ ├── values │ │ │ ├── ids.xml │ │ │ ├── bools.xml │ │ │ ├── play_pause_state.xml │ │ │ ├── colors_bg.xml │ │ │ ├── colors_gloomy.xml │ │ │ ├── colors_gloomy_night.xml │ │ │ ├── dimens.xml │ │ │ ├── colors_night.xml │ │ │ ├── themes.xml │ │ │ ├── themes_bg.xml │ │ │ └── themes_gloomy.xml │ │ ├── values-sw720dp │ │ │ └── dimens.xml │ │ ├── raw │ │ │ └── keep.xml │ │ ├── layout │ │ │ ├── fragment_chat_container.xml │ │ │ ├── item_checkbox.xml │ │ │ ├── item_radio_button.xml │ │ │ ├── layout_image.xml │ │ │ ├── layout_media_control.xml │ │ │ ├── item_chip.xml │ │ │ ├── item_theme.xml │ │ │ ├── item_manga_page_gif.xml │ │ │ ├── item_manga_page.xml │ │ │ ├── activity_image_detail.xml │ │ │ ├── fragment_manga.xml │ │ │ ├── layout_about_row.xml │ │ │ ├── item_stream_message.xml │ │ │ ├── layout_media_info_row.xml │ │ │ ├── dialog_logout.xml │ │ │ ├── dialog_no_wifi.xml │ │ │ ├── item_schedule_day.xml │ │ │ ├── fragment_relation.xml │ │ │ ├── fragment_schedule.xml │ │ │ ├── fragment_discussion.xml │ │ │ ├── fragment_conferences.xml │ │ │ ├── fragment_recommendation.xml │ │ │ └── activity_web_view.xml │ │ ├── mipmap-anydpi-v26 │ │ │ └── ic_launcher.xml │ │ ├── values-sw600dp-land │ │ │ └── dimens.xml │ │ ├── drawable │ │ │ ├── ic_circle_red.xml │ │ │ ├── ic_circle_green.xml │ │ │ ├── text_protection_scrim_top.xml │ │ │ ├── text_protection_scrim_bottom.xml │ │ │ ├── cursor.xml │ │ │ ├── player_control_background.xml │ │ │ ├── ic_japan.xml │ │ │ ├── ic_germany.xml │ │ │ └── play_pause_selector.xml │ │ ├── xml │ │ │ ├── network_security_config.xml │ │ │ ├── widget_provider_news.xml │ │ │ ├── widget_provider_schedule.xml │ │ │ ├── widget_provider_news_dark.xml │ │ │ ├── widget_provider_schedule_dark.xml │ │ │ └── backup_config.xml │ │ ├── menu │ │ │ ├── activity_share.xml │ │ │ ├── fragment_messenger.xml │ │ │ ├── fragment_notifications.xml │ │ │ ├── fragment_topic.xml │ │ │ ├── fragment_manga.xml │ │ │ ├── fragment_share_receiver.xml │ │ │ ├── activity_stream.xml │ │ │ ├── fragment_edit_comment.xml │ │ │ ├── fragment_messenger_cab.xml │ │ │ ├── activity_profile.xml │ │ │ ├── fragment_comments.xml │ │ │ ├── fragment_edit_comment_size.xml │ │ │ ├── fragment_chat_cab.xml │ │ │ ├── fragment_conferences.xml │ │ │ └── fragment_user_comments.xml │ │ ├── values-night │ │ │ ├── themes.xml │ │ │ ├── themes_gloomy.xml │ │ │ └── styles.xml │ │ └── values-sw600dp │ │ │ └── dimens.xml │ └── kotlin │ │ └── me │ │ ├── proxer │ │ └── app │ │ │ ├── base │ │ │ ├── CaptchaSolvedEvent.kt │ │ │ ├── NetworkConnectedEvent.kt │ │ │ ├── BackPressAware.kt │ │ │ ├── CustomTabsAware.kt │ │ │ ├── BaseContentViewModel.kt │ │ │ └── PagedContentViewModel.kt │ │ │ ├── news │ │ │ ├── NewsNotificationEvent.kt │ │ │ ├── widget │ │ │ │ ├── NewsWidgetProvider.kt │ │ │ │ ├── NewsWidgetDarkProvider.kt │ │ │ │ ├── NewsWidgetService.kt │ │ │ │ └── NewsWidgetDarkService.kt │ │ │ └── NewsViewModel.kt │ │ │ ├── comment │ │ │ ├── CommentTooLongException.kt │ │ │ └── CommentInvalidProgressException.kt │ │ │ ├── exception │ │ │ ├── NotLoggedInException.kt │ │ │ ├── TopicEmptyException.kt │ │ │ ├── ChatException.kt │ │ │ ├── AgeConfirmationRequiredException.kt │ │ │ ├── InvalidInputException.kt │ │ │ ├── ChatMessageException.kt │ │ │ ├── AppRequiredException.kt │ │ │ ├── NotConnectedException.kt │ │ │ ├── StreamResolutionException.kt │ │ │ ├── PartialException.kt │ │ │ ├── ChatSynchronizationException.kt │ │ │ ├── StorageException.kt │ │ │ └── ChatSendMessageException.kt │ │ │ ├── notification │ │ │ ├── AccountNotificationEvent.kt │ │ │ ├── NotificationActivity.kt │ │ │ └── NotificationDeletionConfirmationDialog.kt │ │ │ ├── manga │ │ │ ├── MangaNotAvailableException.kt │ │ │ ├── MangaReaderOrientation.kt │ │ │ ├── MangaLinkException.kt │ │ │ ├── MangaChapterInfo.kt │ │ │ └── MangaLinearLayoutManger.kt │ │ │ ├── chat │ │ │ ├── prv │ │ │ │ ├── message │ │ │ │ │ ├── MessengerFragmentPingEvent.kt │ │ │ │ │ ├── MessengerReportDialog.kt │ │ │ │ │ └── MessengerReportViewModel.kt │ │ │ │ ├── conference │ │ │ │ │ ├── ConferenceFragmentPingEvent.kt │ │ │ │ │ └── info │ │ │ │ │ │ └── ConferenceInfoViewModel.kt │ │ │ │ ├── sync │ │ │ │ │ ├── MessengerErrorEvent.kt │ │ │ │ │ └── MessengerDatabase.kt │ │ │ │ ├── ConferenceWithMessage.kt │ │ │ │ └── Participant.kt │ │ │ └── pub │ │ │ │ ├── message │ │ │ │ ├── ChatReportViewModel.kt │ │ │ │ ├── ChatReportDialog.kt │ │ │ │ └── ParsedChatMessage.kt │ │ │ │ └── room │ │ │ │ └── ChatRoomViewModel.kt │ │ │ ├── settings │ │ │ ├── status │ │ │ │ ├── ServerType.kt │ │ │ │ ├── ServerStatus.kt │ │ │ │ └── ServerStatusActivity.kt │ │ │ ├── ProxerLibsActivity.kt │ │ │ ├── theme │ │ │ │ ├── ThemeContainer.kt │ │ │ │ └── ThemeVariant.kt │ │ │ └── AgeConfirmationDialog.kt │ │ │ ├── ui │ │ │ └── view │ │ │ │ ├── bbcode │ │ │ │ └── prototype │ │ │ │ │ ├── AutoClosingPrototype.kt │ │ │ │ │ ├── ContentPrototype.kt │ │ │ │ │ ├── ConditionalTextMutatorPrototype.kt │ │ │ │ │ ├── BreakPrototype.kt │ │ │ │ │ ├── SubscriptPrototype.kt │ │ │ │ │ ├── UnderlinePrototype.kt │ │ │ │ │ ├── SuperscriptPrototype.kt │ │ │ │ │ ├── BoldPrototype.kt │ │ │ │ │ ├── StrikethroughPrototype.kt │ │ │ │ │ ├── ItalicPrototype.kt │ │ │ │ │ ├── TextMutatorPrototype.kt │ │ │ │ │ ├── DividerPrototype.kt │ │ │ │ │ ├── TwitterPrototype.kt │ │ │ │ │ ├── FacebookPrototype.kt │ │ │ │ │ └── PollPrototype.kt │ │ │ │ ├── InfoImageButton.kt │ │ │ │ └── BetterLinkTextView.kt │ │ │ ├── anime │ │ │ ├── AnimeStreamInfo.kt │ │ │ ├── AppRequiredErrorAction.kt │ │ │ ├── schedule │ │ │ │ ├── widget │ │ │ │ │ ├── ScheduleWidgetProvider.kt │ │ │ │ │ ├── ScheduleWidgetDarkProvider.kt │ │ │ │ │ ├── ScheduleWidgetService.kt │ │ │ │ │ └── ScheduleWidgetDarkService.kt │ │ │ │ └── ScheduleViewModel.kt │ │ │ ├── resolver │ │ │ │ ├── MessageStreamResolver.kt │ │ │ │ ├── SteamStreamResolver.kt │ │ │ │ ├── YouTubeStreamResolver.kt │ │ │ │ ├── AnimeOnDemandStreamResolver.kt │ │ │ │ ├── ProsiebenMAXXStreamResolver.kt │ │ │ │ ├── AmazonPrimeVideoStreamResolver.kt │ │ │ │ ├── StreamResolverFactory.kt │ │ │ │ ├── StreamResolver.kt │ │ │ │ └── NetflixStreamResolver.kt │ │ │ └── AnimeStream.kt │ │ │ ├── util │ │ │ ├── WorkerUtils.kt │ │ │ ├── extension │ │ │ │ ├── Aliases.kt │ │ │ │ ├── ProxerRxExtensions.kt │ │ │ │ └── SnackbarExtensions.kt │ │ │ ├── logging │ │ │ │ └── HttpTimberLogger.kt │ │ │ ├── data │ │ │ │ ├── HawkMoshiParser.kt │ │ │ │ ├── InstantJsonAdapter.kt │ │ │ │ └── ResettingMutableLiveData.kt │ │ │ ├── http │ │ │ │ ├── ConnectionCloseInterceptor.kt │ │ │ │ ├── UserAgentInterceptor.kt │ │ │ │ └── ConnectivityInterceptor.kt │ │ │ ├── Validators.kt │ │ │ ├── compat │ │ │ │ ├── MenuPopupCompat.kt │ │ │ │ └── ConnectivityCompat.kt │ │ │ ├── DefaultActivityLifecycleCallbacks.kt │ │ │ ├── rx │ │ │ │ └── RxRetryWithDelay.kt │ │ │ ├── wrapper │ │ │ │ ├── SimpleGlideRequestListener.kt │ │ │ │ └── OriginalSizeGlideTarget.kt │ │ │ └── ActivityUtils.kt │ │ │ ├── forum │ │ │ ├── TopicMetaData.kt │ │ │ └── ParsedPost.kt │ │ │ ├── info │ │ │ ├── industry │ │ │ │ ├── IndustryInfoViewModel.kt │ │ │ │ └── IndustryProjectViewModel.kt │ │ │ └── translatorgroup │ │ │ │ ├── TranslatorGroupInfoViewModel.kt │ │ │ │ └── TranslatorGroupProjectViewModel.kt │ │ │ ├── media │ │ │ ├── discussion │ │ │ │ └── DiscussionViewModel.kt │ │ │ ├── recommendation │ │ │ │ └── RecommendationViewModel.kt │ │ │ ├── TagDao.kt │ │ │ ├── relation │ │ │ │ └── RelationViewModel.kt │ │ │ ├── TagDatabase.kt │ │ │ ├── comments │ │ │ │ └── ParsedComment.kt │ │ │ └── episode │ │ │ │ └── EpisodeRow.kt │ │ │ ├── profile │ │ │ ├── about │ │ │ │ └── ProfileAboutViewModel.kt │ │ │ └── comment │ │ │ │ └── ParsedUserComment.kt │ │ │ └── auth │ │ │ ├── LocalUser.kt │ │ │ └── ProxerLoginTokenManager.kt │ │ └── zhanghai │ │ └── android │ │ └── materialprogressbar │ │ ├── ThinSingleCircularProgressDrawable.kt │ │ └── ThinCircularProgressDrawable.kt ├── release │ ├── res │ │ ├── drawable-nodpi │ │ │ └── explosion.webp │ │ └── values │ │ │ └── strings.xml │ ├── kotlin │ │ └── me │ │ │ └── proxer │ │ │ └── app │ │ │ └── FlavorInitializer.kt │ └── AndroidManifest.xml ├── debug │ ├── kotlin │ │ └── me │ │ │ └── proxer │ │ │ └── app │ │ │ └── FlavorInitializer.kt │ └── AndroidManifest.xml └── logRelease │ └── AndroidManifest.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitattributes ├── config └── detekt │ └── detekt.yml ├── .github ├── workflows │ ├── create-secrets.sh │ ├── publish-to-discord.sh │ └── ci.yml ├── FEATURE_REQUEST.md ├── PULL_REQUEST_TEMPLATE.md ├── BUG_REPORT.md └── CONTRIBUTING.md ├── .editorconfig ├── gradle.properties ├── settings.gradle └── .gitignore /art/logo/play-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/logo/play-logo.png -------------------------------------------------------------------------------- /art/screenshot/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/news.png -------------------------------------------------------------------------------- /art/logo/github-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/logo/github-logo.png -------------------------------------------------------------------------------- /art/logo/proxer-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/logo/proxer-logo.png -------------------------------------------------------------------------------- /art/screenshot/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/profile.png -------------------------------------------------------------------------------- /art/screenshot/ucp-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/ucp-list.png -------------------------------------------------------------------------------- /src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /art/logo/proxer-logo-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/logo/proxer-logo-title.png -------------------------------------------------------------------------------- /art/screenshot/anime-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/anime-list.png -------------------------------------------------------------------------------- /art/screenshot/anime-play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/anime-play.png -------------------------------------------------------------------------------- /art/screenshot/manga-reader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/manga-reader.png -------------------------------------------------------------------------------- /art/screenshot/media-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/media-detail.png -------------------------------------------------------------------------------- /art/screenshot/public-chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/public-chat.png -------------------------------------------------------------------------------- /art/screenshot/ucp-topten.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/ucp-topten.png -------------------------------------------------------------------------------- /art/screenshot/anime-streams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/anime-streams.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /art/screenshot/conference-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/art/screenshot/conference-list.png -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_gj.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_gj.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_hi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_hi.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_lw.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_lw.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_xd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_xd.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/kanna.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/kanna.webp -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_aua.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_aua.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_brav.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_brav.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_bye.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_bye.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_cool.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_cool.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_dx1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_dx1.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_dx2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_dx2.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_emo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_emo.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_ero1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_ero1.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_ero2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_ero2.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_fuu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_fuu.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_haha.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_haha.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_hero.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_hero.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_heul.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_heul.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_kiss.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_kiss.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_like.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_like.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_oehm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_oehm.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_omg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_omg.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_puh.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_puh.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_pwn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_pwn.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_roll.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_roll.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_run.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_run.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_wet.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_wet.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_what.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_what.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_yay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_yay.gif -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_fsk_0.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_fsk_0.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_fsk_12.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_fsk_12.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_fsk_16.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_fsk_16.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_fsk_18.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_fsk_18.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_fsk_6.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_fsk_6.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_fsk_0.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_fsk_0.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_fsk_12.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_fsk_12.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_fsk_16.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_fsk_16.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_fsk_18.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_fsk_18.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_fsk_6.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_fsk_6.webp -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_angst.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_angst.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_blush.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_blush.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_buede.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_buede.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_cryrun.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_cryrun.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_gomen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_gomen.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_kihihi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_kihihi.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_love1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_love1.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_love2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_love2.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_noooo1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_noooo1.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_noooo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_noooo2.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_pfeif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_pfeif.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_sayajin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_sayajin.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_schrei.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_schrei.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_stop1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_stop1.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_stop2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_stop2.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_stress.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_stress.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_verwirr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_verwirr.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_wahaha.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_wahaha.gif -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_fsk_0.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_fsk_0.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_fsk_6.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_fsk_6.webp -------------------------------------------------------------------------------- /src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_fsk_fear.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_fsk_fear.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_fsk_sex.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_fsk_sex.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_fsk_fear.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_fsk_fear.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_fsk_sex.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_fsk_sex.webp -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_schleich.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_schleich.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_schluerf.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_schluerf.gif -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/o_toohappy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/o_toohappy.gif -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_fsk_12.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_fsk_12.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_fsk_16.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_fsk_16.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_fsk_18.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_fsk_18.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_fsk_sex.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_fsk_sex.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_fsk_0.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_fsk_0.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_fsk_12.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_fsk_12.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_fsk_16.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_fsk_16.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_fsk_18.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_fsk_18.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_fsk_6.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_fsk_6.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_fsk_0.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_fsk_0.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_fsk_6.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_fsk_6.webp -------------------------------------------------------------------------------- /src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_stat_check.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_stat_check.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_stat_proxer.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_stat_proxer.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_stat_check.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_stat_check.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_stat_proxer.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_stat_proxer.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_fsk_fear.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_fsk_fear.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_stat_check.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_stat_check.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_fsk_fear.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_fsk_fear.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_fsk_sex.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_fsk_sex.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_fsk_12.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_fsk_12.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_fsk_16.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_fsk_16.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_fsk_18.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_fsk_18.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_fsk_fear.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_fsk_fear.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_fsk_sex.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_fsk_sex.webp -------------------------------------------------------------------------------- /src/release/res/drawable-nodpi/explosion.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/release/res/drawable-nodpi/explosion.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_fsk_violence.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_fsk_violence.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_shortcut_chat.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_shortcut_chat.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_shortcut_news.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_shortcut_news.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_fsk_violence.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_fsk_violence.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_shortcut_chat.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_shortcut_chat.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_shortcut_news.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_shortcut_news.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_fsk_violence.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_fsk_violence.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_stat_proxer.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_stat_proxer.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_stat_check.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_stat_check.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_stat_proxer.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_stat_proxer.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_fsk_bad_language.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_fsk_bad_language.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_fsk_bad_language.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_fsk_bad_language.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_shortcut_chat.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_shortcut_chat.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_shortcut_news.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_shortcut_news.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_fsk_violence.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_fsk_violence.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_shortcut_chat.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_shortcut_chat.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_shortcut_news.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_shortcut_news.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_fsk_violence.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_fsk_violence.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_shortcut_chat.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_shortcut_chat.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_shortcut_news.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_shortcut_news.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_stat_proxer.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_stat_proxer.webp -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/base/CaptchaSolvedEvent.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.base 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class CaptchaSolvedEvent 7 | -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_shortcut_bookmarks.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_shortcut_bookmarks.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_shortcut_bookmarks.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_shortcut_bookmarks.webp -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/widget_news_preview.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/widget_news_preview.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_fsk_bad_language.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_fsk_bad_language.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_fsk_bad_language.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_fsk_bad_language.webp -------------------------------------------------------------------------------- /src/main/res/mipmap-hdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/main/res/mipmap-mdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/widget_schedule_preview.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/widget_schedule_preview.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_shortcut_bookmarks.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_shortcut_bookmarks.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_shortcut_bookmarks.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_shortcut_bookmarks.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_fsk_bad_language.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_fsk_bad_language.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_shortcut_bookmarks.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_shortcut_bookmarks.webp -------------------------------------------------------------------------------- /src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/base/NetworkConnectedEvent.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.base 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class NetworkConnectedEvent 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/news/NewsNotificationEvent.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.news 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class NewsNotificationEvent 7 | -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/widget_news_dark_preview.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/widget_news_dark_preview.webp -------------------------------------------------------------------------------- /src/main/res/values-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 128dp 4 | 5 | -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_shortcut_messenger_group.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_shortcut_messenger_group.webp -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_shortcut_messenger_person.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-hdpi/ic_shortcut_messenger_person.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_shortcut_messenger_group.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_shortcut_messenger_group.webp -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_shortcut_messenger_person.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-mdpi/ic_shortcut_messenger_person.webp -------------------------------------------------------------------------------- /src/main/res/drawable-nodpi/widget_schedule_dark_preview.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-nodpi/widget_schedule_dark_preview.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_shortcut_messenger_group.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_shortcut_messenger_group.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_shortcut_messenger_person.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xhdpi/ic_shortcut_messenger_person.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_shortcut_messenger_group.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_shortcut_messenger_group.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_shortcut_messenger_person.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxhdpi/ic_shortcut_messenger_person.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_shortcut_messenger_group.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_shortcut_messenger_group.webp -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/ic_shortcut_messenger_person.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proxer/ProxerAndroid/HEAD/src/main/res/drawable-xxxhdpi/ic_shortcut_messenger_person.webp -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # These are explicitly windows files and should use crlf 5 | *.bat text eol=crlf 6 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/comment/CommentTooLongException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.comment 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class CommentTooLongException : Exception() 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/NotLoggedInException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class NotLoggedInException : Exception() 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/TopicEmptyException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class TopicEmptyException : Exception() 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/notification/AccountNotificationEvent.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.notification 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class AccountNotificationEvent 7 | -------------------------------------------------------------------------------- /src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/manga/MangaNotAvailableException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.manga 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class MangaNotAvailableException : Exception() 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/prv/message/MessengerFragmentPingEvent.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.prv.message 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class MessengerFragmentPingEvent 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/prv/conference/ConferenceFragmentPingEvent.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.prv.conference 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class ConferenceFragmentPingEvent 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/comment/CommentInvalidProgressException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.comment 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class CommentInvalidProgressException : Exception() 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/ChatException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | open class ChatException(val innerError: Throwable) : Exception() 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/settings/status/ServerType.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.settings.status 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | enum class ServerType { 7 | MAIN, MANGA, STREAM 8 | } 9 | -------------------------------------------------------------------------------- /src/main/res/values-sw720dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | true 6 | 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/AgeConfirmationRequiredException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class AgeConfirmationRequiredException : Exception() 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/InvalidInputException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class InvalidInputException(message: String) : Exception(message) 7 | -------------------------------------------------------------------------------- /src/main/res/raw/keep.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/base/BackPressAware.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.base 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | interface BackPressAware { 7 | 8 | fun onBackPressed(): Boolean 9 | } 10 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/ChatMessageException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class ChatMessageException(innerError: Throwable) : ChatException(innerError) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/AutoClosingPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | interface AutoClosingPrototype : BBPrototype 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/AppRequiredException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class AppRequiredException(val name: String, val appPackage: String) : Exception() 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/NotConnectedException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | import java.io.IOException 4 | 5 | /** 6 | * @author Ruben Gees 7 | */ 8 | class NotConnectedException : IOException() 9 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/StreamResolutionException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class StreamResolutionException(message: String? = null) : Exception(message) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/manga/MangaReaderOrientation.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.manga 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | enum class MangaReaderOrientation { 7 | LEFT_TO_RIGHT, RIGHT_TO_LEFT, VERTICAL 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/AnimeStreamInfo.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | data class AnimeStreamInfo(val name: String, val episodeAmount: Int, val streams: List) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/PartialException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class PartialException(val innerError: Throwable, val partialData: Any?) : Exception(innerError) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/ChatSynchronizationException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class ChatSynchronizationException(innerError: Throwable) : ChatException(innerError) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/StorageException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class StorageException(message: String? = null, cause: Throwable? = null) : Exception(message, cause) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/exception/ChatSendMessageException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.exception 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | class ChatSendMessageException(innerError: Throwable, val id: Long) : ChatException(innerError) 7 | -------------------------------------------------------------------------------- /src/main/res/values/bools.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | 5 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/manga/MangaLinkException.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.manga 2 | 3 | import okhttp3.HttpUrl 4 | 5 | /** 6 | * @author Ruben Gees 7 | */ 8 | class MangaLinkException(val chapterTitle: String, val link: HttpUrl) : Exception() 9 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/settings/status/ServerStatus.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.settings.status 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | data class ServerStatus(val name: String, val number: Int, val type: ServerType, val online: Boolean) 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/prv/sync/MessengerErrorEvent.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.prv.sync 2 | 3 | import me.proxer.app.exception.ChatException 4 | 5 | /** 6 | * @author Ruben Gees 7 | */ 8 | data class MessengerErrorEvent(val error: ChatException) 9 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/ContentPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import me.proxer.app.ui.view.bbcode.BBArgs 4 | 5 | interface ContentPrototype { 6 | 7 | fun isBlank(args: BBArgs): Boolean 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/WorkerUtils.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util 2 | 3 | object WorkerUtils { 4 | 5 | fun shouldRetryForError(error: Throwable) = when { 6 | ErrorUtils.isIpBlockedError(error) -> false 7 | else -> true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/manga/MangaChapterInfo.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.manga 2 | 3 | import me.proxer.library.entity.manga.Chapter 4 | 5 | /** 6 | * @author Ruben Gees 7 | */ 8 | data class MangaChapterInfo(val chapter: Chapter, val name: String, val episodeAmount: Int) 9 | -------------------------------------------------------------------------------- /src/main/res/values/play_pause_state.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /config/detekt/detekt.yml: -------------------------------------------------------------------------------- 1 | complexity: 2 | active: false 3 | 4 | exceptions: 5 | TooGenericExceptionCaught: 6 | active: false 7 | 8 | performance: 9 | SpreadOperator: 10 | active: false 11 | 12 | style: 13 | MagicNumber: 14 | active: false 15 | ForbiddenComment: 16 | active: false 17 | -------------------------------------------------------------------------------- /src/main/res/layout/fragment_chat_container.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/res/layout/item_checkbox.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /src/main/res/layout/item_radio_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /src/debug/kotlin/me/proxer/app/FlavorInitializer.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | @Suppress("unused") 7 | object FlavorInitializer { 8 | 9 | fun initialize(@Suppress("UNUSED_PARAMETER") application: MainApplication) { 10 | // Do nothing in debug flavor. 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/res/values-sw600dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 384dp 5 | 138dp 6 | 96dp 7 | 8 | -------------------------------------------------------------------------------- /src/main/res/drawable/ic_circle_red.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/res/drawable/ic_circle_green.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/base/CustomTabsAware.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.base 2 | 3 | import okhttp3.HttpUrl 4 | 5 | /** 6 | * @author Ruben Gees 7 | */ 8 | interface CustomTabsAware { 9 | 10 | fun setLikelyUrl(url: HttpUrl): Boolean 11 | 12 | fun showPage(url: HttpUrl, forceBrowser: Boolean = false, skipCheck: Boolean = false) 13 | } 14 | -------------------------------------------------------------------------------- /.github/workflows/create-secrets.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | if [[ ${KEYSTORE:+1} ]] && [[ ${SECRETS:+1} ]]; then 5 | echo "${KEYSTORE}" | base64 -d >keystore.jks 6 | echo "${SECRETS}" | base64 -d >secrets.properties 7 | echo "Created secrets." 8 | else 9 | echo "Environment variables not set, skipping." 10 | fi 11 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/extension/Aliases.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util.extension 2 | 3 | import me.proxer.app.chat.prv.LocalConference 4 | import me.proxer.app.chat.prv.LocalMessage 5 | 6 | typealias LocalConferenceMap = Map> 7 | 8 | typealias ProxerNotification = me.proxer.library.entity.notifications.Notification 9 | -------------------------------------------------------------------------------- /src/main/res/layout/layout_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /src/main/res/drawable/text_protection_scrim_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/res/drawable/text_protection_scrim_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/res/layout/layout_media_control.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/logging/HttpTimberLogger.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util.logging 2 | 3 | import okhttp3.logging.HttpLoggingInterceptor 4 | import timber.log.Timber 5 | 6 | /** 7 | * @author Ruben Gees 8 | */ 9 | class HttpTimberLogger : HttpLoggingInterceptor.Logger { 10 | override fun log(message: String) { 11 | Timber.i(message) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | end_of_line = lf 4 | indent_size = 4 5 | indent_style = space 6 | max_line_length = 120 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.kt] 11 | continuation_indent_size = 4 12 | 13 | [*.{java,gradle}] 14 | continuation_indent_size = 8 15 | 16 | [*.{yml, json}] 17 | indent_size = 2 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /src/main/res/values/colors_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #1565c0 4 | #5e92f3 5 | #003c8f 6 | 7 | #00796b 8 | #48a999 9 | #004c40 10 | 11 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/forum/TopicMetaData.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.forum 2 | 3 | import java.util.Date 4 | 5 | /** 6 | * @author Ruben Gees 7 | */ 8 | data class TopicMetaData( 9 | val categoryId: String, 10 | val categoryName: String, 11 | val firstPostDate: Date, 12 | val lastPostDate: Date, 13 | val hits: Int, 14 | val isLocked: Boolean, 15 | val postAmount: Int, 16 | val subject: String 17 | ) 18 | -------------------------------------------------------------------------------- /.github/FEATURE_REQUEST.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | #### This is what I request as a feature: 8 | 9 | _Type here or delete section if not relevant._ 10 | 11 | #### Here are some screenshots/mockups of the feature: 12 | 13 | _Paste here or delete section if not relevant._ 14 | -------------------------------------------------------------------------------- /src/main/res/values/colors_gloomy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #263238 4 | #4f5b62 5 | #000a12 6 | 7 | #263238 8 | #4f5b62 9 | #000a12 10 | 11 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/AppRequiredErrorAction.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import me.proxer.app.util.ErrorUtils 5 | 6 | /** 7 | * @author Ruben Gees 8 | */ 9 | class AppRequiredErrorAction(private val name: String, private val appPackage: String) : ErrorUtils.ErrorAction(0) { 10 | fun showDialog(activity: AppCompatActivity) = AppRequiredDialog.show(activity, name, appPackage) 11 | } 12 | -------------------------------------------------------------------------------- /src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | proxer.me 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/release/kotlin/me/proxer/app/FlavorInitializer.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app 2 | 3 | import cat.ereza.customactivityoncrash.config.CaocConfig 4 | 5 | /** 6 | * @author Ruben Gees 7 | */ 8 | @Suppress("unused") 9 | object FlavorInitializer { 10 | 11 | fun initialize(@Suppress("UNUSED_PARAMETER") application: MainApplication) { 12 | CaocConfig.Builder.create() 13 | .backgroundMode(CaocConfig.BACKGROUND_MODE_CRASH) 14 | .apply() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/ConditionalTextMutatorPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import me.proxer.app.ui.view.bbcode.BBTree 4 | 5 | /** 6 | * @author Ruben Gees 7 | */ 8 | interface ConditionalTextMutatorPrototype : TextMutatorPrototype { 9 | 10 | fun canOptimize(recursiveChildren: List) = recursiveChildren.none { 11 | it.prototype !== TextPrototype && it.prototype !is TextMutatorPrototype 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/res/values/colors_gloomy_night.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #455a64 4 | #718792 5 | #1c313a 6 | 7 | #78909c 8 | #a7c0cd 9 | #4b636e 10 | 11 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/info/industry/IndustryInfoViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.info.industry 2 | 3 | import me.proxer.app.base.BaseContentViewModel 4 | import me.proxer.library.api.Endpoint 5 | import me.proxer.library.entity.info.Industry 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class IndustryInfoViewModel(private val industryId: String) : BaseContentViewModel() { 11 | 12 | override val endpoint: Endpoint 13 | get() = api.info.industry(industryId) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/news/widget/NewsWidgetProvider.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.news.widget 2 | 3 | import android.appwidget.AppWidgetManager 4 | import android.appwidget.AppWidgetProvider 5 | import android.content.Context 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class NewsWidgetProvider : AppWidgetProvider() { 11 | 12 | override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { 13 | NewsWidgetUpdateWorker.enqueueWork() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/news/widget/NewsWidgetDarkProvider.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.news.widget 2 | 3 | import android.appwidget.AppWidgetManager 4 | import android.appwidget.AppWidgetProvider 5 | import android.content.Context 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class NewsWidgetDarkProvider : AppWidgetProvider() { 11 | 12 | override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { 13 | NewsWidgetUpdateWorker.enqueueWork() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/res/menu/activity_share.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_messenger.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_notifications.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_topic.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/schedule/widget/ScheduleWidgetProvider.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.schedule.widget 2 | 3 | import android.appwidget.AppWidgetManager 4 | import android.appwidget.AppWidgetProvider 5 | import android.content.Context 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class ScheduleWidgetProvider : AppWidgetProvider() { 11 | 12 | override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { 13 | ScheduleWidgetUpdateWorker.enqueueWork() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/media/discussion/DiscussionViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.media.discussion 2 | 3 | import me.proxer.app.base.BaseContentViewModel 4 | import me.proxer.library.api.Endpoint 5 | import me.proxer.library.entity.info.ForumDiscussion 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class DiscussionViewModel(private val entryId: String) : BaseContentViewModel>() { 11 | 12 | override val endpoint: Endpoint> 13 | get() = api.info.forumDiscussions(entryId) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/schedule/widget/ScheduleWidgetDarkProvider.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.schedule.widget 2 | 3 | import android.appwidget.AppWidgetManager 4 | import android.appwidget.AppWidgetProvider 5 | import android.content.Context 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class ScheduleWidgetDarkProvider : AppWidgetProvider() { 11 | 12 | override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { 13 | ScheduleWidgetUpdateWorker.enqueueWork() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 10 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/base/BaseContentViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.base 2 | 3 | import io.reactivex.Single 4 | import me.proxer.app.util.extension.buildSingle 5 | import me.proxer.library.api.Endpoint 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | abstract class BaseContentViewModel : BaseViewModel() { 11 | 12 | override val dataSingle: Single 13 | get() = Single.fromCallable { validate() } 14 | .flatMap { endpoint.buildSingle() } 15 | 16 | protected abstract val endpoint: Endpoint 17 | } 18 | -------------------------------------------------------------------------------- /src/main/res/drawable/cursor.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/res/layout/item_chip.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_manga.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/media/recommendation/RecommendationViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.media.recommendation 2 | 3 | import me.proxer.app.base.BaseContentViewModel 4 | import me.proxer.library.api.Endpoint 5 | import me.proxer.library.entity.info.Recommendation 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class RecommendationViewModel(private val entryId: String) : BaseContentViewModel>() { 11 | 12 | override val endpoint: Endpoint> 13 | get() = api.info.recommendations(entryId) 14 | } 15 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | #### This Pull Request makes the following changes: 8 | 9 | _Type here or delete section if not relevant._ 10 | 11 | #### Here are some screenshots from the change: 12 | 13 | _Type here or delete section if not relevant._ 14 | 15 | #### The following code adjustments were necessary: 16 | 17 | _Type here or delete section if not relevant._ 18 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/profile/about/ProfileAboutViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.profile.about 2 | 3 | import me.proxer.app.base.BaseContentViewModel 4 | import me.proxer.library.api.Endpoint 5 | import me.proxer.library.entity.user.UserAbout 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class ProfileAboutViewModel( 11 | private val userId: String?, 12 | private val username: String? 13 | ) : BaseContentViewModel() { 14 | 15 | override val endpoint: Endpoint 16 | get() = api.user.about(userId, username) 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/prv/conference/info/ConferenceInfoViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.prv.conference.info 2 | 3 | import me.proxer.app.base.BaseContentViewModel 4 | import me.proxer.library.api.Endpoint 5 | import me.proxer.library.entity.messenger.ConferenceInfo 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class ConferenceInfoViewModel(private val conferenceId: String) : BaseContentViewModel() { 11 | 12 | override val endpoint: Endpoint 13 | get() = api.messenger.conferenceInfo(conferenceId) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/info/translatorgroup/TranslatorGroupInfoViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.info.translatorgroup 2 | 3 | import me.proxer.app.base.BaseContentViewModel 4 | import me.proxer.library.api.Endpoint 5 | import me.proxer.library.entity.info.TranslatorGroup 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class TranslatorGroupInfoViewModel(private val translatorGroupId: String) : BaseContentViewModel() { 11 | 12 | override val endpoint: Endpoint 13 | get() = api.info.translatorGroup(translatorGroupId) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/auth/LocalUser.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.auth 2 | 3 | import com.squareup.moshi.Json 4 | import com.squareup.moshi.JsonClass 5 | 6 | /** 7 | * @author Ruben Gees 8 | */ 9 | @JsonClass(generateAdapter = true) 10 | data class LocalUser( 11 | @Json(name = "token") val token: String, 12 | @Json(name = "id") val id: String, 13 | @Json(name = "name") val name: String, 14 | @Json(name = "image") val image: String 15 | ) { 16 | fun matches(userId: String?, username: String?) = this.id == userId || this.name.equals(username, ignoreCase = true) 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/data/HawkMoshiParser.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util.data 2 | 3 | import com.orhanobut.hawk.Parser 4 | import com.squareup.moshi.Moshi 5 | import java.lang.reflect.Type 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class HawkMoshiParser(private val moshi: Moshi) : Parser { 11 | override fun fromJson(content: String, type: Type): T? { 12 | return moshi.adapter(type).fromJson(content) 13 | } 14 | 15 | override fun toJson(body: Any): String? { 16 | return moshi.adapter(body.javaClass).toJson(body) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/res/drawable/player_control_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/base/PagedContentViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.base 2 | 3 | import io.reactivex.Single 4 | import me.proxer.app.util.extension.buildSingle 5 | import me.proxer.library.api.PagingLimitEndpoint 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | abstract class PagedContentViewModel : PagedViewModel() { 11 | 12 | override val dataSingle: Single> 13 | get() = Single.fromCallable { validate() } 14 | .flatMap { endpoint.page(page).limit(itemsOnPage).buildSingle() } 15 | 16 | protected abstract val endpoint: PagingLimitEndpoint> 17 | } 18 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_share_receiver.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/res/layout/item_theme.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/prv/ConferenceWithMessage.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.prv 2 | 3 | import androidx.room.Embedded 4 | import me.proxer.library.enums.MessageAction 5 | 6 | /** 7 | * @author Ruben Gees 8 | */ 9 | data class ConferenceWithMessage( 10 | @Embedded val conference: LocalConference, 11 | @Embedded val message: SimpleLocalMessage? 12 | ) { 13 | 14 | data class SimpleLocalMessage( 15 | val messageId: Long, 16 | val messageText: String, 17 | val userId: String, 18 | val username: String, 19 | val messageAction: MessageAction 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /src/main/res/drawable/ic_japan.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /src/release/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/resolver/MessageStreamResolver.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.resolver 2 | 3 | import androidx.core.text.parseAsHtml 4 | import io.reactivex.Single 5 | import me.proxer.app.util.extension.buildSingle 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | object MessageStreamResolver : StreamResolver() { 11 | 12 | override val name = "Nachricht" 13 | override val resolveEarly = true 14 | 15 | override fun resolve(id: String): Single = api.anime.link(id) 16 | .buildSingle() 17 | .map { StreamResolutionResult.Message(it.trim().parseAsHtml().trim()) } 18 | } 19 | -------------------------------------------------------------------------------- /.github/BUG_REPORT.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | I am using version: X.X.X 8 | My device is: X 9 | It runs `Android` version: X.X.X 10 | 11 | #### This is what happens: 12 | 13 | _Type here or delete section if not relevant._ 14 | 15 | #### This is what I expect to happen: 16 | 17 | _Type here or delete section if not relevant._ 18 | 19 | #### I determined the following steps to reproduce: 20 | 21 | _Type here or delete section if not relevant._ 22 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/pub/message/ChatReportViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.pub.message 2 | 3 | import com.gojuno.koptional.Optional 4 | import io.reactivex.Single 5 | import me.proxer.app.chat.ReportViewModel 6 | import me.proxer.app.util.extension.buildSingle 7 | import me.proxer.app.util.extension.safeInject 8 | import me.proxer.library.ProxerApi 9 | 10 | class ChatReportViewModel : ReportViewModel() { 11 | 12 | private val api by safeInject() 13 | 14 | override fun reportSingle(id: String, message: String): Single> { 15 | return api.chat.reportMessage(id, message).buildSingle() 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/res/xml/widget_provider_news.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | -------------------------------------------------------------------------------- /src/main/res/xml/widget_provider_schedule.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | -------------------------------------------------------------------------------- /src/main/res/xml/widget_provider_news_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/BreakPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import me.proxer.app.ui.view.bbcode.BBTree 4 | import me.proxer.app.ui.view.bbcode.prototype.BBPrototype.Companion.REGEX_OPTIONS 5 | 6 | /** 7 | * @author Ruben Gees 8 | */ 9 | object BreakPrototype : BBPrototype { 10 | 11 | override val startRegex = Regex(" *br *", REGEX_OPTIONS) 12 | override val endRegex = Regex("/ *br *", REGEX_OPTIONS) 13 | 14 | override val canHaveChildren get() = false 15 | 16 | override fun construct(code: String, parent: BBTree): BBTree { 17 | return TextPrototype.construct("\n", parent) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/res/values-night/themes_gloomy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zhanghai/android/materialprogressbar/ThinSingleCircularProgressDrawable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Zhang Hai 3 | * All Rights Reserved. 4 | */ 5 | package me.zhanghai.android.materialprogressbar 6 | 7 | import android.graphics.Canvas 8 | import android.graphics.Paint 9 | 10 | /** 11 | * Adjusted drawable to make stroke thinner. 12 | * 13 | * @author Ruben Gees 14 | */ 15 | internal class ThinSingleCircularProgressDrawable(style: Int) : SingleCircularProgressDrawable(style) { 16 | 17 | override fun onDrawRing(canvas: Canvas, paint: Paint) { 18 | super.onDrawRing(canvas, paint.apply { strokeWidth = 2f }) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/res/xml/widget_provider_schedule_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/resolver/SteamStreamResolver.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.resolver 2 | 3 | import io.reactivex.Single 4 | import me.proxer.app.exception.StreamResolutionException 5 | import me.proxer.app.util.extension.buildSingle 6 | import me.proxer.app.util.extension.toPrefixedUrlOrNull 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | object SteamStreamResolver : StreamResolver() { 12 | 13 | override val name = "Steam" 14 | 15 | override fun resolve(id: String): Single = api.anime.link(id) 16 | .buildSingle() 17 | .map { StreamResolutionResult.Link(it.toPrefixedUrlOrNull() ?: throw StreamResolutionException()) } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/AnimeStream.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime 2 | 3 | import me.proxer.app.anime.resolver.StreamResolutionResult 4 | import org.threeten.bp.Instant 5 | 6 | /** 7 | * @author Ruben Gees 8 | */ 9 | data class AnimeStream( 10 | val id: String, 11 | val hoster: String, 12 | val hosterName: String, 13 | val image: String, 14 | val uploaderId: String, 15 | val uploaderName: String, 16 | val date: Instant, 17 | val translatorGroupId: String?, 18 | val translatorGroupName: String?, 19 | val isOfficial: Boolean, 20 | val isPublic: Boolean, 21 | val isSupported: Boolean, 22 | val resolutionResult: StreamResolutionResult? 23 | ) 24 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/resolver/YouTubeStreamResolver.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.resolver 2 | 3 | import io.reactivex.Single 4 | import me.proxer.app.exception.StreamResolutionException 5 | import me.proxer.app.util.extension.buildSingle 6 | import me.proxer.app.util.extension.toPrefixedUrlOrNull 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | object YouTubeStreamResolver : StreamResolver() { 12 | 13 | override val name = "YouTube" 14 | 15 | override fun resolve(id: String): Single = api.anime.link(id) 16 | .buildSingle() 17 | .map { StreamResolutionResult.Link(it.toPrefixedUrlOrNull() ?: throw StreamResolutionException()) } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/res/drawable/ic_germany.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/resolver/AnimeOnDemandStreamResolver.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.resolver 2 | 3 | import io.reactivex.Single 4 | import me.proxer.app.exception.StreamResolutionException 5 | import me.proxer.app.util.extension.buildSingle 6 | import me.proxer.app.util.extension.toPrefixedUrlOrNull 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | object AnimeOnDemandStreamResolver : StreamResolver() { 12 | 13 | override val name = "Anime on demand" 14 | 15 | override fun resolve(id: String): Single = api.anime.link(id) 16 | .buildSingle() 17 | .map { StreamResolutionResult.Link(it.toPrefixedUrlOrNull() ?: throw StreamResolutionException()) } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/resolver/ProsiebenMAXXStreamResolver.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.resolver 2 | 3 | import io.reactivex.Single 4 | import me.proxer.app.exception.StreamResolutionException 5 | import me.proxer.app.util.extension.buildSingle 6 | import me.proxer.app.util.extension.toPrefixedUrlOrNull 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | object ProsiebenMAXXStreamResolver : StreamResolver() { 12 | 13 | override val name = "ProSieben MAXX" 14 | 15 | override fun resolve(id: String): Single = api.anime.link(id) 16 | .buildSingle() 17 | .map { StreamResolutionResult.Link(it.toPrefixedUrlOrNull() ?: throw StreamResolutionException()) } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/info/industry/IndustryProjectViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.info.industry 2 | 3 | import me.proxer.app.base.PagedContentViewModel 4 | import me.proxer.library.api.PagingLimitEndpoint 5 | import me.proxer.library.entity.list.IndustryProject 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class IndustryProjectViewModel(private val industryId: String) : PagedContentViewModel() { 11 | 12 | override val itemsOnPage = 30 13 | 14 | override val endpoint: PagingLimitEndpoint> 15 | get() = api.list.industryProjectList(industryId) 16 | .includeHentai(preferenceHelper.isAgeRestrictedMediaAllowed && storageHelper.isLoggedIn) 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/resolver/AmazonPrimeVideoStreamResolver.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.resolver 2 | 3 | import io.reactivex.Single 4 | import me.proxer.app.exception.StreamResolutionException 5 | import me.proxer.app.util.extension.buildSingle 6 | import me.proxer.app.util.extension.toPrefixedUrlOrNull 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | object AmazonPrimeVideoStreamResolver : StreamResolver() { 12 | 13 | override val name = "Amazon Prime Video" 14 | 15 | override fun resolve(id: String): Single = api.anime.link(id) 16 | .buildSingle() 17 | .map { StreamResolutionResult.Link(it.toPrefixedUrlOrNull() ?: throw StreamResolutionException()) } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/resolver/StreamResolverFactory.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.resolver 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | object StreamResolverFactory { 7 | 8 | private val resolvers = arrayOf( 9 | AmazonPrimeVideoStreamResolver, AnimeOnDemandStreamResolver, MessageStreamResolver, CrunchyrollStreamResolver, 10 | DailymotionStreamResolver, Mp4UploadStreamResolver, NetflixStreamResolver, ProsiebenMAXXStreamResolver, 11 | ProxerStreamResolver, ProxerStreamCFResolver, SteamStreamResolver, StreamcloudStreamResolver, 12 | YourUploadStreamResolver, YouTubeStreamResolver 13 | ) 14 | 15 | fun resolverFor(name: String) = resolvers.find { it.supports(name) } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | false 6 | 7 | 16dp 8 | 16dp 9 | 8dp 10 | 8dp 11 | 12 | 8dp 13 | 14 | 512dp 15 | 184dp 16 | 128dp 17 | 18 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/pub/message/ChatReportDialog.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.pub.message 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import androidx.core.os.bundleOf 5 | import me.proxer.app.chat.ReportDialog 6 | import org.koin.androidx.viewmodel.ext.android.viewModel 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | class ChatReportDialog : ReportDialog() { 12 | 13 | companion object { 14 | fun show(activity: AppCompatActivity, messageId: String) = ChatReportDialog() 15 | .apply { arguments = bundleOf(ID_ARGUMENT to messageId) } 16 | .show(activity.supportFragmentManager, "chat_report_dialog") 17 | } 18 | 19 | override val viewModel by viewModel() 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/auth/ProxerLoginTokenManager.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.auth 2 | 3 | import me.proxer.app.util.data.StorageHelper 4 | import me.proxer.library.LoginTokenManager 5 | 6 | /** 7 | * @author Ruben Gees 8 | */ 9 | class ProxerLoginTokenManager(private val storageHelper: StorageHelper) : LoginTokenManager { 10 | 11 | override fun provide() = storageHelper.user?.token ?: storageHelper.temporaryToken 12 | 13 | override fun persist(loginToken: String?) { 14 | when (loginToken) { 15 | null -> storageHelper.user = null 16 | else -> Unit /* Don't do anything in case the token is not null. We save the token 17 | manually in the LoginDialog. */ 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/res/xml/backup_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 13 | 14 | 17 | 20 | 23 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /src/release/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Absturz 4 | 5 | Die App ist leider abgestürzt. Sende den Fehler bitte an @RubyGee oder einen 6 | anderen Techniker um bei der Beseitigung zu helfen! 7 | 8 | Fehlerbericht 9 | Neustart 10 | 11 | Fehlerbericht 12 | Kopieren 13 | Schließen 14 | 15 | Proxer.Me Fehlerbericht 16 | 17 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/prv/message/MessengerReportDialog.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.prv.message 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import androidx.core.os.bundleOf 5 | import me.proxer.app.chat.ReportDialog 6 | import org.koin.androidx.viewmodel.ext.android.viewModel 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | class MessengerReportDialog : ReportDialog() { 12 | 13 | companion object { 14 | fun show(activity: AppCompatActivity, conferenceId: String) = MessengerReportDialog().apply { 15 | arguments = bundleOf(ID_ARGUMENT to conferenceId) 16 | }.show(activity.supportFragmentManager, "messenger_report_dialog") 17 | } 18 | 19 | override val viewModel by viewModel() 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/SubscriptPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import android.text.SpannableStringBuilder 4 | import android.text.style.SubscriptSpan 5 | import androidx.core.text.set 6 | import me.proxer.app.ui.view.bbcode.BBArgs 7 | import me.proxer.app.ui.view.bbcode.prototype.BBPrototype.Companion.REGEX_OPTIONS 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | object SubscriptPrototype : TextMutatorPrototype { 13 | 14 | override val startRegex = Regex(" *sub( .*?)?", REGEX_OPTIONS) 15 | override val endRegex = Regex("/ *sub *", REGEX_OPTIONS) 16 | 17 | override fun mutate(text: SpannableStringBuilder, args: BBArgs) = text.apply { 18 | this[0..length] = SubscriptSpan() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/UnderlinePrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import android.text.SpannableStringBuilder 4 | import android.text.style.UnderlineSpan 5 | import androidx.core.text.set 6 | import me.proxer.app.ui.view.bbcode.BBArgs 7 | import me.proxer.app.ui.view.bbcode.prototype.BBPrototype.Companion.REGEX_OPTIONS 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | object UnderlinePrototype : TextMutatorPrototype { 13 | 14 | override val startRegex = Regex(" *u( .*?)?", REGEX_OPTIONS) 15 | override val endRegex = Regex("/ *u *", REGEX_OPTIONS) 16 | 17 | override fun mutate(text: SpannableStringBuilder, args: BBArgs) = text.apply { 18 | this[0..length] = UnderlineSpan() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/SuperscriptPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import android.text.SpannableStringBuilder 4 | import android.text.style.SuperscriptSpan 5 | import androidx.core.text.set 6 | import me.proxer.app.ui.view.bbcode.BBArgs 7 | import me.proxer.app.ui.view.bbcode.prototype.BBPrototype.Companion.REGEX_OPTIONS 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | object SuperscriptPrototype : TextMutatorPrototype { 13 | 14 | override val startRegex = Regex(" *sup( .*?)?", REGEX_OPTIONS) 15 | override val endRegex = Regex("/ *sup *", REGEX_OPTIONS) 16 | 17 | override fun mutate(text: SpannableStringBuilder, args: BBArgs) = text.apply { 18 | this[0..length] = SuperscriptSpan() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/res/menu/activity_stream.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/http/ConnectionCloseInterceptor.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util.http 2 | 3 | import me.proxer.library.util.ProxerUrls.hasProxerProxyHost 4 | import okhttp3.Interceptor 5 | import okhttp3.Response 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class ConnectionCloseInterceptor : Interceptor { 11 | 12 | override fun intercept(chain: Interceptor.Chain): Response { 13 | val oldRequest = chain.request() 14 | 15 | return if (oldRequest.url.hasProxerProxyHost) { 16 | val newRequest = oldRequest.newBuilder() 17 | .header("Connection", "close") 18 | .build() 19 | 20 | chain.proceed(newRequest) 21 | } else { 22 | chain.proceed(oldRequest) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | false 5 | false 6 | 7 | 12dp 8 | 12dp 9 | 8dp 10 | 8dp 11 | 12 | 4dp 13 | 14 | 256dp 15 | 92dp 16 | 64dp 17 | 18 | 32dp 19 | 20 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/media/TagDao.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.media 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | import androidx.room.Transaction 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | @Dao 13 | abstract class TagDao { 14 | 15 | @Transaction 16 | open fun replaceTags(tags: List): List { 17 | clear() 18 | 19 | return insertTags(tags) 20 | } 21 | 22 | @Insert(onConflict = OnConflictStrategy.REPLACE) 23 | abstract fun insertTags(tags: List): List 24 | 25 | @Query("SELECT * FROM tags") 26 | abstract fun getTags(): List 27 | 28 | @Query("DELETE FROM tags") 29 | abstract fun clear() 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/BoldPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import android.graphics.Typeface.BOLD 4 | import android.text.SpannableStringBuilder 5 | import android.text.style.StyleSpan 6 | import androidx.core.text.set 7 | import me.proxer.app.ui.view.bbcode.BBArgs 8 | import me.proxer.app.ui.view.bbcode.prototype.BBPrototype.Companion.REGEX_OPTIONS 9 | 10 | /** 11 | * @author Ruben Gees 12 | */ 13 | object BoldPrototype : TextMutatorPrototype { 14 | 15 | override val startRegex = Regex(" *b( .*?)?", REGEX_OPTIONS) 16 | override val endRegex = Regex("/ *b *", REGEX_OPTIONS) 17 | 18 | override fun mutate(text: SpannableStringBuilder, args: BBArgs) = text.apply { 19 | this[0..length] = StyleSpan(BOLD) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/info/translatorgroup/TranslatorGroupProjectViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.info.translatorgroup 2 | 3 | import me.proxer.app.base.PagedContentViewModel 4 | import me.proxer.library.api.PagingLimitEndpoint 5 | import me.proxer.library.entity.list.TranslatorGroupProject 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | class TranslatorGroupProjectViewModel( 11 | private val translatorGroupId: String 12 | ) : PagedContentViewModel() { 13 | 14 | override val itemsOnPage = 30 15 | 16 | override val endpoint: PagingLimitEndpoint> 17 | get() = api.list.translatorGroupProjectList(translatorGroupId) 18 | .includeHentai(preferenceHelper.isAgeRestrictedMediaAllowed && storageHelper.isLoggedIn) 19 | } 20 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/StrikethroughPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import android.text.SpannableStringBuilder 4 | import android.text.style.StrikethroughSpan 5 | import androidx.core.text.set 6 | import me.proxer.app.ui.view.bbcode.BBArgs 7 | import me.proxer.app.ui.view.bbcode.prototype.BBPrototype.Companion.REGEX_OPTIONS 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | object StrikethroughPrototype : TextMutatorPrototype { 13 | 14 | override val startRegex = Regex(" *(s|strike)( .*?)?", REGEX_OPTIONS) 15 | override val endRegex = Regex("/ *(s|strike) *", REGEX_OPTIONS) 16 | 17 | override fun mutate(text: SpannableStringBuilder, args: BBArgs) = text.apply { 18 | this[0..length] = StrikethroughSpan() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/ItalicPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import android.graphics.Typeface 4 | import android.text.SpannableStringBuilder 5 | import android.text.style.StyleSpan 6 | import androidx.core.text.set 7 | import me.proxer.app.ui.view.bbcode.BBArgs 8 | import me.proxer.app.ui.view.bbcode.prototype.BBPrototype.Companion.REGEX_OPTIONS 9 | 10 | /** 11 | * @author Ruben Gees 12 | */ 13 | object ItalicPrototype : TextMutatorPrototype { 14 | 15 | override val startRegex = Regex(" *i( .*?)?", REGEX_OPTIONS) 16 | override val endRegex = Regex("/ *i *", REGEX_OPTIONS) 17 | 18 | override fun mutate(text: SpannableStringBuilder, args: BBArgs) = text.apply { 19 | this[0..length] = StyleSpan(Typeface.ITALIC) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/Validators.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util 2 | 3 | import me.proxer.app.exception.AgeConfirmationRequiredException 4 | import me.proxer.app.exception.NotLoggedInException 5 | import me.proxer.app.util.data.PreferenceHelper 6 | import me.proxer.app.util.data.StorageHelper 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | class Validators(private val storageHelper: StorageHelper, private val preferenceHelper: PreferenceHelper) { 12 | 13 | fun validateLogin() { 14 | if (!storageHelper.isLoggedIn) { 15 | throw NotLoggedInException() 16 | } 17 | } 18 | 19 | fun validateAgeConfirmation() { 20 | if (!preferenceHelper.isAgeRestrictedMediaAllowed) { 21 | throw AgeConfirmationRequiredException() 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Thank you for your interest in contributing! 2 | 3 | All contributions are welcome, might it be a simple fix of a typo or the 4 | rewrite of an entire module. 5 | 6 | Before working on the change, check if there is already somebody working 7 | on the problem (Search issues or look through the commits/code). 8 | 9 | Please try to match the coding style as closely as possible by looking 10 | at the existing code. If in doubt, refer to the 11 | [Kotlin style guide](https://android.github.io/kotlin-guides/style.html). 12 | 13 | If you are not sure about something, simply 14 | [create a new issue](https://github.com/proxer/ProxerAndroid/issues/new). 15 | The PR does not need to be perfect at first as it can be reviewed and 16 | improved! 17 | 18 | All contributors will be credited in the README. 19 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/media/relation/RelationViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.media.relation 2 | 3 | import io.reactivex.Single 4 | import me.proxer.app.base.BaseContentViewModel 5 | import me.proxer.library.api.Endpoint 6 | import me.proxer.library.entity.info.Relation 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | class RelationViewModel(private val entryId: String) : BaseContentViewModel>() { 12 | 13 | override val endpoint: Endpoint> 14 | get() = api.info.relations(entryId) 15 | .includeHentai(preferenceHelper.isAgeRestrictedMediaAllowed && storageHelper.isLoggedIn) 16 | 17 | override val dataSingle: Single> 18 | get() = super.dataSingle 19 | .map { relations -> relations.filterNot { it.id == entryId } } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/res/drawable/play_pause_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 13 | 14 | 18 | 19 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_edit_comment.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_messenger_cab.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 22 | 23 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx2048M -XX:MaxPermSize=512m -XX:MaxHeapSize=1024M -Dfile.encoding=UTF-8 2 | org.gradle.vfs.watch=true 3 | org.gradle.parallel=true 4 | org.gradle.caching=true 5 | 6 | kotlin.code.style=official 7 | 8 | kapt.use.worker.api=true 9 | kapt.incremental.apt=true 10 | kapt.include.compile.classpath=false 11 | 12 | android.useAndroidX=true 13 | android.enableJetifier=true 14 | android.namespacedRClass=true 15 | android.enableR8.fullMode=true 16 | android.useMinimalKeepRules=true 17 | android.enableSeparateAnnotationProcessing=true 18 | android.bundle.enableUncompressedNativeLibs=false 19 | android.suppressUnsupportedOptionWarnings=android.suppressUnsupportedOptionWarnings,android.enableR8.fullMode,\ 20 | android.namespacedRClass,android.useMinimalKeepRules,android.enableSeparateAnnotationProcessing 21 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/data/InstantJsonAdapter.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util.data 2 | 3 | import com.squareup.moshi.JsonAdapter 4 | import com.squareup.moshi.JsonReader 5 | import com.squareup.moshi.JsonWriter 6 | import org.threeten.bp.Instant 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | class InstantJsonAdapter : JsonAdapter() { 12 | override fun fromJson(reader: JsonReader): Instant? { 13 | return when (reader.peek()) { 14 | JsonReader.Token.NULL -> null 15 | else -> Instant.ofEpochMilli(reader.nextLong()) 16 | } 17 | } 18 | 19 | override fun toJson(writer: JsonWriter, value: Instant?) { 20 | when (value) { 21 | null -> writer.nullValue() 22 | else -> writer.value(value.toEpochMilli()) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/settings/ProxerLibsActivity.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.settings 2 | 3 | import android.os.Bundle 4 | import androidx.fragment.app.commitNow 5 | import com.mikepenz.aboutlibraries.Libs 6 | import com.mikepenz.aboutlibraries.ui.LibsSupportFragment 7 | import me.proxer.app.R 8 | import me.proxer.app.base.DrawerActivity 9 | 10 | class ProxerLibsActivity : DrawerActivity() { 11 | 12 | override fun onCreate(savedInstanceState: Bundle?) { 13 | super.onCreate(savedInstanceState) 14 | 15 | title = intent.extras?.getString(Libs.BUNDLE_TITLE, "") 16 | 17 | val fragment = LibsSupportFragment().apply { 18 | arguments = intent.extras 19 | } 20 | 21 | supportFragmentManager.commitNow { 22 | replace(R.id.container, fragment) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/resolver/StreamResolver.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.resolver 2 | 3 | import com.squareup.moshi.Moshi 4 | import io.reactivex.Single 5 | import me.proxer.app.util.extension.safeInject 6 | import me.proxer.library.ProxerApi 7 | import okhttp3.OkHttpClient 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | abstract class StreamResolver { 13 | 14 | abstract val name: String 15 | 16 | open val resolveEarly: Boolean get() = false 17 | open val ignore: Boolean get() = false 18 | 19 | protected val api by safeInject() 20 | protected val client by safeInject() 21 | protected val moshi by safeInject() 22 | 23 | open fun supports(name: String) = name.equals(this.name, true) 24 | abstract fun resolve(id: String): Single 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/settings/theme/ThemeContainer.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.settings.theme 2 | 3 | /** 4 | * @author Ruben Gees 5 | */ 6 | data class ThemeContainer(val theme: Theme, val variant: ThemeVariant) { 7 | 8 | companion object { 9 | private const val DELIMITER = "_" 10 | 11 | fun fromPreferenceString(value: String): ThemeContainer { 12 | val split = value.split(DELIMITER) 13 | 14 | val theme = Theme.values().find { it.preferenceId == split.getOrNull(0) } ?: Theme.CLASSIC 15 | val variant = ThemeVariant.values().find { it.preferenceId == split.getOrNull(1) } ?: ThemeVariant.SYSTEM 16 | 17 | return ThemeContainer(theme, variant) 18 | } 19 | } 20 | 21 | fun toPreferenceString() = "${theme.preferenceId}$DELIMITER${variant.preferenceId}" 22 | } 23 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/compat/MenuPopupCompat.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util.compat 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.view.Menu 6 | import android.view.View 7 | import androidx.appcompat.view.menu.MenuBuilder 8 | import androidx.appcompat.view.menu.MenuPopupHelper 9 | 10 | /** 11 | * @author Ruben Gees 12 | */ 13 | class MenuPopupCompat(private val context: Context, private val menu: Menu, private val anchorView: View) { 14 | 15 | private var forceShowIcon: Boolean = false 16 | 17 | fun forceShowIcon() = this.apply { forceShowIcon = true } 18 | 19 | @SuppressLint("RestrictedApi") 20 | fun show(x: Int = 0, y: Int = 0) = MenuPopupHelper(context, menu as MenuBuilder, anchorView) 21 | .apply { setForceShowIcon(forceShowIcon) } 22 | .show(x, y) 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/DefaultActivityLifecycleCallbacks.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util 2 | 3 | import android.app.Activity 4 | import android.app.Application 5 | import android.os.Bundle 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | interface DefaultActivityLifecycleCallbacks : Application.ActivityLifecycleCallbacks { 11 | 12 | override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) = Unit 13 | override fun onActivityStarted(activity: Activity) = Unit 14 | override fun onActivityResumed(activity: Activity) = Unit 15 | override fun onActivityPaused(activity: Activity) = Unit 16 | override fun onActivityStopped(activity: Activity) = Unit 17 | override fun onActivityDestroyed(activity: Activity) = Unit 18 | override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit 19 | } 20 | -------------------------------------------------------------------------------- /src/main/res/menu/activity_profile.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/rx/RxRetryWithDelay.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util.rx 2 | 3 | import io.reactivex.Flowable 4 | import io.reactivex.functions.Function 5 | import java.util.concurrent.TimeUnit 6 | 7 | /** 8 | * Stolen and adjusted from here: https://stackoverflow.com/a/25292833/4279995 9 | */ 10 | class RxRetryWithDelay( 11 | private val maxRetries: Int, 12 | private val retryDelayMillis: Long 13 | ) : Function, Flowable<*>> { 14 | 15 | private var retryCount: Int = 0 16 | 17 | override fun apply(attempts: Flowable): Flowable = attempts 18 | .flatMap { throwable -> 19 | when { 20 | ++retryCount < maxRetries -> Flowable.timer(retryDelayMillis, TimeUnit.MILLISECONDS) 21 | else -> Flowable.error(throwable) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/http/UserAgentInterceptor.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util.http 2 | 3 | import me.proxer.app.MainApplication.Companion.USER_AGENT 4 | import me.proxer.library.util.ProxerUrls.hasProxerHost 5 | import okhttp3.Interceptor 6 | import okhttp3.Response 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | class UserAgentInterceptor : Interceptor { 12 | 13 | override fun intercept(chain: Interceptor.Chain): Response { 14 | val request = chain.request() 15 | 16 | val newRequest = when (request.header("User-Agent") == null && request.url.hasProxerHost) { 17 | true -> 18 | request.newBuilder() 19 | .header("User-Agent", USER_AGENT) 20 | .build() 21 | 22 | false -> request 23 | } 24 | 25 | return chain.proceed(newRequest) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/logRelease/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 10 | 11 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/media/TagDatabase.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.media 2 | 3 | import androidx.room.Database 4 | import androidx.room.RoomDatabase 5 | import androidx.room.TypeConverters 6 | import androidx.room.migration.Migration 7 | import androidx.sqlite.db.SupportSQLiteDatabase 8 | import me.proxer.app.util.converter.RoomConverters 9 | 10 | /** 11 | * @author Ruben Gees 12 | */ 13 | @Suppress("UnnecessaryAbstractClass") 14 | @Database(entities = [LocalTag::class], version = 2) 15 | @TypeConverters(RoomConverters::class) 16 | abstract class TagDatabase : RoomDatabase() { 17 | 18 | companion object { 19 | val MIGRATION_1_2 = object : Migration(1, 2) { 20 | override fun migrate(database: SupportSQLiteDatabase) { 21 | // Nothing to do here, needed due to a bug. 22 | } 23 | } 24 | } 25 | 26 | abstract fun dao(): TagDao 27 | } 28 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/news/widget/NewsWidgetService.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.news.widget 2 | 3 | import android.content.Intent 4 | import android.widget.RemoteViewsService 5 | import com.squareup.moshi.Moshi 6 | import me.proxer.app.util.extension.getSafeStringArrayExtra 7 | import me.proxer.app.util.extension.safeInject 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | class NewsWidgetService : RemoteViewsService() { 13 | 14 | companion object { 15 | const val ARGUMENT_NEWS = "news" 16 | } 17 | 18 | private val moshi by safeInject() 19 | 20 | override fun onGetViewFactory(intent: Intent): RemoteViewsFactory { 21 | val news = intent.getSafeStringArrayExtra(ARGUMENT_NEWS) 22 | .mapNotNull { moshi.adapter(SimpleNews::class.java).fromJson(it) } 23 | 24 | return NewsWidgetViewsFactory(applicationContext, false, news) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/news/widget/NewsWidgetDarkService.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.news.widget 2 | 3 | import android.content.Intent 4 | import android.widget.RemoteViewsService 5 | import com.squareup.moshi.Moshi 6 | import me.proxer.app.util.extension.getSafeStringArrayExtra 7 | import me.proxer.app.util.extension.safeInject 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | class NewsWidgetDarkService : RemoteViewsService() { 13 | 14 | companion object { 15 | const val ARGUMENT_NEWS = "news" 16 | } 17 | 18 | private val moshi by safeInject() 19 | 20 | override fun onGetViewFactory(intent: Intent): RemoteViewsFactory { 21 | val news = intent.getSafeStringArrayExtra(ARGUMENT_NEWS) 22 | .mapNotNull { moshi.adapter(SimpleNews::class.java).fromJson(it) } 23 | 24 | return NewsWidgetViewsFactory(applicationContext, true, news) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/settings/theme/ThemeVariant.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.settings.theme 2 | 3 | import android.os.Build 4 | import androidx.annotation.StringRes 5 | import androidx.appcompat.app.AppCompatDelegate 6 | import me.proxer.app.R 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | enum class ThemeVariant( 12 | val preferenceId: String, 13 | @StringRes val variantName: Int?, 14 | @AppCompatDelegate.NightMode val value: Int 15 | ) { 16 | LIGHT("0", R.string.theme_variant_light, AppCompatDelegate.MODE_NIGHT_NO), 17 | DARK("1", R.string.theme_variant_dark, AppCompatDelegate.MODE_NIGHT_YES), 18 | SYSTEM( 19 | "2", 20 | null, 21 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { 22 | AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM 23 | } else { 24 | AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY 25 | } 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /src/main/res/layout/item_manga_page_gif.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/res/layout/item_manga_page.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/res/values/colors_night.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #C21414 5 | #FC533E 6 | #890000 7 | 8 | #303030 9 | #FFFFFF 10 | #424242 11 | 12 | #424242 13 | #FFFFFF 14 | #5C5C5C 15 | 16 | #1FFFFFFF 17 | #B3FFFFFF 18 | #42FFFFFF 19 | 20 | #1FFFFFFF 21 | #9E9E9E 22 | 23 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/InfoImageButton.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import androidx.appcompat.widget.AppCompatImageButton 6 | import androidx.appcompat.widget.TooltipCompat 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | class InfoImageButton @JvmOverloads constructor( 12 | context: Context, 13 | attrs: AttributeSet? = null, 14 | defStyleAttr: Int = 0 15 | ) : AppCompatImageButton(context, attrs, defStyleAttr) { 16 | 17 | init { 18 | updateTooltip() 19 | } 20 | 21 | override fun setContentDescription(contentDescription: CharSequence?) { 22 | super.setContentDescription(contentDescription) 23 | 24 | updateTooltip() 25 | } 26 | 27 | private fun updateTooltip() { 28 | contentDescription?.let { 29 | TooltipCompat.setTooltipText(this, it) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/res/layout/activity_image_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/forum/ParsedPost.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.forum 2 | 3 | import me.proxer.app.ui.view.bbcode.BBTree 4 | import me.proxer.app.util.extension.toDate 5 | import me.proxer.library.entity.ProxerDateItem 6 | import me.proxer.library.entity.ProxerIdItem 7 | import me.proxer.library.entity.ProxerImageItem 8 | import org.threeten.bp.Instant 9 | 10 | /** 11 | * @author Ruben Gees 12 | */ 13 | data class ParsedPost( 14 | override val id: String, 15 | val parentId: String, 16 | val userId: String, 17 | val username: String, 18 | override val image: String, 19 | val instant: Instant, 20 | val signature: BBTree?, 21 | val modifiedById: String?, 22 | val modifiedByName: String?, 23 | val modifiedReason: String?, 24 | val parsedMessage: BBTree, 25 | val thankYouAmount: Int 26 | ) : ProxerIdItem, ProxerImageItem, ProxerDateItem { 27 | 28 | @Transient 29 | override val date = instant.toDate() 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/compat/ConnectivityCompat.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("DEPRECATION") 2 | 3 | package me.proxer.app.util.compat 4 | 5 | import android.net.ConnectivityManager 6 | import android.net.NetworkCapabilities 7 | import android.os.Build 8 | 9 | val ConnectivityManager.isConnected 10 | get() = when { 11 | Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> activeNetwork != null 12 | Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> activeNetworkInfo != null 13 | else -> activeNetworkInfo?.isConnectedOrConnecting ?: false 14 | } 15 | 16 | val ConnectivityManager.isConnectedToCellular 17 | get() = when { 18 | Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> 19 | getNetworkCapabilities(activeNetwork) 20 | ?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ?: false 21 | else -> getNetworkInfo(ConnectivityManager.TYPE_MOBILE)?.isConnectedOrConnecting ?: false 22 | } 23 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/pub/message/ParsedChatMessage.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.pub.message 2 | 3 | import me.proxer.app.ui.view.bbcode.toSimpleBBTree 4 | import me.proxer.app.util.extension.toDate 5 | import me.proxer.library.entity.ProxerDateItem 6 | import me.proxer.library.entity.ProxerIdItem 7 | import me.proxer.library.entity.ProxerImageItem 8 | import me.proxer.library.enums.ChatMessageAction 9 | import org.threeten.bp.Instant 10 | 11 | /** 12 | * @author Ruben Gees 13 | */ 14 | data class ParsedChatMessage( 15 | override val id: String, 16 | val userId: String, 17 | val username: String, 18 | override val image: String, 19 | val message: String, 20 | val action: ChatMessageAction, 21 | val instant: Instant 22 | ) : ProxerIdItem, ProxerImageItem, ProxerDateItem { 23 | 24 | @Transient 25 | override val date = instant.toDate() 26 | 27 | @Transient 28 | val styledMessage = message.toSimpleBBTree() 29 | } 30 | -------------------------------------------------------------------------------- /src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 20 | 21 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { scriptHandler -> 2 | apply from: "gradle/versions.gradle" 3 | apply from: "gradle/repositories.gradle", to: scriptHandler 4 | 5 | plugins { 6 | id "org.jetbrains.kotlin.android" version "${kotlinVersion}" 7 | id "org.jetbrains.kotlin.kapt" version "${kotlinVersion}" 8 | 9 | id "com.mikepenz.aboutlibraries.plugin" version "${aboutLibrariesVersion}" 10 | 11 | id "com.github.ben-manes.versions" version "${versionsPluginVersion}" 12 | id "io.gitlab.arturbosch.detekt" version "${detektPluginVersion}" 13 | id "org.jlleitschuh.gradle.ktlint" version "${ktlintPluginVersion}" 14 | } 15 | 16 | resolutionStrategy { 17 | eachPlugin { 18 | if (requested.id.id == "com.android.application") { 19 | useModule("com.android.tools.build:gradle:${androidPluginVersion}") 20 | } 21 | } 22 | } 23 | } 24 | 25 | rootProject.name = "ProxerAndroid" 26 | -------------------------------------------------------------------------------- /src/main/res/values/themes_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/schedule/ScheduleViewModel.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.schedule 2 | 3 | import io.reactivex.Single 4 | import me.proxer.app.base.BaseViewModel 5 | import me.proxer.app.util.extension.buildSingle 6 | import me.proxer.library.entity.media.CalendarEntry 7 | import me.proxer.library.enums.CalendarDay 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | class ScheduleViewModel : BaseViewModel>>() { 13 | 14 | override val dataSingle: Single>> 15 | get() = Single.fromCallable { validate() } 16 | .flatMap { api.media.calendar().buildSingle() } 17 | .map { calendarEntries -> calendarEntries.groupBy { it.weekDay } } 18 | .map { groupedCalendarEntries -> 19 | groupedCalendarEntries.mapValues { (_, calendarEntries) -> 20 | calendarEntries.sortedBy { it.date } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/schedule/widget/ScheduleWidgetService.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.schedule.widget 2 | 3 | import android.content.Intent 4 | import android.widget.RemoteViewsService 5 | import com.squareup.moshi.Moshi 6 | import me.proxer.app.util.extension.getSafeStringArrayExtra 7 | import me.proxer.app.util.extension.safeInject 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | class ScheduleWidgetService : RemoteViewsService() { 13 | 14 | companion object { 15 | const val ARGUMENT_CALENDAR_ENTRIES = "calendar_entries" 16 | } 17 | 18 | private val moshi by safeInject() 19 | 20 | override fun onGetViewFactory(intent: Intent): RemoteViewsFactory { 21 | val calendarEntries = intent.getSafeStringArrayExtra(ARGUMENT_CALENDAR_ENTRIES) 22 | .mapNotNull { moshi.adapter(SimpleCalendarEntry::class.java).fromJson(it) } 23 | 24 | return ScheduleWidgetViewsFactory(applicationContext, false, calendarEntries) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/anime/schedule/widget/ScheduleWidgetDarkService.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.anime.schedule.widget 2 | 3 | import android.content.Intent 4 | import android.widget.RemoteViewsService 5 | import com.squareup.moshi.Moshi 6 | import me.proxer.app.util.extension.getSafeStringArrayExtra 7 | import me.proxer.app.util.extension.safeInject 8 | 9 | /** 10 | * @author Ruben Gees 11 | */ 12 | class ScheduleWidgetDarkService : RemoteViewsService() { 13 | 14 | companion object { 15 | const val ARGUMENT_CALENDAR_ENTRIES = "calendar_entries" 16 | } 17 | 18 | private val moshi by safeInject() 19 | 20 | override fun onGetViewFactory(intent: Intent): RemoteViewsFactory { 21 | val calendarEntries = intent.getSafeStringArrayExtra(ARGUMENT_CALENDAR_ENTRIES) 22 | .mapNotNull { moshi.adapter(SimpleCalendarEntry::class.java).fromJson(it) } 23 | 24 | return ScheduleWidgetViewsFactory(applicationContext, true, calendarEntries) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/settings/AgeConfirmationDialog.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.settings 2 | 3 | import android.app.Dialog 4 | import android.os.Bundle 5 | import androidx.appcompat.app.AppCompatActivity 6 | import com.afollestad.materialdialogs.MaterialDialog 7 | import me.proxer.app.R 8 | import me.proxer.app.base.BaseDialog 9 | 10 | /** 11 | * @author Ruben Gees 12 | */ 13 | class AgeConfirmationDialog : BaseDialog() { 14 | 15 | companion object { 16 | fun show(activity: AppCompatActivity) = AgeConfirmationDialog() 17 | .show(activity.supportFragmentManager, "age_confirmation_dialog") 18 | } 19 | 20 | override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = MaterialDialog(requireContext()) 21 | .message(R.string.dialog_age_confirmation_content) 22 | .positiveButton(R.string.dialog_age_confirmation_positive) { 23 | preferenceHelper.isAgeRestrictedMediaAllowed = true 24 | } 25 | .negativeButton(R.string.cancel) 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zhanghai/android/materialprogressbar/ThinCircularProgressDrawable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Zhang Hai 3 | * All Rights Reserved. 4 | */ 5 | package me.zhanghai.android.materialprogressbar 6 | 7 | import android.content.Context 8 | import android.graphics.drawable.Drawable 9 | import me.zhanghai.android.materialprogressbar.MaterialProgressBar.DETERMINATE_CIRCULAR_PROGRESS_STYLE_NORMAL 10 | 11 | /** 12 | * Adjusted drawable to make stroke thinner. 13 | * 14 | * @author Ruben Gees 15 | */ 16 | internal class ThinCircularProgressDrawable( 17 | context: Context 18 | ) : BaseProgressLayerDrawable( 19 | arrayOf( 20 | CircularProgressBackgroundDrawable(), 21 | ThinSingleCircularProgressDrawable(DETERMINATE_CIRCULAR_PROGRESS_STYLE_NORMAL), 22 | ThinSingleCircularProgressDrawable(DETERMINATE_CIRCULAR_PROGRESS_STYLE_NORMAL) 23 | ), 24 | context 25 | ) 26 | -------------------------------------------------------------------------------- /src/main/res/values/themes_gloomy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_comments.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15 | 16 | 17 | 18 | 21 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/wrapper/SimpleGlideRequestListener.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util.wrapper 2 | 3 | import com.bumptech.glide.load.DataSource 4 | import com.bumptech.glide.load.engine.GlideException 5 | import com.bumptech.glide.request.RequestListener 6 | import com.bumptech.glide.request.target.Target 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | @Suppress("FunctionOnlyReturningConstant") 12 | interface SimpleGlideRequestListener : RequestListener { 13 | 14 | override fun onLoadFailed( 15 | error: GlideException?, 16 | model: Any?, 17 | target: Target?, 18 | isFirstResource: Boolean 19 | ) = onLoadFailed(error) 20 | 21 | override fun onResourceReady( 22 | resource: R, 23 | model: Any?, 24 | target: Target?, 25 | dataSource: DataSource?, 26 | isFirstResource: Boolean 27 | ) = onResourceReady(resource) 28 | 29 | fun onLoadFailed(error: GlideException?) = false 30 | fun onResourceReady(resource: R) = false 31 | } 32 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/prv/Participant.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.prv 2 | 3 | import android.os.Parcel 4 | import android.os.Parcelable 5 | import me.proxer.app.util.extension.readStringSafely 6 | 7 | /** 8 | * @author Ruben Gees 9 | */ 10 | data class Participant(val username: String, val image: String = "") : Parcelable { 11 | 12 | companion object { 13 | @Suppress("unused") 14 | @JvmField 15 | val CREATOR = object : Parcelable.Creator { 16 | override fun createFromParcel(parcel: Parcel) = Participant(parcel) 17 | override fun newArray(size: Int): Array = arrayOfNulls(size) 18 | } 19 | } 20 | 21 | constructor(parcel: Parcel) : this( 22 | parcel.readStringSafely(), 23 | parcel.readStringSafely() 24 | ) 25 | 26 | override fun writeToParcel(parcel: Parcel, flags: Int) { 27 | parcel.writeString(username) 28 | parcel.writeString(image) 29 | } 30 | 31 | override fun describeContents() = 0 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/settings/status/ServerStatusActivity.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.settings.status 2 | 3 | import android.app.Activity 4 | import android.os.Bundle 5 | import androidx.fragment.app.commitNow 6 | import me.proxer.app.R 7 | import me.proxer.app.base.DrawerActivity 8 | import me.proxer.app.util.extension.startActivity 9 | 10 | /** 11 | * @author Ruben Gees 12 | */ 13 | class ServerStatusActivity : DrawerActivity() { 14 | 15 | companion object { 16 | fun navigateTo(context: Activity) = context.startActivity() 17 | } 18 | 19 | override fun onCreate(savedInstanceState: Bundle?) { 20 | super.onCreate(savedInstanceState) 21 | 22 | title = getString(R.string.section_server_status) 23 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 24 | 25 | if (savedInstanceState == null) { 26 | supportFragmentManager.commitNow { 27 | replace(R.id.container, ServerStatusFragment.newInstance()) 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/ui/view/bbcode/prototype/TextMutatorPrototype.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.ui.view.bbcode.prototype 2 | 3 | import android.text.SpannableStringBuilder 4 | import android.view.View 5 | import android.widget.TextView 6 | import me.proxer.app.ui.view.bbcode.BBArgs 7 | import me.proxer.app.ui.view.bbcode.BBCodeView 8 | import me.proxer.app.ui.view.bbcode.BBTree 9 | import me.proxer.app.ui.view.bbcode.applyToViews 10 | import me.proxer.app.ui.view.bbcode.toSpannableStringBuilder 11 | 12 | /** 13 | * @author Ruben Gees 14 | */ 15 | interface TextMutatorPrototype : BBPrototype { 16 | 17 | override fun makeViews(parent: BBCodeView, children: List, args: BBArgs): List { 18 | val childViews = children.flatMap { it.makeViews(parent, args) } 19 | 20 | return applyToViews(childViews) { view: TextView -> 21 | view.text = mutate(view.text.toSpannableStringBuilder(), args) 22 | } 23 | } 24 | 25 | fun mutate(text: SpannableStringBuilder, args: BBArgs): SpannableStringBuilder 26 | } 27 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_edit_comment_size.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/manga/MangaLinearLayoutManger.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.manga 2 | 3 | import android.content.Context 4 | import androidx.recyclerview.widget.LinearLayoutManager 5 | import androidx.recyclerview.widget.RecyclerView 6 | import me.proxer.app.util.DeviceUtils 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | class MangaLinearLayoutManger( 12 | context: Context, 13 | readerOrientation: MangaReaderOrientation 14 | ) : LinearLayoutManager( 15 | context, 16 | if (readerOrientation == MangaReaderOrientation.VERTICAL) VERTICAL else HORIZONTAL, 17 | readerOrientation == MangaReaderOrientation.RIGHT_TO_LEFT 18 | ) { 19 | 20 | private val extraLayoutSpace = when (readerOrientation) { 21 | MangaReaderOrientation.VERTICAL -> DeviceUtils.getScreenHeight(context) / 2 22 | else -> DeviceUtils.getScreenWidth(context) / 2 23 | } 24 | 25 | init { 26 | isItemPrefetchEnabled = false 27 | } 28 | 29 | override fun getExtraLayoutSpace(state: RecyclerView.State) = extraLayoutSpace 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/chat/prv/sync/MessengerDatabase.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.chat.prv.sync 2 | 3 | import androidx.room.Database 4 | import androidx.room.RoomDatabase 5 | import androidx.room.TypeConverters 6 | import androidx.room.migration.Migration 7 | import androidx.sqlite.db.SupportSQLiteDatabase 8 | import me.proxer.app.chat.prv.LocalConference 9 | import me.proxer.app.chat.prv.LocalMessage 10 | import me.proxer.app.util.converter.RoomConverters 11 | 12 | /** 13 | * @author Ruben Gees 14 | */ 15 | @Suppress("UnnecessaryAbstractClass") 16 | @Database(entities = [LocalConference::class, LocalMessage::class], version = 2) 17 | @TypeConverters(RoomConverters::class) 18 | abstract class MessengerDatabase : RoomDatabase() { 19 | 20 | companion object { 21 | val MIGRATION_1_2 = object : Migration(1, 2) { 22 | override fun migrate(database: SupportSQLiteDatabase) { 23 | // Nothing to do here, needed due to a bug. 24 | } 25 | } 26 | } 27 | 28 | abstract fun dao(): MessengerDao 29 | } 30 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/extension/ProxerRxExtensions.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("NOTHING_TO_INLINE") 2 | 3 | package me.proxer.app.util.extension 4 | 5 | import io.reactivex.Single 6 | import me.proxer.app.exception.PartialException 7 | import me.proxer.app.util.rx.CallResponseSingle 8 | import me.proxer.app.util.rx.CallStringBodySingle 9 | import me.proxer.app.util.rx.ProxerCallNullableSingle 10 | import me.proxer.app.util.rx.ProxerCallSingle 11 | import me.proxer.library.api.Endpoint 12 | import okhttp3.Call 13 | import okhttp3.Response 14 | 15 | inline fun Endpoint.buildSingle() = ProxerCallSingle(build()) 16 | 17 | @JvmName("buildNullableSingle") 18 | inline fun Endpoint.buildSingle() = ProxerCallNullableSingle(build()) 19 | 20 | inline fun Endpoint.buildPartialErrorSingle(input: I): Single = buildSingle() 21 | .onErrorResumeNext { Single.error(PartialException(it, input)) } 22 | 23 | inline fun Call.toSingle(): Single = CallResponseSingle(this) 24 | 25 | inline fun Call.toBodySingle(): Single = CallStringBodySingle(this) 26 | -------------------------------------------------------------------------------- /src/main/res/layout/fragment_manga.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/media/comments/ParsedComment.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.media.comments 2 | 3 | import me.proxer.app.ui.view.bbcode.BBTree 4 | import me.proxer.app.util.extension.toDate 5 | import me.proxer.library.entity.ProxerDateItem 6 | import me.proxer.library.entity.ProxerIdItem 7 | import me.proxer.library.entity.ProxerImageItem 8 | import me.proxer.library.entity.info.RatingDetails 9 | import me.proxer.library.enums.UserMediaProgress 10 | import org.threeten.bp.Instant 11 | 12 | /** 13 | * @author Ruben Gees 14 | */ 15 | data class ParsedComment( 16 | override val id: String, 17 | val entryId: String, 18 | val authorId: String, 19 | val mediaProgress: UserMediaProgress, 20 | val ratingDetails: RatingDetails, 21 | val parsedContent: BBTree, 22 | val overallRating: Int, 23 | val episode: Int, 24 | val helpfulVotes: Int, 25 | val instant: Instant, 26 | val author: String, 27 | override val image: String 28 | ) : ProxerIdItem, ProxerImageItem, ProxerDateItem { 29 | 30 | @Transient 31 | override val date = instant.toDate() 32 | } 33 | -------------------------------------------------------------------------------- /src/main/res/layout/layout_about_row.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/res/layout/item_stream_message.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/res/layout/layout_media_info_row.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/res/menu/fragment_chat_cab.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 22 | 23 | 31 | 32 | -------------------------------------------------------------------------------- /.github/workflows/publish-to-discord.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | CHANGELOG=$(git log --pretty=format:"- %s" "${COMMIT_RANGE:1:-1}" --reverse) 5 | 6 | if [[ ${DISCORD_WEBHOOK_URL:+1} ]]; then 7 | FILE="$(find ./build/outputs/apk/logRelease/ -type f -name "*.apk")" 8 | FILENAME="$(basename "$FILE")" 9 | 10 | echo "Uploading apk..." 11 | 12 | DOWNLOAD_URL=$(curl --silent --show-error --fail "$UPLOAD_URL" --form "apk=@$FILE") 13 | 14 | echo "Publishing apk..." 15 | echo "$CHANGELOG" 16 | 17 | curl --silent --show-error --fail --request POST \ 18 | "$DISCORD_WEBHOOK_URL" \ 19 | --header 'Content-Type: application/json' \ 20 | --data '{ 21 | "embeds": [ 22 | { 23 | "title": "'"$FILENAME"'", 24 | "url": "'"$DOWNLOAD_URL"'", 25 | "description": "'"${CHANGELOG//$'\n'/\\n}"'", 26 | "color": "9047566" 27 | } 28 | ] 29 | }' 30 | 31 | unset FILE 32 | unset FILENAME 33 | unset DOWNLOAD_URL 34 | else 35 | echo "DISCORD_WEBHOOK_URL not set." 36 | exit 1 37 | fi 38 | 39 | unset CHANGELOG 40 | -------------------------------------------------------------------------------- /src/main/kotlin/me/proxer/app/util/ActivityUtils.kt: -------------------------------------------------------------------------------- 1 | package me.proxer.app.util 2 | 3 | import android.app.Activity 4 | import android.content.Intent 5 | import android.widget.ImageView 6 | import androidx.core.app.ActivityOptionsCompat 7 | 8 | /** 9 | * @author Ruben Gees 10 | */ 11 | object ActivityUtils { 12 | 13 | private const val TRANSITION_NAME_EXTRA = "transition_name" 14 | 15 | fun navigateToWithImageTransition(intent: Intent, context: Activity, imageView: ImageView?) { 16 | if (imageView?.drawable != null) { 17 | intent.putExtra(TRANSITION_NAME_EXTRA, imageView.transitionName) 18 | 19 | context.startActivity( 20 | intent, 21 | ActivityOptionsCompat.makeSceneTransitionAnimation( 22 | context, 23 | imageView, 24 | imageView.transitionName 25 | ).toBundle() 26 | ) 27 | } else { 28 | context.startActivity(intent) 29 | } 30 | } 31 | 32 | fun getTransitionName(context: Activity): String? = context.intent.getStringExtra(TRANSITION_NAME_EXTRA) 33 | } 34 | -------------------------------------------------------------------------------- /src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 21 |