├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── extension-okhttp-2.10.8.aar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── net
│ │ └── xblacky
│ │ └── animexstream
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-playstore.png
│ ├── java
│ │ └── net
│ │ │ └── vapormusic
│ │ │ └── animexstream
│ │ │ ├── AnimeXStream.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── Private.kt
│ │ │ ├── SplashActivity.kt
│ │ │ ├── Tls12SocketFactory.java
│ │ │ ├── enableTls12OnPreLollipop.java
│ │ │ ├── ui
│ │ │ └── main
│ │ │ │ ├── animeinfo
│ │ │ │ ├── AnimeInfoFragment.kt
│ │ │ │ ├── AnimeInfoRepository.kt
│ │ │ │ ├── AnimeInfoViewModel.kt
│ │ │ │ ├── AnimeInfoViewModelFactory.kt
│ │ │ │ └── epoxy
│ │ │ │ │ ├── AnimeInfoController.kt
│ │ │ │ │ └── AnimeInfoModels.kt
│ │ │ │ ├── favourites
│ │ │ │ ├── FavouriteFragment.kt
│ │ │ │ ├── FavouriteRepository.kt
│ │ │ │ ├── FavouriteViewModel.kt
│ │ │ │ └── epoxy
│ │ │ │ │ ├── FavouriteController.kt
│ │ │ │ │ └── FavouriteModel.kt
│ │ │ │ ├── home
│ │ │ │ ├── HomeFragment.kt
│ │ │ │ ├── HomeRepository.kt
│ │ │ │ ├── HomeViewModel.kt
│ │ │ │ └── epoxy
│ │ │ │ │ ├── EpoxyHomeModel.kt
│ │ │ │ │ └── HomeController.kt
│ │ │ │ ├── mal
│ │ │ │ └── LoginFragment.kt
│ │ │ │ ├── player
│ │ │ │ ├── EpisodeRepository.kt
│ │ │ │ ├── ModifyGestureDetector.java
│ │ │ │ ├── OnSwipeTouchListener.kt
│ │ │ │ ├── VideoPlayerActivity.kt
│ │ │ │ ├── VideoPlayerFragment.kt
│ │ │ │ └── VideoPlayerViewModel.kt
│ │ │ │ ├── search
│ │ │ │ ├── SearchFragment.kt
│ │ │ │ ├── SearchRepository.kt
│ │ │ │ ├── SearchViewModel.kt
│ │ │ │ ├── adapter
│ │ │ │ │ ├── Suggestions.kt
│ │ │ │ │ └── SuggestionsAdapter.kt
│ │ │ │ └── epoxy
│ │ │ │ │ └── SearchController.kt
│ │ │ │ └── settings
│ │ │ │ └── SettingsFragment.kt
│ │ │ └── utils
│ │ │ ├── CommonViewModel.kt
│ │ │ ├── CommonViewModel2.kt
│ │ │ ├── ItemOffsetDecoration.kt
│ │ │ ├── Tags
│ │ │ └── GenreTags.kt
│ │ │ ├── Utils.kt
│ │ │ ├── connectivity
│ │ │ ├── ConnectivityProviderImpl.kt
│ │ │ ├── ConnectivityProviderLegacyImpl.kt
│ │ │ └── base
│ │ │ │ ├── ConnectivityProvider.kt
│ │ │ │ └── ConnectivityProviderBaseImpl.kt
│ │ │ ├── constants
│ │ │ └── C.kt
│ │ │ ├── epoxy
│ │ │ └── CommonModel.kt
│ │ │ ├── helper
│ │ │ └── WatchedEpisode.kt
│ │ │ ├── mal
│ │ │ └── PkceGenerator.kt
│ │ │ ├── model
│ │ │ ├── AnimeInfoModel.kt
│ │ │ ├── AnimeMetaModel.kt
│ │ │ ├── Content.kt
│ │ │ ├── EpisodeInfo.kt
│ │ │ ├── EpisodeModel.kt
│ │ │ ├── ErrorModel.kt
│ │ │ ├── FavouriteModel.kt
│ │ │ ├── GenreModel.kt
│ │ │ ├── HomeScreenModel.kt
│ │ │ ├── LoadingModel2.kt
│ │ │ ├── MALModel
│ │ │ │ └── UserAnimeList
│ │ │ │ │ ├── Datum.java
│ │ │ │ │ ├── ListStatus.java
│ │ │ │ │ ├── MainPicture.java
│ │ │ │ │ ├── Node.java
│ │ │ │ │ ├── Paging.java
│ │ │ │ │ └── UserAnimeList.java
│ │ │ ├── PaheModel
│ │ │ │ ├── ResolutionURLs
│ │ │ │ │ ├── Datum.java
│ │ │ │ │ ├── ResolutionURLs.java
│ │ │ │ │ ├── _1080.java
│ │ │ │ │ ├── _360.java
│ │ │ │ │ ├── _480.java
│ │ │ │ │ └── _720.java
│ │ │ │ └── SessionURLs
│ │ │ │ │ ├── Data.java
│ │ │ │ │ └── SessionsURLs.java
│ │ │ ├── SettingsModel.kt
│ │ │ ├── SuggestionModel.kt
│ │ │ ├── UpdateModel.kt
│ │ │ └── WatchedEpisode.kt
│ │ │ ├── parser
│ │ │ └── HtmlParser.kt
│ │ │ ├── realm
│ │ │ └── InitalizeRealm.kt
│ │ │ └── rertofit
│ │ │ ├── NetworkInterface.kt
│ │ │ └── RetrofitHelper.java
│ └── res
│ │ ├── drawable-night
│ │ └── stream.png
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_arrow.xml
│ │ ├── ic_baseline_brightness_3_24.xml
│ │ ├── ic_baseline_home_24.xml
│ │ ├── ic_baseline_settings.xml
│ │ ├── ic_baseline_settings_24.xml
│ │ ├── ic_brightness.xml
│ │ ├── ic_error.xml
│ │ ├── ic_favorite.xml
│ │ ├── ic_file_download_24px.xml
│ │ ├── ic_internet.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_media_pause.xml
│ │ ├── ic_media_play.xml
│ │ ├── ic_media_seek_backward.xml
│ │ ├── ic_media_seek_forward.xml
│ │ ├── ic_play_button.xml
│ │ ├── ic_search.xml
│ │ ├── ic_unfavorite.xml
│ │ ├── ic_volume.xml
│ │ ├── list_selector_background.xml
│ │ ├── search_edit_text_background.xml
│ │ ├── shadow_backgorund.xml
│ │ ├── shape_sub_dub.xml
│ │ ├── splash_drawable.xml
│ │ └── stream.png
│ │ ├── layout
│ │ ├── activity_video_player.xml
│ │ ├── error_screen_video_player.xml
│ │ ├── exo_player_custom_controls.xml
│ │ ├── fragment_animeinfo.xml
│ │ ├── fragment_favourite.xml
│ │ ├── fragment_home.xml
│ │ ├── fragment_search.xml
│ │ ├── fragment_settings.xml
│ │ ├── fragment_video_player.xml
│ │ ├── fragment_video_player_placeholder.xml
│ │ ├── loading.xml
│ │ ├── main_activity.xml
│ │ ├── recycler_anime_common.xml
│ │ ├── recycler_anime_mini_header.xml
│ │ ├── recycler_anime_popular.xml
│ │ ├── recycler_anime_recent_sub_dub_2.xml
│ │ ├── recycler_episode_item.xml
│ │ ├── recycler_loading.xml
│ │ ├── tags_genre.xml
│ │ └── web_view.xml
│ │ ├── menu
│ │ └── bottom_navigation_menu.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── navigation
│ │ └── app_navigation.xml
│ │ ├── values-es
│ │ └── strings.xml
│ │ ├── values-night
│ │ └── colors.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ ├── motion_scene.xml
│ │ ├── motion_scene_animeinfo.xml
│ │ └── motion_scene_favourites.xml
│ └── test
│ └── java
│ └── net
│ └── xblacky
│ └── animexstream
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── meta
└── android
│ ├── animexstream.png
│ ├── download.png
│ └── screenshots
│ ├── screenshot_01.jpg
│ ├── screenshot_02.jpg
│ ├── screenshot_03.jpg
│ ├── screenshot_04.jpg
│ ├── screenshot_05.jpg
│ ├── screenshot_06.jpg
│ ├── screenshot_07.jpg
│ ├── screenshot_08.jpg
│ ├── screenshot_09.jpg
│ ├── screenshot_10.jpg
│ ├── screenshot_11.jpg
│ └── screenshot_12.jpg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | .idea
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Mukul Banga
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |

2 | Anime X Stream
3 | An Android app to watch anime on your phone without ads.
4 | 
5 |
6 |
7 |
8 |
9 |
10 |
11 | WARNING: THIS IS A BETA VERSION of application, THEREFORE YOU MAY ENCOUNTER BUGS. You can OPEN the ISSUE on GITHUB REPOSITORY.
12 |
13 |
Do not PUT ANIME X STREAM OR ANY FORK OF IT INTO GOOGLE PLAYSTORE or Any other Store. It may VIOLATE THEIR TERMS AND CONDITIONS or you may encounter legal obligations.
14 |
15 | **Star :star: this repo to show your support and it really does matter!** :clap:
16 |
17 | ## Screenshots
18 |
19 | [
](meta/android/screenshots/screenshot_01.jpg)
20 | [
](meta/android/screenshots/screenshot_02.jpg)
21 | [
](meta/android/screenshots/screenshot_03.jpg)
22 | [
](meta/android/screenshots/screenshot_04.jpg)
23 | [
](meta/android/screenshots/screenshot_05.jpg)
24 | [
](meta/android/screenshots/screenshot_06.jpg)
25 | [
](meta/android/screenshots/screenshot_07.jpg)
26 | [
](meta/android/screenshots/screenshot_08.jpg)
27 | [
](meta/android/screenshots/screenshot_09.jpg)
28 | [
](meta/android/screenshots/screenshot_10.jpg)
29 | [
](meta/android/screenshots/screenshot_11.jpg)
30 | [
](meta/android/screenshots/screenshot_12.jpg)
31 |
32 |
33 | ## Description
34 |
35 | Anime X Stream parses website data and filter required info, thus It removes the ads for seamless experience. The app doesn't require account creation to use it.
36 |
37 | ### Features
38 |
39 | * Search Anime
40 | * Recently Added Episodes
41 | * Popular Animes
42 | * Anime Movies
43 | * Watch Progress
44 | * Add To Favourites
45 | * Auto Quality for Video Playback
46 | * Video Player Volume/Brightness Control
47 | * Ads Free Video Placback
48 | * Directly skip to next/previous episode from player.
49 | * Dark Mode Support
50 | * MyAnimeList watched progress syncing (Will require Login)
51 |
52 | ### Coming Features
53 |
54 | * Different list of Popular/ Recent / Movies
55 | * … and many more
56 |
57 | ### Technologies used
58 | * Kotlin
59 | * MVVM
60 | * Retrofit & RxJava
61 | * Epoxy
62 | * ExoPlayer
63 | * Android Architecture Components
64 | * Glide
65 | * Apache Commons
66 | * Rhino
67 |
68 | ## Contribution
69 | Your ideas, translations, design changes, code cleaning, or real heavy code changes or any help is always welcome. The more is contribution the better it gets
70 |
71 | [Pull requests](https://github.com/VaporMusic/AnimeXStream/pulls) will be reviewed
72 |
73 | #### Known issues and limitations
74 | - Last Episode Progress not showing when getting back from player.
75 | - Keyboard not showing sometimes for search
76 | - No error and loading screen for Home, Search, Favourites Fragment
77 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | google-services.json
3 | /src/main/java/net/blacky/animexstream/Private.kt
--------------------------------------------------------------------------------
/app/libs/extension-okhttp-2.10.8.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/libs/extension-okhttp-2.10.8.aar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/net/xblacky/animexstream/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("net.vapormusic.animexstream", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/AnimeXStream.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream
2 |
3 | import android.app.Application
4 | import androidx.appcompat.app.AppCompatDelegate
5 | import androidx.multidex.MultiDexApplication
6 | import io.realm.Realm
7 | import net.vapormusic.animexstream.utils.model.SettingsModel
8 | import net.vapormusic.animexstream.utils.realm.InitalizeRealm
9 | import timber.log.Timber
10 | import java.security.Security
11 | import org.conscrypt.Conscrypt
12 |
13 | class AnimeXStream : MultiDexApplication() {
14 |
15 | override fun onCreate() {
16 | super.onCreate()
17 | Security.insertProviderAt(Conscrypt.newProvider(), 1)
18 | AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
19 | InitalizeRealm.initializeRealm(this)
20 |
21 |
22 | if (BuildConfig.DEBUG) {
23 | Timber.plant(Timber.DebugTree())
24 | }
25 | }
26 |
27 |
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/Private.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream
2 |
3 | class Private {
4 | companion object{
5 | val MAL_CLIENT_ID : String = "df368c0b8286b739ee77f0b905960700"
6 | }
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/SplashActivity.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import androidx.appcompat.app.AppCompatActivity
6 |
7 |
8 | class SplashActivity : AppCompatActivity(){
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | val mainIntent = Intent(this, MainActivity::class.java)
12 | startActivity(mainIntent)
13 | finish()
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/Tls12SocketFactory.java:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream;
2 |
3 | import java.io.IOException;
4 | import java.net.InetAddress;
5 | import java.net.Socket;
6 | import java.net.UnknownHostException;
7 |
8 | import javax.net.ssl.SSLSocket;
9 | import javax.net.ssl.SSLSocketFactory;
10 |
11 | /**
12 | * Enables TLS v1.2 when creating SSLSockets.
13 | *
14 | * For some reason, android supports TLS v1.2 from API 16, but enables it by
15 | * default only from API 20.
16 | * @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
17 | * @see SSLSocketFactory
18 | */
19 | public class Tls12SocketFactory extends SSLSocketFactory {
20 | private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
21 |
22 | final SSLSocketFactory delegate;
23 |
24 | public Tls12SocketFactory(SSLSocketFactory base) {
25 | this.delegate = base;
26 | }
27 |
28 | @Override
29 | public String[] getDefaultCipherSuites() {
30 | return delegate.getDefaultCipherSuites();
31 | }
32 |
33 | @Override
34 | public String[] getSupportedCipherSuites() {
35 | return delegate.getSupportedCipherSuites();
36 | }
37 |
38 | @Override
39 | public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
40 | return patch(delegate.createSocket(s, host, port, autoClose));
41 | }
42 |
43 | @Override
44 | public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
45 | return patch(delegate.createSocket(host, port));
46 | }
47 |
48 | @Override
49 | public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
50 | return patch(delegate.createSocket(host, port, localHost, localPort));
51 | }
52 |
53 | @Override
54 | public Socket createSocket(InetAddress host, int port) throws IOException {
55 | return patch(delegate.createSocket(host, port));
56 | }
57 |
58 | @Override
59 | public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
60 | return patch(delegate.createSocket(address, port, localAddress, localPort));
61 | }
62 |
63 | private Socket patch(Socket s) {
64 | if (s instanceof SSLSocket) {
65 | ((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
66 | }
67 | return s;
68 | }
69 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/enableTls12OnPreLollipop.java:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream;
2 |
3 | import android.os.Build;
4 | import android.util.Log;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import javax.net.ssl.SSLContext;
10 |
11 | import okhttp3.CipherSuite;
12 | import okhttp3.ConnectionSpec;
13 | import okhttp3.OkHttpClient;
14 | import okhttp3.TlsVersion;
15 |
16 | public class enableTls12OnPreLollipop{
17 | public OkHttpClient.Builder enableTls12OnPreLollipop2(OkHttpClient.Builder client) {
18 | if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
19 | try {
20 | SSLContext sc = SSLContext.getInstance("TLSv1.2");
21 | sc.init(null, null, null);
22 | client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));
23 |
24 | ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
25 | .tlsVersions(TlsVersion.TLS_1_2)
26 | .cipherSuites(
27 | CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
28 | CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
29 | CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
30 | CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
31 | CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
32 | CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
33 | CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
34 | CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
35 | CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
36 | CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
37 | CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
38 | CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
39 | .build();
40 |
41 | List specs = new ArrayList<>();
42 | specs.add(cs);
43 | specs.add(ConnectionSpec.COMPATIBLE_TLS);
44 | specs.add(ConnectionSpec.CLEARTEXT);
45 |
46 |
47 | client.connectionSpecs(specs);
48 | } catch (Exception exc) {
49 | Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
50 | }
51 | }
52 |
53 | return client;
54 | }
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/animeinfo/AnimeInfoViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.animeinfo
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import retrofit2.http.Url
6 | import java.lang.IllegalArgumentException
7 |
8 | class AnimeInfoViewModelFactory(private val categoryUrl: String) : ViewModelProvider.Factory {
9 | override fun create(modelClass: Class): T {
10 | if(modelClass.isAssignableFrom(AnimeInfoViewModel::class.java)){
11 | return AnimeInfoViewModel(categoryUrl = categoryUrl) as T
12 | }
13 | throw IllegalArgumentException("Unknown ViewModel Class")
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/animeinfo/epoxy/AnimeInfoController.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.animeinfo.epoxy
2 |
3 | import android.content.Intent
4 | import android.view.View
5 | import androidx.lifecycle.MutableLiveData
6 | import com.airbnb.epoxy.TypedEpoxyController
7 | import io.reactivex.disposables.CompositeDisposable
8 | import io.reactivex.observers.DisposableObserver
9 | import net.vapormusic.animexstream.ui.main.animeinfo.AnimeInfoRepository
10 | import net.vapormusic.animexstream.ui.main.player.VideoPlayerActivity
11 | import net.vapormusic.animexstream.utils.model.AnimeInfoModel
12 | import net.vapormusic.animexstream.utils.model.EpisodeModel
13 | import net.vapormusic.animexstream.utils.model.FavouriteModel
14 | import net.vapormusic.animexstream.utils.rertofit.NetworkInterface
15 | import okhttp3.ResponseBody
16 | import org.json.JSONObject
17 | import timber.log.Timber
18 |
19 | class AnimeInfoController : TypedEpoxyController>(){
20 | var animeName: String = ""
21 | var MALAnimeID: String? = ""
22 | private lateinit var isWatchedHelper: net.vapormusic.animexstream.utils.helper.WatchedEpisode
23 | private var _animeInfoModel: MutableLiveData = MutableLiveData()
24 | override fun buildModels(data: ArrayList?) {
25 | data?.forEach {
26 | EpisodeModel_()
27 | .id(it.episodeurl)
28 | .episodeModel(it)
29 | .clickListener { model, _, clickedView, _ ->
30 | startVideoActivity(model.episodeModel(),clickedView)
31 | }
32 | .spanSizeOverride { totalSpanCount, _, _ ->
33 | totalSpanCount/totalSpanCount
34 | }
35 | .watchedProgress(isWatchedHelper.getWatchedDuration(it.episodeurl.hashCode()))
36 | .addTo(this)
37 | }
38 |
39 | }
40 |
41 | fun setAnime(animeName: String){
42 | this.animeName = animeName
43 | isWatchedHelper = net.vapormusic.animexstream.utils.helper.WatchedEpisode(animeName)
44 | }
45 |
46 | fun setMALID( animeName: String){
47 | val animeInfoRepository = AnimeInfoRepository()
48 | CompositeDisposable().add(
49 | animeInfoRepository.MALAnimeID(animeName).subscribeWith(MALAnimeIDObserver())
50 | )
51 | }
52 |
53 | private fun MALAnimeIDObserver(): DisposableObserver {
54 | return object : DisposableObserver() {
55 | override fun onNext(t: ResponseBody) {
56 | val obj = JSONObject(t.string())
57 | val array = obj.getJSONArray("results")
58 | MALAnimeID= array.getJSONObject(0).getString("mal_id")
59 |
60 | Timber.e("mal id 2: " + MALAnimeID)
61 |
62 | }
63 |
64 | override fun onComplete() {
65 |
66 | }
67 |
68 | override fun onError(e: Throwable) {
69 | }
70 |
71 | }}
72 |
73 | fun isWatchedHelperUpdated():Boolean{
74 | return ::isWatchedHelper.isInitialized
75 | }
76 |
77 | private fun startVideoActivity(episodeModel: EpisodeModel, clickedView: View){
78 | val intent = Intent(clickedView.context, VideoPlayerActivity::class.java)
79 | intent.putExtra("episodeUrl",episodeModel.episodeurl)
80 | intent.putExtra("episodeNumber",episodeModel.episodeNumber)
81 | intent.putExtra("animeName",animeName)
82 | intent.putExtra("MALID",MALAnimeID)
83 | Timber.e("mal id 2: " + MALAnimeID)
84 | // intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK
85 | clickedView.context.startActivity(intent)
86 | }
87 |
88 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/animeinfo/epoxy/AnimeInfoModels.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.animeinfo.epoxy
2 |
3 | import android.graphics.Color
4 | import android.graphics.PorterDuff
5 | import android.os.Build
6 | import android.view.View
7 | import android.widget.FrameLayout
8 | import android.widget.ProgressBar
9 | import android.widget.TextView
10 | import androidx.cardview.widget.CardView
11 | import androidx.core.content.ContextCompat
12 | import androidx.core.content.res.ResourcesCompat
13 | import androidx.core.graphics.drawable.DrawableCompat
14 | import com.airbnb.epoxy.EpoxyAttribute
15 | import com.airbnb.epoxy.EpoxyHolder
16 | import com.airbnb.epoxy.EpoxyModelClass
17 | import com.airbnb.epoxy.EpoxyModelWithHolder
18 | import kotlinx.android.synthetic.main.recycler_episode_item.view.*
19 | import net.vapormusic.animexstream.R
20 |
21 |
22 |
23 | @EpoxyModelClass(layout = R.layout.recycler_episode_item)
24 | abstract class EpisodeModel : EpoxyModelWithHolder(){
25 |
26 | @EpoxyAttribute
27 | lateinit var episodeModel: net.vapormusic.animexstream.utils.model.EpisodeModel
28 | @EpoxyAttribute
29 | lateinit var clickListener: View.OnClickListener
30 | @EpoxyAttribute
31 | var watchedProgress: Long = 0
32 |
33 |
34 | override fun bind(holder: HomeHeaderHolder) {
35 | super.bind(holder)
36 |
37 | holder.episodeText.text = episodeModel.episodeNumber
38 | holder.cardView.setOnClickListener(clickListener)
39 | holder.progressBar.progress = if(watchedProgress >90) 100 else if(watchedProgress in 1..10) 10 else watchedProgress.toInt()
40 | holder.cardView.setCardBackgroundColor(
41 | ResourcesCompat.getColor(
42 | holder.cardView.resources,
43 | R.color.episode_background,
44 | null
45 | )
46 | )
47 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
48 | holder.progressBar.getProgressDrawable().setColorFilter(ResourcesCompat.getColor(holder.progress_color.resources, R.color.progress, null), PorterDuff.Mode.SRC_IN);
49 | }
50 | }
51 |
52 | class HomeHeaderHolder : EpoxyHolder(){
53 | lateinit var episodeText: TextView
54 | lateinit var cardView: CardView
55 | lateinit var progressBar: ProgressBar
56 | lateinit var progress_color : FrameLayout
57 |
58 | override fun bindView(itemView: View) {
59 | episodeText = itemView.episodeNumber
60 | cardView = itemView.cardView
61 | progressBar = itemView.watchedProgress
62 | progress_color = itemView.progress_color
63 | }
64 | }
65 |
66 |
67 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/favourites/FavouriteRepository.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.favourites
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.android.schedulers.AndroidSchedulers
5 | import io.reactivex.schedulers.Schedulers
6 | import io.realm.Realm
7 | import net.vapormusic.animexstream.utils.realm.InitalizeRealm
8 | import net.vapormusic.animexstream.utils.rertofit.NetworkInterface
9 | import net.vapormusic.animexstream.utils.rertofit.RetrofitHelper
10 | import okhttp3.ResponseBody
11 |
12 | class FavouriteRepository{
13 | private val retrofit = RetrofitHelper.getRetrofitInstance()
14 | private val realm = Realm.getInstance(InitalizeRealm.getConfig())
15 |
16 | fun fetchMALFavoriteList(access_token: String): Observable {
17 | val animeInfoService = retrofit.create(NetworkInterface.MALGetFavoriteList::class.java)
18 | return animeInfoService.get(access_token = "Bearer "+ access_token).subscribeOn(Schedulers.io()).observeOn(
19 | AndroidSchedulers.mainThread())
20 | }
21 |
22 | fun SetMALFavorite(access_token: String, mal_id: String): Observable {
23 | val animeEpisodeService = retrofit.create(NetworkInterface.MALSetFavorite::class.java)
24 | return animeEpisodeService.get(access_token = "Bearer "+ access_token, anime_id = mal_id).subscribeOn(
25 | Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
26 | }
27 |
28 | fun DeleteMALFavorite(access_token: String, mal_id: String): Observable {
29 |
30 | val animeEpisodeService = retrofit.create(NetworkInterface.MALRemoveFavorite::class.java)
31 | return animeEpisodeService.get(access_token = "Bearer "+ access_token, anime_id = mal_id)
32 | .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/favourites/FavouriteViewModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.favourites
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import io.realm.Realm
7 | import io.realm.RealmResults
8 | import io.realm.Sort
9 | import net.vapormusic.animexstream.utils.model.FavouriteModel
10 | import net.vapormusic.animexstream.utils.realm.InitalizeRealm
11 |
12 | class FavouriteViewModel : ViewModel() {
13 |
14 | private lateinit var result: RealmResults
15 | private val realm = Realm.getInstance(InitalizeRealm.getConfig())
16 | private val _favouriteLists: MutableLiveData> =
17 | MutableLiveData(ArrayList())
18 | var favouriteList: LiveData> = _favouriteLists
19 | init {
20 | favouriteListListener()
21 | }
22 |
23 | private fun favouriteListListener() {
24 | result = realm.where(FavouriteModel::class.java).sort("insertionTime", Sort.DESCENDING).findAll()
25 | _favouriteLists.value = realm.copyFromRealm(result) as ArrayList?
26 | result.addChangeListener { newList ->
27 | _favouriteLists.value = realm.copyFromRealm(newList) as ArrayList?
28 | }
29 |
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/favourites/epoxy/FavouriteController.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.favourites.epoxy
2 |
3 | import com.airbnb.epoxy.TypedEpoxyController
4 | import net.vapormusic.animexstream.utils.model.AnimeMetaModel
5 | import net.vapormusic.animexstream.utils.model.FavouriteModel
6 |
7 | class FavouriteController(private var adapterCallbacks: EpoxySearchAdapterCallbacks) :
8 | TypedEpoxyController>() {
9 | override fun buildModels(data: ArrayList?) {
10 | data?.let { arrayList ->
11 | arrayList.forEach {
12 |
13 | FavouriteModel_()
14 | .id(it.ID)
15 | .favouriteModel(it)
16 | .spanSizeOverride { totalSpanCount, _, _ -> totalSpanCount / totalSpanCount }
17 | .clickListener { model, _, _, _ ->
18 | adapterCallbacks.animeTitleClick(model = model.favouriteModel())
19 | }
20 | .addTo(this)
21 | }
22 | }
23 | }
24 |
25 | interface EpoxySearchAdapterCallbacks {
26 | fun animeTitleClick(model: FavouriteModel)
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/favourites/epoxy/FavouriteModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.favourites.epoxy
2 |
3 | import android.view.View
4 | import android.widget.TextView
5 | import androidx.appcompat.widget.AppCompatImageView
6 | import androidx.constraintlayout.widget.ConstraintLayout
7 | import com.airbnb.epoxy.EpoxyAttribute
8 | import com.airbnb.epoxy.EpoxyHolder
9 | import com.airbnb.epoxy.EpoxyModelClass
10 | import com.airbnb.epoxy.EpoxyModelWithHolder
11 | import com.bumptech.glide.Glide
12 | import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
13 | import kotlinx.android.synthetic.main.recycler_anime_common.view.*
14 | import net.vapormusic.animexstream.R
15 | import net.vapormusic.animexstream.utils.model.AnimeMetaModel
16 |
17 | @EpoxyModelClass(layout = R.layout.recycler_anime_common)
18 | abstract class FavouriteModel : EpoxyModelWithHolder(){
19 |
20 | @EpoxyAttribute
21 | lateinit var favouriteModel: net.vapormusic.animexstream.utils.model.FavouriteModel
22 | @EpoxyAttribute
23 | var clickListener: View.OnClickListener? = null
24 |
25 | override fun bind(holder: MovieHolder) {
26 | Glide.with(holder.animeImageView.context).load(favouriteModel.imageUrl).transition(
27 | DrawableTransitionOptions.withCrossFade()).into(holder.animeImageView)
28 | holder.animeTitle.text = favouriteModel.animeName
29 | favouriteModel.releasedDate?.let {
30 | val text = "Released: $it"
31 | holder.releasedDate.text = text
32 | }
33 | holder.root.setOnClickListener(clickListener)
34 |
35 | }
36 | class MovieHolder : EpoxyHolder(){
37 |
38 | lateinit var animeImageView: AppCompatImageView
39 | lateinit var animeTitle: TextView
40 | lateinit var releasedDate: TextView
41 | lateinit var root: ConstraintLayout
42 |
43 | override fun bindView(itemView: View) {
44 | animeImageView = itemView.animeImage
45 | animeTitle = itemView.animeTitle
46 | releasedDate = itemView.releasedDate
47 | root = itemView.root
48 | }
49 |
50 | }
51 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/home/HomeRepository.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.home
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.android.schedulers.AndroidSchedulers
5 | import io.reactivex.schedulers.Schedulers
6 | import io.realm.Realm
7 | import io.realm.Sort
8 | import net.vapormusic.animexstream.utils.constants.C
9 | import net.vapormusic.animexstream.utils.rertofit.NetworkInterface
10 | import net.vapormusic.animexstream.utils.rertofit.RetrofitHelper
11 | import net.vapormusic.animexstream.utils.model.AnimeMetaModel
12 | import net.vapormusic.animexstream.utils.realm.InitalizeRealm
13 | import okhttp3.ResponseBody
14 | import retrofit2.Retrofit
15 |
16 | class HomeRepository {
17 | private var retrofit: Retrofit = RetrofitHelper.getRetrofitInstance()!!
18 |
19 |
20 | fun fetchRecentSubOrDub(page: Int, type: Int): Observable {
21 | val fetchHomeListService = retrofit.create(NetworkInterface.FetchRecentSubOrDub::class.java)
22 | return fetchHomeListService.get(page, type).subscribeOn(Schedulers.io())
23 | .observeOn(AndroidSchedulers.mainThread())
24 | }
25 |
26 | fun fetchPopularFromAjax(page: Int): Observable {
27 | val fetchPopularListService =
28 | retrofit.create(NetworkInterface.FetchPopularFromAjax::class.java)
29 | return fetchPopularListService.get(page).subscribeOn(Schedulers.io())
30 | .observeOn(AndroidSchedulers.mainThread())
31 | }
32 |
33 | fun fetchMovies(page: Int): Observable {
34 | val fetchMoviesListService = retrofit.create(NetworkInterface.FetchMovies::class.java)
35 | return fetchMoviesListService.get(page).subscribeOn(Schedulers.io())
36 | .observeOn(AndroidSchedulers.mainThread())
37 | }
38 |
39 | fun fetchNewestAnime(page: Int): Observable {
40 | val fetchNewestSeasonService =
41 | retrofit.create(NetworkInterface.FetchNewestSeason::class.java)
42 | return fetchNewestSeasonService.get(page).subscribeOn(Schedulers.io())
43 | .observeOn(AndroidSchedulers.mainThread())
44 | }
45 |
46 | fun addDataInRealm(animeList: ArrayList) {
47 | val realm: Realm = Realm.getInstance(InitalizeRealm.getConfig())
48 |
49 | try {
50 | realm.executeTransaction { realm1: Realm ->
51 | realm1.insertOrUpdate(animeList)
52 | }
53 | } catch (ignored: Exception) {
54 | }
55 | }
56 |
57 | fun removeFromRealm(){
58 | val realm: Realm = Realm.getInstance(InitalizeRealm.getConfig())
59 |
60 | realm.executeTransaction{
61 | val results = it.where(AnimeMetaModel::class.java).lessThanOrEqualTo("timestamp", System.currentTimeMillis() - C.MAX_TIME_FOR_ANIME).findAll()
62 | results.deleteAllFromRealm()
63 | }
64 | }
65 |
66 | fun fetchFromRealm(typeValue: Int): ArrayList {
67 | val realm: Realm = Realm.getInstance(InitalizeRealm.getConfig())
68 |
69 |
70 | val list: ArrayList = ArrayList()
71 | try {
72 | val results =
73 | realm.where(AnimeMetaModel::class.java)?.equalTo("typeValue", typeValue)?.sort("insertionOrder", Sort.ASCENDING)?.findAll()
74 | results?.let {
75 | list.addAll(it)
76 | }
77 |
78 |
79 | } catch (ignored: Exception) {
80 | }
81 | return list
82 | }
83 |
84 |
85 |
86 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/home/epoxy/HomeController.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.home.epoxy
2 |
3 | import android.view.View
4 | import com.airbnb.epoxy.Carousel
5 | import com.airbnb.epoxy.Carousel.setDefaultGlobalSnapHelperFactory
6 | import com.airbnb.epoxy.CarouselModel_
7 | import com.airbnb.epoxy.TypedEpoxyController
8 | import net.vapormusic.animexstream.R
9 | import net.vapormusic.animexstream.utils.constants.C
10 | import net.vapormusic.animexstream.utils.epoxy.AnimeCommonModel_
11 | import net.vapormusic.animexstream.utils.model.AnimeMetaModel
12 | import net.vapormusic.animexstream.utils.model.HomeScreenModel
13 |
14 |
15 | class HomeController(var adapterCallbacks: EpoxyAdapterCallbacks) : TypedEpoxyController>() {
16 |
17 |
18 | override fun buildModels(data: ArrayList) {
19 |
20 |
21 | data.forEach { homeScreenModel ->
22 |
23 | AnimeMiniHeaderModel_()
24 | .id(homeScreenModel.typeValue)
25 | .typeName(homeScreenModel.type)
26 | .addIf(!homeScreenModel.animeList.isNullOrEmpty(),this)
27 |
28 |
29 |
30 | when (homeScreenModel.typeValue) {
31 |
32 | C.TYPE_MOVIE, C.TYPE_NEW_SEASON -> {
33 | val movieModelList: ArrayList = ArrayList()
34 | homeScreenModel.animeList?.forEach {
35 | val animeMetaModel = it
36 |
37 | movieModelList.add(
38 | AnimeCommonModel_()
39 | .id(animeMetaModel.ID)
40 | .clickListener { model, _, _, _ ->
41 | adapterCallbacks.animeTitleClick(model = model.animeMetaModel())
42 | }
43 | .animeMetaModel(animeMetaModel)
44 | )
45 | }
46 | setDefaultGlobalSnapHelperFactory(null)
47 |
48 | CarouselModel_()
49 | .id(homeScreenModel.hashCode())
50 | .models(movieModelList)
51 | .padding(Carousel.Padding.dp(20,0,20,0,20))
52 | .addTo(this)
53 |
54 | }
55 | C.TYPE_POPULAR_ANIME -> {
56 | homeScreenModel.animeList?.forEach {
57 | val animeMetaModel = it
58 |
59 |
60 | AnimePopularModel_()
61 | .id(animeMetaModel.ID)
62 | .clickListener { model, _, _, _ ->
63 | adapterCallbacks.animeTitleClick(model = model.animeMetaModel())
64 | }
65 | .animeMetaModel(animeMetaModel)
66 | .addTo(this)
67 | }
68 |
69 | }
70 | else ->{
71 | val recentModelList: ArrayList = ArrayList()
72 | homeScreenModel.animeList?.forEach {
73 | val animeMetaModel = it
74 | recentModelList.add(
75 | AnimeSubDubModel2_()
76 | .id(animeMetaModel.ID)
77 | .clickListener { model, _, clickedView, _ ->
78 | recentSubDubClick(model.animeMetaModel(),clickedView)
79 | }
80 | .animeMetaModel(animeMetaModel)
81 | )
82 | }
83 | CarouselModel_()
84 | .id(homeScreenModel.hashCode())
85 | .models(recentModelList)
86 | .padding(Carousel.Padding.dp(20,0,20,0,20))
87 | .addTo(this)
88 | }
89 | }
90 |
91 | }
92 |
93 | }
94 |
95 | private fun recentSubDubClick(model: AnimeMetaModel, clickedView: View){
96 | when(clickedView.id){
97 | R.id.backgroundImage->{
98 | adapterCallbacks.recentSubDubEpisodeClick(model = model )
99 | }
100 | R.id.animeTitle->{
101 | adapterCallbacks.animeTitleClick(model = model)
102 | }
103 | }
104 |
105 | }
106 |
107 |
108 | interface EpoxyAdapterCallbacks{
109 | fun recentSubDubEpisodeClick(model: AnimeMetaModel)
110 | fun animeTitleClick(model: AnimeMetaModel)
111 | }
112 |
113 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/mal/LoginFragment.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.mal
2 |
3 |
4 | import android.os.Bundle
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import androidx.fragment.app.Fragment;
9 | import androidx.navigation.fragment.findNavController
10 | import com.axiel7.moelist.utils.PkceGenerator
11 | import kotlinx.android.synthetic.main.fragment_settings.view.*
12 | import kotlinx.android.synthetic.main.web_view.view.*
13 | import net.vapormusic.animexstream.R
14 |
15 | class LoginFragment : Fragment(), View.OnClickListener {
16 |
17 |
18 | private lateinit var rootView: View
19 | private lateinit var codeVerifier: String
20 | private lateinit var codeChallenge: String
21 |
22 | override fun onCreateView(
23 | inflater: LayoutInflater,
24 | container: ViewGroup?,
25 | savedInstanceState: Bundle?
26 | ): View? {
27 | rootView = inflater.inflate(R.layout.fragment_settings, container, false)
28 | setupClickListeners()
29 | codeVerifier = PkceGenerator.generateVerifier(128)
30 | codeChallenge = codeVerifier
31 |
32 | return rootView
33 | }
34 |
35 |
36 |
37 |
38 | override fun onResume() {
39 | super.onResume()
40 | }
41 |
42 | private fun setupClickListeners() {
43 | rootView.exitwebview.setOnClickListener(this)
44 |
45 | }
46 |
47 | override fun onClick(v: View?) {
48 | when (v?.id) {
49 | R.id.exitwebview -> findNavController().popBackStack()
50 |
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/player/EpisodeRepository.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.player
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.android.schedulers.AndroidSchedulers
5 | import io.reactivex.schedulers.Schedulers
6 | import io.realm.Realm
7 | import net.vapormusic.animexstream.utils.constants.C
8 | import net.vapormusic.animexstream.utils.rertofit.NetworkInterface
9 | import net.vapormusic.animexstream.utils.rertofit.RetrofitHelper
10 | import net.vapormusic.animexstream.utils.model.Content
11 | import net.vapormusic.animexstream.utils.model.WatchedEpisode
12 | import net.vapormusic.animexstream.utils.realm.InitalizeRealm
13 | import okhttp3.ResponseBody
14 | import retrofit2.Retrofit
15 | import timber.log.Timber
16 |
17 |
18 | class EpisodeRepository {
19 | private var retrofit: Retrofit = RetrofitHelper.getRetrofitInstance()!!
20 | private var realm = Realm.getInstance(InitalizeRealm.getConfig())
21 |
22 |
23 | fun fetchEpisodeMediaUrl(url: String): Observable {
24 | val mediaUrlService = retrofit.create(NetworkInterface.FetchEpisodeMediaUrl::class.java)
25 | return mediaUrlService.get(url).subscribeOn(Schedulers.io())
26 | .observeOn(AndroidSchedulers.mainThread())
27 | }
28 |
29 | fun fetchM3u8Url(url: String): Observable {
30 | val m3u8urlService = retrofit.create(NetworkInterface.FetchM3u8Url::class.java)
31 | return m3u8urlService.get(url).subscribeOn(Schedulers.io())
32 | .observeOn(AndroidSchedulers.mainThread())
33 | }
34 | fun fetchGoogleUrl(url: String): Observable {
35 | val m3u8urlService = retrofit.create(NetworkInterface.FetchGoogleUrl::class.java)
36 | return m3u8urlService.get(url).subscribeOn(Schedulers.io())
37 | .observeOn(AndroidSchedulers.mainThread())
38 | }
39 | fun fetchM3u8Urlv2(url: String, ref : String): Observable {
40 | val m3u8urlService = retrofit.create(NetworkInterface.FetchM3u8Urlv2::class.java)
41 | return m3u8urlService.get(url,ref).subscribeOn(Schedulers.io())
42 | .observeOn(AndroidSchedulers.mainThread())
43 | }
44 |
45 | fun fetchWatchedDuration(id: Int): WatchedEpisode?{
46 | return realm.where(WatchedEpisode::class.java).equalTo("id", id).findFirst()
47 | }
48 |
49 | fun fetchContent(episodeUrl: String): Content? {
50 | try {
51 | var content: Content? = null
52 | val result = realm.where(Content::class.java).equalTo("episodeUrl", episodeUrl).findFirst()
53 | result?.let {
54 | content = realm.copyFromRealm(it)
55 | }
56 | Timber.e("ID : %s", content?.episodeUrl.hashCode())
57 | val watchedEpisode = fetchWatchedDuration(content?.episodeUrl.hashCode())
58 | content?.watchedDuration = watchedEpisode?.watchedDuration?.let { it
59 | } ?: 0
60 | return content
61 |
62 |
63 | } catch (ignored: Exception) {
64 | }
65 | return null
66 | }
67 |
68 |
69 | fun saveContent(content: Content){
70 | try {
71 | content.insertionTime = System.currentTimeMillis()
72 | realm.executeTransactionAsync { realm1: Realm ->
73 | realm1.insertOrUpdate(content)
74 | }
75 |
76 | val progressPercentage: Long = ((content.watchedDuration.toDouble()/(content.duration).toDouble()) * 100).toLong()
77 | val watchedEpisode = WatchedEpisode(
78 | id = content.episodeUrl.hashCode(),
79 | watchedDuration = content.watchedDuration,
80 | watchedPercentage = progressPercentage,
81 | animeName = content.animeName
82 |
83 | )
84 | realm.executeTransactionAsync {
85 | it.insertOrUpdate(watchedEpisode)
86 | }
87 | } catch (ignored: Exception) {
88 | }
89 | }
90 |
91 |
92 | fun clearContent(){
93 | realm.executeTransactionAsync {
94 | val results = it.where(Content::class.java).lessThanOrEqualTo("insertionTime", System.currentTimeMillis() - C.MAX_TIME_M3U8_URL).findAll()
95 | results.deleteAllFromRealm()
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/player/ModifyGestureDetector.java:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.player;
2 |
3 | import android.content.Context;
4 | import android.view.GestureDetector;
5 | import android.view.MotionEvent;
6 |
7 | import timber.log.Timber;
8 |
9 | public class ModifyGestureDetector extends GestureDetector {
10 |
11 | MyGestureListener myGestureListener;
12 |
13 | public ModifyGestureDetector(Context context, OnGestureListener listener) {
14 | super(context, listener);
15 | init(listener);
16 | }
17 |
18 | void init(GestureDetector.OnGestureListener listener){
19 | if (listener instanceof MyGestureListener){
20 | myGestureListener = (MyGestureListener) listener;
21 | }
22 | }
23 |
24 | //u can write something more complex as long as u need
25 | @Override
26 | public boolean onTouchEvent(MotionEvent ev) {
27 | Timber.e("vapor_action: "+ev.getAction());
28 | if(ev.getAction() == MotionEvent.ACTION_UP
29 | && myGestureListener != null){
30 | myGestureListener.onUp(ev);
31 | }
32 | return super.onTouchEvent(ev);
33 | }
34 |
35 | public interface MyGestureListener{
36 | public void onUp(MotionEvent ev);
37 | }}
38 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/search/SearchRepository.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.search
2 |
3 |
4 | import io.reactivex.Observable
5 | import io.reactivex.android.schedulers.AndroidSchedulers
6 | import io.reactivex.schedulers.Schedulers
7 | import net.vapormusic.animexstream.utils.model.SuggestionModel
8 | import net.vapormusic.animexstream.utils.rertofit.NetworkInterface
9 | import net.vapormusic.animexstream.utils.rertofit.RetrofitHelper
10 | import okhttp3.ResponseBody
11 | import retrofit2.Call
12 | import retrofit2.Callback
13 |
14 | class SearchRepository {
15 |
16 | private val retrofit = RetrofitHelper.getRetrofitInstance()
17 |
18 | fun fetchSearchList(keyWord: String, pageNumber: Int): Observable{
19 | val searchService = retrofit.create(NetworkInterface.FetchSearchData::class.java)
20 | return searchService.get(keyWord,pageNumber).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
21 | }
22 |
23 | fun fetchSearchSuggestions(keyWord: String): Call {
24 | val searchService = retrofit.create(NetworkInterface.FetchSearchSuggestionData::class.java)
25 | return searchService.get(keyWord)
26 | }
27 |
28 | fun fetchSearchGenre(genre: String, pageNumber: Int): Observable {
29 | val searchService = retrofit.create(NetworkInterface.FetchSearchViaGenreData::class.java)
30 | return searchService.get(genre,pageNumber).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
31 | }
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/search/adapter/Suggestions.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.search.adapter
2 |
3 | import android.content.Context
4 | import android.widget.ArrayAdapter
5 | import android.widget.Filter
6 | import android.widget.Filterable
7 | import net.vapormusic.animexstream.ui.main.search.SearchRepository
8 | import net.vapormusic.animexstream.utils.constants.C
9 | import net.vapormusic.animexstream.utils.parser.HtmlParser
10 | import okhttp3.OkHttpClient
11 | import okhttp3.Request
12 | import java.io.BufferedInputStream
13 | import java.io.InputStream
14 | import java.net.HttpURLConnection
15 | import java.net.URL
16 | import java.util.*
17 | import kotlin.collections.ArrayList
18 |
19 |
20 | class Suggestions(context: Context, resource: Int) : ArrayAdapter(context, resource), Filterable{
21 |
22 | private var dataList: List<*> = emptyList()
23 |
24 | private val listFilter = ListFilter(this)
25 |
26 |
27 | override fun getCount(): Int {
28 | return dataList.size
29 | }
30 |
31 | override fun getItem(position: Int): String {
32 | return (dataList[position] as? String ?: "")
33 | }
34 |
35 | override fun getFilter(): Filter {
36 | return listFilter
37 | }
38 |
39 | class ListFilter(var suggestions: Suggestions) : Filter() {
40 | private val lock = Any()
41 | private val searchRepository = SearchRepository()
42 |
43 | override fun performFiltering(prefix: CharSequence?): FilterResults {
44 | val results = FilterResults()
45 | if (prefix == null || prefix.isEmpty()) {
46 | synchronized(lock) {
47 | results.values = ArrayList()
48 | results.count = 0
49 | }
50 | } else {
51 | val searchStrLowerCase = prefix.toString().toLowerCase(Locale.ROOT)
52 |
53 | val url = URL("${C.SUGGESTION_URL}?keyword=$searchStrLowerCase")
54 | val urlConnection: HttpURLConnection = url.openConnection() as HttpURLConnection
55 | urlConnection.addRequestProperty("x-requested-with", "XMLHttpRequest")
56 |
57 | try {
58 | val inp: InputStream = BufferedInputStream(urlConnection.inputStream)
59 | val list = HtmlParser.parseSuggestions(String(inp.readBytes()))
60 | results.values = list
61 | results.count = list.size
62 | } finally {
63 | urlConnection.disconnect()
64 | }
65 | }
66 | return results
67 | }
68 |
69 | override fun publishResults(
70 | constraint: CharSequence?,
71 | results: FilterResults
72 | ) {
73 | if (results.values != null) {
74 | this.suggestions.dataList = results.values as List<*>
75 | } else {
76 | this.suggestions.dataList = emptyList()
77 | }
78 | if (results.count > 0) {
79 | this.suggestions.notifyDataSetChanged()
80 | } else {
81 | this.suggestions.notifyDataSetInvalidated()
82 | }
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/search/adapter/SuggestionsAdapter.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.search.adapter
2 |
3 | import android.content.Context
4 | import android.widget.ArrayAdapter
5 | import android.widget.Filter
6 | import android.widget.Filterable
7 |
8 |
9 | class SuggestionsAdapter(context: Context, resource: Int, suggestionsCallback: SuggestionsFilter.SuggestionAdapterCallbacks) : ArrayAdapter(context, resource), Filterable{
10 |
11 | private var dataList: List<*> = emptyList()
12 |
13 | private val listFilter = SuggestionsFilter(suggestionsCallback)
14 |
15 |
16 | override fun getCount(): Int {
17 | return dataList.size
18 | }
19 |
20 | override fun getItem(position: Int): String {
21 | return (dataList[position] as? String ?: "")
22 | }
23 |
24 | override fun getFilter(): Filter {
25 | return listFilter
26 | }
27 |
28 | fun setResults(result: List?) {
29 | result?.let {
30 | dataList = it
31 | notifyDataSetChanged()
32 | }
33 | }
34 |
35 | class SuggestionsFilter(private var suggestionsCallback: SuggestionAdapterCallbacks) : Filter() {
36 |
37 | private var lock: CharSequence = ""
38 |
39 | interface SuggestionAdapterCallbacks {
40 | fun findSuggestions(hint: String, newQuery: Boolean)
41 | }
42 |
43 | override fun performFiltering(prefix: CharSequence?): FilterResults {
44 | return FilterResults()
45 | }
46 |
47 | override fun publishResults(
48 | constraint: CharSequence?,
49 | results: FilterResults
50 | ) {
51 | constraint?.trim()?.let { hint ->
52 | if(hint != ""){
53 | suggestionsCallback.findSuggestions(hint.toString(), lock != hint)
54 | lock = hint
55 | }
56 | }
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/ui/main/search/epoxy/SearchController.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.ui.main.search.epoxy
2 |
3 | import com.airbnb.epoxy.Typed2EpoxyController
4 | import net.vapormusic.animexstream.utils.epoxy.AnimeCommonModel_
5 | import net.vapormusic.animexstream.utils.epoxy.LoadingModel_
6 | import net.vapormusic.animexstream.utils.model.AnimeMetaModel
7 |
8 | class SearchController(var adapterCallbacks: EpoxySearchAdapterCallbacks) : Typed2EpoxyController, Boolean>() {
9 |
10 |
11 | override fun buildModels(data: ArrayList?, isLoading: Boolean) {
12 | data?.forEach { animeMetaModel ->
13 | AnimeCommonModel_()
14 | .id(animeMetaModel.ID)
15 | .animeMetaModel(animeMetaModel)
16 | .spanSizeOverride { totalSpanCount, _, _ -> totalSpanCount / totalSpanCount }
17 | .clickListener { model, _, _, _ ->
18 | adapterCallbacks.animeTitleClick(model = model.animeMetaModel())
19 | }
20 | .addTo(this)
21 | }
22 | if(!data.isNullOrEmpty()){
23 | LoadingModel_()
24 | .id("loading")
25 | .spanSizeOverride { totalSpanCount, _, _ ->
26 | totalSpanCount
27 | }
28 | .addIf(isLoading,this)
29 | }
30 | }
31 |
32 |
33 | interface EpoxySearchAdapterCallbacks{
34 | fun animeTitleClick(model: AnimeMetaModel)
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/CommonViewModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import net.vapormusic.animexstream.R
7 | import net.vapormusic.animexstream.utils.constants.C
8 | import net.vapormusic.animexstream.utils.model.ErrorModel
9 | import net.vapormusic.animexstream.utils.model.LoadingModel
10 | import retrofit2.HttpException
11 | import java.net.HttpURLConnection
12 | import java.net.SocketException
13 | import java.net.SocketTimeoutException
14 | import java.net.UnknownHostException
15 |
16 | open class CommonViewModel : ViewModel() {
17 | private var _isLoading: MutableLiveData = MutableLiveData()
18 | private var _errorModel: MutableLiveData = MutableLiveData()
19 | var isLoading: LiveData = _isLoading
20 | var errorModel: LiveData = _errorModel
21 |
22 |
23 |
24 | protected fun updateErrorModel(show: Boolean,e: Throwable?, isListEmpty: Boolean) {
25 | val errorCode: Int
26 | var errorMsgId = R.string.something_went_wrong
27 |
28 | if (e is HttpException) {
29 | errorCode = when (e.code()) {
30 | HttpURLConnection.HTTP_BAD_REQUEST -> C.RESPONSE_UNKNOWN
31 | else -> C.ERROR_CODE_DEFAULT
32 | }
33 | } else if (e is SocketException || e is UnknownHostException || e is SocketTimeoutException) {
34 | errorCode = C.NO_INTERNET_CONNECTION
35 | errorMsgId = R.string.no_internet
36 | } else{
37 | errorCode = C.ERROR_CODE_DEFAULT
38 | }
39 |
40 | _errorModel.value = ErrorModel(
41 | show = show,
42 | errorCode = errorCode,
43 | errorMsgId = errorMsgId,
44 | isListEmpty = isListEmpty
45 | )
46 |
47 | }
48 |
49 | protected fun isLoading():Boolean{
50 | return _isLoading.value?.isLoading ?: false
51 | }
52 |
53 | protected fun updateLoading(loading: Boolean, isListEmpty: Boolean = true){
54 | _isLoading.value = LoadingModel(
55 | loading,
56 | isListEmpty
57 | )
58 | }
59 |
60 |
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/CommonViewModel2.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import net.vapormusic.animexstream.R
7 | import net.vapormusic.animexstream.utils.constants.C
8 | import net.vapormusic.animexstream.utils.model.ErrorModel
9 | import net.vapormusic.animexstream.utils.model.LoadingModel2
10 | import retrofit2.HttpException
11 | import java.net.HttpURLConnection
12 | import java.net.SocketException
13 | import java.net.SocketTimeoutException
14 | import java.net.UnknownHostException
15 |
16 | open class CommonViewModel2 : ViewModel(){
17 |
18 | private val _loadingModel: MutableLiveData = MutableLiveData()
19 | val loadingModel: LiveData = _loadingModel
20 | private var errorCode: Int = C.ERROR_CODE_DEFAULT
21 | private var errorMsgId = R.string.something_went_wrong
22 |
23 | init {
24 | _loadingModel.postValue(null)
25 | }
26 |
27 | private fun updateErrorModel(e: Throwable?) {
28 | e?.let {
29 | if (e is HttpException) {
30 | errorCode = when (e.code()) {
31 | HttpURLConnection.HTTP_BAD_REQUEST -> C.RESPONSE_UNKNOWN
32 | else -> C.ERROR_CODE_DEFAULT
33 | }
34 | } else if (e is SocketException || e is UnknownHostException || e is SocketTimeoutException) {
35 | errorCode = C.NO_INTERNET_CONNECTION
36 | errorMsgId = R.string.no_internet
37 | } else{
38 | errorCode = C.ERROR_CODE_DEFAULT
39 | }
40 | }
41 | }
42 |
43 | protected fun isLoading(): Boolean{
44 | _loadingModel.value?.let {
45 | return it.loading == Loading.LOADING
46 | } ?: return false
47 | }
48 |
49 | protected fun updateLoadingState(loading: Loading, e: Throwable?, isListEmpty: Boolean = true){
50 | updateErrorModel(e)
51 | _loadingModel.value = LoadingModel2(
52 | loading = loading,
53 | errorCode = errorCode,
54 | errorMsg = errorMsgId,
55 | isListEmpty = isListEmpty
56 | )
57 | }
58 | enum class Loading{
59 | LOADING, COMPLETED, ERROR
60 | }
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/ItemOffsetDecoration.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils
2 |
3 | import android.content.Context
4 | import android.graphics.Rect
5 | import android.view.View
6 | import androidx.annotation.DimenRes
7 | import androidx.recyclerview.widget.RecyclerView
8 | import androidx.recyclerview.widget.RecyclerView.ItemDecoration
9 |
10 | class ItemOffsetDecoration(private val mItemOffset: Int) : ItemDecoration() {
11 |
12 | constructor(context: Context?, @DimenRes itemOffsetId: Int) : this(
13 | context!!.resources.getDimensionPixelSize(
14 | itemOffsetId
15 | )
16 | )
17 |
18 | override fun getItemOffsets(
19 | outRect: Rect, view: View, parent: RecyclerView,
20 | state: RecyclerView.State
21 | ) {
22 | super.getItemOffsets(outRect, view, parent, state)
23 | outRect[mItemOffset, mItemOffset, mItemOffset] = mItemOffset
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/Tags/GenreTags.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.Tags
2 |
3 | import android.content.Context
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.LinearLayout
8 | import kotlinx.android.synthetic.main.tags_genre.view.*
9 | import net.vapormusic.animexstream.R
10 |
11 | class GenreTags(var context: Context){
12 |
13 | public fun getGenreTag(genreName: String, genreUrl: String): View{
14 | var view =LayoutInflater.from(context).inflate(R.layout.tags_genre, null)
15 | var button = view.genre
16 | button.text = genreName
17 | button.maxLines = 1
18 | val rel_button1 = LinearLayout.LayoutParams(
19 | ViewGroup.LayoutParams.WRAP_CONTENT,
20 | ViewGroup.LayoutParams.WRAP_CONTENT
21 | )
22 | rel_button1.setMargins(8, 8, 8, 8)
23 | button.layoutParams = rel_button1
24 | return view
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/Utils.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils
2 |
3 | import android.content.Context
4 | import android.util.DisplayMetrics
5 | import net.vapormusic.animexstream.utils.constants.C
6 |
7 |
8 | class Utils {
9 | companion object{
10 |
11 | fun getTypeName(typeValue: Int) : String{
12 |
13 | return when(typeValue){
14 |
15 | C.TYPE_RECENT_DUB -> "Recent Dub"
16 | C.TYPE_RECENT_SUB -> "Recent Sub"
17 | C.TYPE_MOVIE -> "Movies"
18 | C.TYPE_POPULAR_ANIME -> "Popular Anime"
19 | C.TYPE_GENRE -> "Categories"
20 | C.TYPE_NEW_SEASON-> "New Season"
21 | else -> "Default"
22 | }
23 | }
24 |
25 | fun calculateNoOfColumns(
26 | context: Context,
27 | columnWidthDp: Float
28 | ): Int {
29 | val displayMetrics: DisplayMetrics = context.resources.displayMetrics
30 | val screenWidthDp = displayMetrics.widthPixels / displayMetrics.density
31 | return (screenWidthDp / columnWidthDp + 0.5).toInt()
32 | }
33 |
34 | fun getPositionByType(typeValue: Int): Int{
35 | return when (typeValue){
36 | C.TYPE_RECENT_SUB -> C.RECENT_SUB_POSITION
37 | C.TYPE_NEW_SEASON -> C.NEWEST_SEASON_POSITION
38 | C.TYPE_RECENT_DUB -> C.RECENT_SUB_POSITION
39 | C.TYPE_MOVIE -> C.MOVIE_POSITION
40 | C.TYPE_POPULAR_ANIME -> C.POPULAR_POSITION
41 | else -> 0
42 | }
43 | }
44 |
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/connectivity/ConnectivityProviderImpl.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.connectivity
2 |
3 | import android.net.ConnectivityManager
4 | import android.net.ConnectivityManager.NetworkCallback
5 | import android.net.Network
6 | import android.net.NetworkCapabilities
7 | import android.os.Build
8 | import androidx.annotation.RequiresApi
9 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProvider.NetworkState
10 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProvider.NetworkState.ConnectedState.Connected
11 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProvider.NetworkState.NotConnectedState
12 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProviderBaseImpl
13 |
14 | @RequiresApi(Build.VERSION_CODES.N)
15 | class ConnectivityProviderImpl(private val cm: ConnectivityManager) :
16 | ConnectivityProviderBaseImpl() {
17 |
18 | private val networkCallback = ConnectivityCallback()
19 |
20 | override fun subscribe() {
21 | cm.registerDefaultNetworkCallback(networkCallback)
22 | }
23 |
24 | override fun unsubscribe() {
25 | cm.unregisterNetworkCallback(networkCallback)
26 | }
27 |
28 | override fun getNetworkState(): NetworkState {
29 | val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
30 | return if (capabilities != null) {
31 | Connected(capabilities)
32 | } else {
33 | NotConnectedState
34 | }
35 | }
36 |
37 | private inner class ConnectivityCallback : NetworkCallback() {
38 |
39 | override fun onCapabilitiesChanged(network: Network, capabilities: NetworkCapabilities) {
40 | dispatchChange(Connected(capabilities))
41 | }
42 |
43 | override fun onLost(network: Network) {
44 | dispatchChange(NotConnectedState)
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/connectivity/ConnectivityProviderLegacyImpl.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.connectivity
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.content.IntentFilter
7 | import android.net.ConnectivityManager
8 | import android.net.ConnectivityManager.CONNECTIVITY_ACTION
9 | import android.net.ConnectivityManager.EXTRA_NETWORK_INFO
10 | import android.net.NetworkInfo
11 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProvider.NetworkState
12 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProvider.NetworkState.ConnectedState.ConnectedLegacy
13 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProvider.NetworkState.NotConnectedState
14 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProviderBaseImpl
15 |
16 | @Suppress("DEPRECATION")
17 | class ConnectivityProviderLegacyImpl(
18 | private val context: Context,
19 | private val cm: ConnectivityManager
20 | ) : ConnectivityProviderBaseImpl() {
21 |
22 | private val receiver = ConnectivityReceiver()
23 |
24 | override fun subscribe() {
25 | context.registerReceiver(receiver, IntentFilter(CONNECTIVITY_ACTION))
26 | }
27 |
28 | override fun unsubscribe() {
29 | context.unregisterReceiver(receiver)
30 | }
31 |
32 | override fun getNetworkState(): NetworkState {
33 | val activeNetworkInfo = cm.activeNetworkInfo
34 | return if (activeNetworkInfo != null) {
35 | ConnectedLegacy(activeNetworkInfo)
36 | } else {
37 | NotConnectedState
38 | }
39 | }
40 |
41 | private inner class ConnectivityReceiver : BroadcastReceiver() {
42 | override fun onReceive(c: Context, intent: Intent) {
43 | // on some devices ConnectivityManager.getActiveNetworkInfo() does not provide the correct network state
44 | // https://issuetracker.google.com/issues/37137911
45 | val networkInfo = cm.activeNetworkInfo
46 | val fallbackNetworkInfo: NetworkInfo? = intent.getParcelableExtra(EXTRA_NETWORK_INFO)
47 | // a set of dirty workarounds
48 | val state: NetworkState =
49 | if (networkInfo?.isConnectedOrConnecting == true) {
50 | ConnectedLegacy(networkInfo)
51 | } else if (networkInfo != null && fallbackNetworkInfo != null &&
52 | networkInfo.isConnectedOrConnecting != fallbackNetworkInfo.isConnectedOrConnecting
53 | ) {
54 | ConnectedLegacy(fallbackNetworkInfo)
55 | } else {
56 | val state = networkInfo ?: fallbackNetworkInfo
57 | if (state != null) ConnectedLegacy(state) else NotConnectedState
58 | }
59 | dispatchChange(state)
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/connectivity/base/ConnectivityProvider.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.connectivity.base
2 |
3 | import android.content.Context
4 | import android.content.Context.CONNECTIVITY_SERVICE
5 | import android.net.ConnectivityManager
6 | import android.net.NetworkCapabilities
7 | import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
8 | import android.net.NetworkInfo
9 | import android.os.Build
10 | import androidx.annotation.RequiresApi
11 | import net.vapormusic.animexstream.utils.connectivity.ConnectivityProviderImpl
12 | import net.vapormusic.animexstream.utils.connectivity.ConnectivityProviderLegacyImpl
13 |
14 | interface ConnectivityProvider {
15 | interface ConnectivityStateListener {
16 | fun onStateChange(state: NetworkState)
17 | }
18 |
19 | fun addListener(listener: ConnectivityStateListener)
20 | fun removeListener(listener: ConnectivityStateListener)
21 |
22 | fun getNetworkState(): NetworkState
23 |
24 | @Suppress("MemberVisibilityCanBePrivate", "CanBeParameter")
25 | sealed class NetworkState {
26 | object NotConnectedState : NetworkState()
27 |
28 | sealed class ConnectedState(val hasInternet: Boolean) : NetworkState() {
29 |
30 | @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
31 | data class Connected(val capabilities: NetworkCapabilities) : ConnectedState(
32 | capabilities.hasCapability(NET_CAPABILITY_INTERNET)
33 | )
34 |
35 | @Suppress("DEPRECATION")
36 | data class ConnectedLegacy(val networkInfo: NetworkInfo) : ConnectedState(
37 | networkInfo.isConnectedOrConnecting
38 | )
39 | }
40 | }
41 |
42 | companion object {
43 | fun createProvider(context: Context): ConnectivityProvider {
44 | val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
45 | return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
46 | ConnectivityProviderImpl(cm)
47 | } else {
48 | ConnectivityProviderLegacyImpl(context, cm)
49 | }
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/connectivity/base/ConnectivityProviderBaseImpl.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.connectivity.base
2 |
3 | import android.os.Handler
4 | import android.os.Looper
5 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProvider.ConnectivityStateListener
6 | import net.vapormusic.animexstream.utils.connectivity.base.ConnectivityProvider.NetworkState
7 |
8 | abstract class ConnectivityProviderBaseImpl : ConnectivityProvider {
9 | private val handler = Handler(Looper.getMainLooper())
10 | private val listeners = mutableSetOf()
11 | private var subscribed = false
12 |
13 | override fun addListener(listener: ConnectivityStateListener) {
14 | listeners.add(listener)
15 | listener.onStateChange(getNetworkState()) // propagate an initial state
16 | verifySubscription()
17 | }
18 |
19 | override fun removeListener(listener: ConnectivityStateListener) {
20 | listeners.remove(listener)
21 | verifySubscription()
22 | }
23 |
24 | private fun verifySubscription() {
25 | if (!subscribed && listeners.isNotEmpty()) {
26 | subscribe()
27 | subscribed = true
28 | } else if (subscribed && listeners.isEmpty()) {
29 | unsubscribe()
30 | subscribed = false
31 | }
32 | }
33 |
34 | protected fun dispatchChange(state: NetworkState) {
35 | handler.post {
36 | for (listener in listeners) {
37 | listener.onStateChange(state)
38 | }
39 | }
40 | }
41 |
42 | protected abstract fun subscribe()
43 | protected abstract fun unsubscribe()
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/constants/C.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.constants
2 |
3 | class C {
4 | companion object{
5 |
6 | const val GIT_DOWNLOAD_URL = "https://github.com/vapormusic/AnimeXStream/"
7 |
8 | //Error Codes
9 | const val RESPONSE_UNKNOWN: Int = 1000
10 | const val ERROR_CODE_DEFAULT: Int = -1000
11 | const val NO_INTERNET_CONNECTION = 1001
12 |
13 | //Base URLS
14 | var BASE_URL = "https://gogoanime.pe/"
15 |
16 | const val EPISODE_LOAD_URL = "https://ajax.gogo-load.com/ajax/load-list-episode"
17 | const val SUGGESTION_URL = "https://vidstreaming.io/ajax-search.html"
18 | const val SEARCH_URL = "/search.html"
19 |
20 | //MAL integration
21 | //
22 | // const val AUTH_DEEP_LINK = "animexstream://auth"
23 | const val AUTH_DEEP_LINK = "net.myanimelist://login.input"
24 | const val MAL_OAUTH2_BASE = "https://myanimelist.net/v1/oauth2/"
25 | const val MAL_STATE = "animexstreamauth"
26 | const val MAL_GET_TRACKING = 900
27 | const val MAL_SET_TRACKING = 901
28 | const val MAL_NEW_ACCESS = 902
29 | const val MAL_REFRESH_ACCESS = 903
30 |
31 | //Model Type
32 | const val TYPE_RECENT_SUB = 1
33 | const val TYPE_POPULAR_ANIME =2
34 | const val TYPE_RECENT_DUB = 3
35 | const val TYPE_GENRE = 4
36 | const val TYPE_MOVIE = 5
37 | const val TYPE_NEW_SEASON = 6
38 | const val TYPE_DEFAULT= -1
39 |
40 | // Retrofit Request TYPE
41 |
42 | const val RECENT_SUB = 1
43 | const val RECENT_DUB = 2
44 |
45 | const val MAX_LIMIT_FOR_SUB_DUB = 10
46 |
47 |
48 | const val NEWEST_SEASON_POSITION = 2
49 | const val RECENT_SUB_POSITION = 0
50 | const val RECENT_DUB_POSITION = 1
51 | const val POPULAR_POSITION = 4
52 | const val MOVIE_POSITION = 3
53 |
54 | //Episode URL Type
55 | const val TYPE_MEDIA_URL = 100
56 | const val TYPE_M3U8_URL = 101
57 | const val TYPE_M3U8_PREPROCESS_URL = 102
58 |
59 | //Anime Info URL Type
60 | const val TYPE_ANIME_INFO = 1000
61 | const val TYPE_EPISODE_LIST = 1001
62 | const val M3U8_REGEX_PATTERN = "(http|https)://([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?"
63 |
64 | //Anime Search Types
65 | const val TYPE_SEARCH_NEW = 2000
66 | const val TYPE_SEARCH_UPDATE = 2001
67 |
68 | //Network Requests Header
69 | const val USER_AGENT = "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
70 | const val USER_AGENT_MAL = "User-Agent: MAL (android, 1.0.8)"
71 | const val ORIGIN = "origin: https://gogoanime.pe/"
72 | const val REFERER = "referer: https://gogoanime.lol/"
73 | const val XML_HTTP_REQUEST = "x-requested-with: XMLHttpRequest"
74 |
75 | //Realm
76 | const val MAX_TIME_M3U8_URL = 2 * 60 * 60 *1000
77 | const val MAX_TIME_FOR_ANIME = 2 * 24 * 60 *60 * 1000
78 | }
79 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/epoxy/CommonModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.epoxy
2 |
3 | import android.view.View
4 | import android.widget.TextView
5 | import androidx.appcompat.widget.AppCompatImageView
6 | import androidx.constraintlayout.widget.ConstraintLayout
7 | import com.airbnb.epoxy.EpoxyAttribute
8 | import com.airbnb.epoxy.EpoxyHolder
9 | import com.airbnb.epoxy.EpoxyModelClass
10 | import com.airbnb.epoxy.EpoxyModelWithHolder
11 | import com.bumptech.glide.Glide
12 | import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
13 | import kotlinx.android.synthetic.main.recycler_anime_common.view.*
14 | import net.vapormusic.animexstream.R
15 | import net.vapormusic.animexstream.utils.model.AnimeMetaModel
16 |
17 | @EpoxyModelClass(layout = R.layout.recycler_anime_common)
18 | abstract class AnimeCommonModel : EpoxyModelWithHolder(){
19 |
20 | @EpoxyAttribute
21 | lateinit var animeMetaModel: AnimeMetaModel
22 | @EpoxyAttribute
23 | var clickListener: View.OnClickListener? = null
24 |
25 | override fun bind(holder: MovieHolder) {
26 | Glide.with(holder.animeImageView.context).load(animeMetaModel.imageUrl).transition(
27 | DrawableTransitionOptions.withCrossFade()).into(holder.animeImageView)
28 | holder.animeTitle.text = animeMetaModel.title
29 | animeMetaModel.releasedDate?.let {
30 | holder.releasedDate.text = it
31 | }
32 | holder.root.setOnClickListener(clickListener)
33 |
34 | }
35 | class MovieHolder : EpoxyHolder(){
36 |
37 | lateinit var animeImageView: AppCompatImageView
38 | lateinit var animeTitle: TextView
39 | lateinit var releasedDate: TextView
40 | lateinit var root: ConstraintLayout
41 |
42 | override fun bindView(itemView: View) {
43 | animeImageView = itemView.animeImage
44 | animeTitle = itemView.animeTitle
45 | releasedDate = itemView.releasedDate
46 | root = itemView.root
47 | }
48 |
49 | }
50 | }
51 |
52 | @EpoxyModelClass(layout = R.layout.recycler_loading)
53 | abstract class LoadingModel : EpoxyModelWithHolder()
54 |
55 | class LoadingHolder : EpoxyHolder() {
56 | override fun bindView(itemView: View) {
57 | }
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/helper/WatchedEpisode.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.helper
2 |
3 | import io.realm.Realm
4 | import io.realm.RealmResults
5 | import net.vapormusic.animexstream.utils.model.WatchedEpisode
6 | import net.vapormusic.animexstream.utils.realm.InitalizeRealm
7 | import timber.log.Timber
8 | import java.util.*
9 | import kotlin.collections.HashMap
10 |
11 | class WatchedEpisode(private var animeName: String){
12 | private var results: RealmResults? = null
13 | private val realm = Realm.getInstance(InitalizeRealm.getConfig())
14 | private val watchedMap: HashMap = HashMap()
15 |
16 | init {
17 | results = realm.where(net.vapormusic.animexstream.utils.model.WatchedEpisode::class.java)
18 | .equalTo("animeName", animeName).findAll()
19 | updateWatchMap(results)
20 | results?.addChangeListener { newResult->
21 | updateWatchMap(newResult)
22 | }
23 | }
24 |
25 | private fun updateWatchMap(results: RealmResults?){
26 | watchedMap.clear()
27 | results?.forEach {
28 | watchedMap[it.id] = it.watchedPercentage ?: 0
29 | }
30 |
31 | }
32 |
33 | fun isWatched(id: Int): Boolean{
34 | return watchedMap.containsKey(id)
35 | }
36 |
37 | fun getWatchedDuration(id: Int): Long{
38 | return watchedMap[id] ?: 0
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/mal/PkceGenerator.kt:
--------------------------------------------------------------------------------
1 | package com.axiel7.moelist.utils
2 |
3 | import org.apache.commons.lang3.RandomStringUtils
4 |
5 | object PkceGenerator {
6 | private const val CODE_VERIFIER_STRING =
7 | "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
8 |
9 | fun generateVerifier(length: Int): String {
10 | return RandomStringUtils.random(length, CODE_VERIFIER_STRING)
11 | }
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/AnimeInfoModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | data class AnimeInfoModel(
4 |
5 | var id: String,
6 | var animeTitle: String,
7 | var imageUrl: String,
8 | var type: String,
9 | var releasedTime: String,
10 | var status: String,
11 | var genre: ArrayList,
12 | var plotSummary: String,
13 | var alias: String,
14 | var endEpisode: String,
15 | var MALAnimeID: String? = ""
16 | )
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/AnimeMetaModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | import android.os.Parcelable
4 | import io.realm.RealmList
5 | import io.realm.RealmObject
6 | import io.realm.annotations.PrimaryKey
7 | import kotlinx.android.parcel.Parcelize
8 | import java.sql.Timestamp
9 |
10 | public open class AnimeMetaModel(
11 | @PrimaryKey
12 | var ID: Int = 0,
13 | var typeValue: Int? = null,
14 | var imageUrl: String = "",
15 | var categoryUrl: String? = null,
16 | var episodeUrl: String? = null,
17 | var title: String = "",
18 | var episodeNumber: String? = null,
19 | var genreList: RealmList? =null,
20 | var timestamp: Long = System.currentTimeMillis(),
21 | var insertionOrder: Int = -1,
22 | var releasedDate: String? =null
23 | ): RealmObject()
24 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/Content.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | import io.realm.RealmObject
4 | import io.realm.annotations.Ignore
5 | import io.realm.annotations.PrimaryKey
6 | import java.time.Duration
7 |
8 |
9 | open class Content(
10 | var url: String?="",
11 | @Ignore
12 | var animeName: String = "",
13 | var episodeName: String?="",
14 | @PrimaryKey
15 | var episodeUrl: String?="",
16 | var nextEpisodeUrl: String?= null,
17 | var previousEpisodeUrl: String?=null,
18 | @Ignore
19 | var watchedDuration: Long = 0,
20 | @Ignore
21 | var duration: Long = 0,
22 | var insertionTime: Long = 0,
23 | @Ignore
24 | var referer: String?=""
25 |
26 | ): RealmObject()
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/EpisodeInfo.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | data class EpisodeInfo(
4 | var vidcdnUrl: String? =null,
5 | var nextEpisodeUrl: String? = null,
6 | var previousEpisodeUrl: String? = null
7 | // var referer: String? = null
8 | )
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/EpisodeModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | data class EpisodeModel(
4 | var episodeNumber: String,
5 | var episodeurl: String,
6 | var episodeType: String
7 | )
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/ErrorModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | data class ErrorModel(
4 | var show:Boolean = false,
5 | var isListEmpty: Boolean = true,
6 | var errorMsgId: Int,
7 | var errorCode: Int
8 | )
9 |
10 | data class LoadingModel(
11 | var isLoading: Boolean,
12 | var isListEmpty: Boolean
13 | )
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/FavouriteModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | import io.realm.RealmObject
4 | import io.realm.annotations.PrimaryKey
5 |
6 | open class FavouriteModel(
7 | @PrimaryKey
8 | var ID: String? = "",
9 | var animeName: String? = "",
10 | var categoryUrl: String? ="",
11 | var imageUrl: String? ="",
12 | var releasedDate: String? = null,
13 | var MAL_ID: String? = "",
14 | var insertionTime: Long = System.currentTimeMillis()
15 | ): RealmObject()
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/GenreModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | import io.realm.RealmObject
4 | import io.realm.annotations.PrimaryKey
5 |
6 | open class GenreModel(
7 | @PrimaryKey
8 | var genreUrl: String ="",
9 | var genreName: String = ""
10 | ) : RealmObject()
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/HomeScreenModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | import kotlin.collections.ArrayList
4 |
5 | data class HomeScreenModel(
6 | var typeValue: Int,
7 | var type: String = "",
8 | var animeList: ArrayList? = null
9 | )
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/LoadingModel2.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | import net.vapormusic.animexstream.R
4 | import net.vapormusic.animexstream.utils.CommonViewModel2
5 | import net.vapormusic.animexstream.utils.constants.C
6 |
7 | data class LoadingModel2(
8 | val loading: CommonViewModel2.Loading,
9 | val isListEmpty: Boolean,
10 | val errorCode: Int,
11 | val errorMsg: Int
12 | )
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/MALModel/UserAnimeList/Datum.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.MALModel.UserAnimeList;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class Datum {
8 |
9 | @SerializedName("node")
10 | @Expose
11 | private Node node;
12 | @SerializedName("list_status")
13 | @Expose
14 | private ListStatus listStatus;
15 |
16 | public Node getNode() {
17 | return node;
18 | }
19 |
20 | public void setNode(Node node) {
21 | this.node = node;
22 | }
23 |
24 | public ListStatus getListStatus() {
25 | return listStatus;
26 | }
27 |
28 | public void setListStatus(ListStatus listStatus) {
29 | this.listStatus = listStatus;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/MALModel/UserAnimeList/ListStatus.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.MALModel.UserAnimeList;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class ListStatus {
8 |
9 | @SerializedName("status")
10 | @Expose
11 | private String status;
12 | @SerializedName("score")
13 | @Expose
14 | private Integer score;
15 | @SerializedName("num_episodes_watched")
16 | @Expose
17 | private Integer numEpisodesWatched;
18 | @SerializedName("is_rewatching")
19 | @Expose
20 | private Boolean isRewatching;
21 | @SerializedName("updated_at")
22 | @Expose
23 | private String updatedAt;
24 |
25 | public String getStatus() {
26 | return status;
27 | }
28 |
29 | public void setStatus(String status) {
30 | this.status = status;
31 | }
32 |
33 | public Integer getScore() {
34 | return score;
35 | }
36 |
37 | public void setScore(Integer score) {
38 | this.score = score;
39 | }
40 |
41 | public Integer getNumEpisodesWatched() {
42 | return numEpisodesWatched;
43 | }
44 |
45 | public void setNumEpisodesWatched(Integer numEpisodesWatched) {
46 | this.numEpisodesWatched = numEpisodesWatched;
47 | }
48 |
49 | public Boolean getIsRewatching() {
50 | return isRewatching;
51 | }
52 |
53 | public void setIsRewatching(Boolean isRewatching) {
54 | this.isRewatching = isRewatching;
55 | }
56 |
57 | public String getUpdatedAt() {
58 | return updatedAt;
59 | }
60 |
61 | public void setUpdatedAt(String updatedAt) {
62 | this.updatedAt = updatedAt;
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/MALModel/UserAnimeList/MainPicture.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.MALModel.UserAnimeList;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class MainPicture {
8 |
9 | @SerializedName("medium")
10 | @Expose
11 | private String medium;
12 | @SerializedName("large")
13 | @Expose
14 | private String large;
15 |
16 | public String getMedium() {
17 | return medium;
18 | }
19 |
20 | public void setMedium(String medium) {
21 | this.medium = medium;
22 | }
23 |
24 | public String getLarge() {
25 | return large;
26 | }
27 |
28 | public void setLarge(String large) {
29 | this.large = large;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/MALModel/UserAnimeList/Node.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.MALModel.UserAnimeList;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class Node {
8 |
9 | @SerializedName("id")
10 | @Expose
11 | private Integer id;
12 | @SerializedName("title")
13 | @Expose
14 | private String title;
15 | @SerializedName("main_picture")
16 | @Expose
17 | private MainPicture mainPicture;
18 |
19 | public Integer getId() {
20 | return id;
21 | }
22 |
23 | public void setId(Integer id) {
24 | this.id = id;
25 | }
26 |
27 | public String getTitle() {
28 | return title;
29 | }
30 |
31 | public void setTitle(String title) {
32 | this.title = title;
33 | }
34 |
35 | public MainPicture getMainPicture() {
36 | return mainPicture;
37 | }
38 |
39 | public void setMainPicture(MainPicture mainPicture) {
40 | this.mainPicture = mainPicture;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/MALModel/UserAnimeList/Paging.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.MALModel.UserAnimeList;
3 |
4 |
5 | public class Paging {
6 |
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/MALModel/UserAnimeList/UserAnimeList.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.MALModel.UserAnimeList;
3 |
4 | import java.util.List;
5 | import com.google.gson.annotations.Expose;
6 | import com.google.gson.annotations.SerializedName;
7 |
8 | public class UserAnimeList {
9 |
10 | @SerializedName("data")
11 | @Expose
12 | private List data = null;
13 | @SerializedName("paging")
14 | @Expose
15 | private Paging paging;
16 |
17 | public List getData() {
18 | return data;
19 | }
20 |
21 | public void setData(List data) {
22 | this.data = data;
23 | }
24 |
25 | public Paging getPaging() {
26 | return paging;
27 | }
28 |
29 | public void setPaging(Paging paging) {
30 | this.paging = paging;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/PaheModel/ResolutionURLs/Datum.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class Datum {
8 |
9 | @SerializedName("720")
10 | @Expose
11 | private net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._720 _720;
12 | @SerializedName("1080")
13 | @Expose
14 | private net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._1080 _1080;
15 | @SerializedName("480")
16 | @Expose
17 | private net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._480 _480;
18 | @SerializedName("360")
19 | @Expose
20 | private net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._360 _360;
21 |
22 | public net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._720 get720() {
23 | return _720;
24 | }
25 |
26 | public void set720(net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._720 _720) {
27 | this._720 = _720;
28 | }
29 |
30 | public net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._1080 get1080() {
31 | return _1080;
32 | }
33 |
34 | public void set1080(net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._1080 _1080) {
35 | this._1080 = _1080;
36 | }
37 |
38 | public net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._360 get360() {
39 | return _360;
40 | }
41 |
42 | public void set360(net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._360 _360) {
43 | this._360 = _360;
44 | }
45 |
46 | public net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._480 get480() {
47 | return _480;
48 | }
49 |
50 | public void set480(net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs._480 _480) {
51 | this._480 = _480;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/PaheModel/ResolutionURLs/ResolutionURLs.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs;
3 |
4 | import java.util.List;
5 | import com.google.gson.annotations.Expose;
6 | import com.google.gson.annotations.SerializedName;
7 |
8 | public class ResolutionURLs {
9 |
10 | @SerializedName("data")
11 | @Expose
12 | private List data = null;
13 |
14 | public List getData() {
15 | return data;
16 | }
17 |
18 | public void setData(List data) {
19 | this.data = data;
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/PaheModel/ResolutionURLs/_1080.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class _1080 {
8 |
9 | @SerializedName("filesize")
10 | @Expose
11 | private Integer filesize;
12 | @SerializedName("crc32")
13 | @Expose
14 | private String crc32;
15 | @SerializedName("revision")
16 | @Expose
17 | private String revision;
18 | @SerializedName("fansub")
19 | @Expose
20 | private String fansub;
21 | @SerializedName("audio")
22 | @Expose
23 | private String audio;
24 | @SerializedName("disc")
25 | @Expose
26 | private String disc;
27 | @SerializedName("hq")
28 | @Expose
29 | private Integer hq;
30 | @SerializedName("kwik")
31 | @Expose
32 | private String kwik;
33 | @SerializedName("kwik_adfly")
34 | @Expose
35 | private String kwikAdfly;
36 | @SerializedName("kwik_shst")
37 | @Expose
38 | private String kwikShst;
39 | @SerializedName("server")
40 | @Expose
41 | private String server;
42 |
43 | public Integer getFilesize() {
44 | return filesize;
45 | }
46 |
47 | public void setFilesize(Integer filesize) {
48 | this.filesize = filesize;
49 | }
50 |
51 | public String getCrc32() {
52 | return crc32;
53 | }
54 |
55 | public void setCrc32(String crc32) {
56 | this.crc32 = crc32;
57 | }
58 |
59 | public String getRevision() {
60 | return revision;
61 | }
62 |
63 | public void setRevision(String revision) {
64 | this.revision = revision;
65 | }
66 |
67 | public String getFansub() {
68 | return fansub;
69 | }
70 |
71 | public void setFansub(String fansub) {
72 | this.fansub = fansub;
73 | }
74 |
75 | public String getAudio() {
76 | return audio;
77 | }
78 |
79 | public void setAudio(String audio) {
80 | this.audio = audio;
81 | }
82 |
83 | public String getDisc() {
84 | return disc;
85 | }
86 |
87 | public void setDisc(String disc) {
88 | this.disc = disc;
89 | }
90 |
91 | public Integer getHq() {
92 | return hq;
93 | }
94 |
95 | public void setHq(Integer hq) {
96 | this.hq = hq;
97 | }
98 |
99 | public String getKwik() {
100 | return kwik;
101 | }
102 |
103 | public void setKwik(String kwik) {
104 | this.kwik = kwik;
105 | }
106 |
107 | public String getKwikAdfly() {
108 | return kwikAdfly;
109 | }
110 |
111 | public void setKwikAdfly(String kwikAdfly) {
112 | this.kwikAdfly = kwikAdfly;
113 | }
114 |
115 | public String getKwikShst() {
116 | return kwikShst;
117 | }
118 |
119 | public void setKwikShst(String kwikShst) {
120 | this.kwikShst = kwikShst;
121 | }
122 |
123 | public String getServer() {
124 | return server;
125 | }
126 |
127 | public void setServer(String server) {
128 | this.server = server;
129 | }
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/PaheModel/ResolutionURLs/_360.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class _360 {
8 |
9 | @SerializedName("filesize")
10 | @Expose
11 | private Integer filesize;
12 | @SerializedName("crc32")
13 | @Expose
14 | private String crc32;
15 | @SerializedName("revision")
16 | @Expose
17 | private String revision;
18 | @SerializedName("fansub")
19 | @Expose
20 | private String fansub;
21 | @SerializedName("audio")
22 | @Expose
23 | private String audio;
24 | @SerializedName("disc")
25 | @Expose
26 | private String disc;
27 | @SerializedName("hq")
28 | @Expose
29 | private Integer hq;
30 | @SerializedName("kwik")
31 | @Expose
32 | private String kwik;
33 | @SerializedName("kwik_adfly")
34 | @Expose
35 | private String kwikAdfly;
36 | @SerializedName("kwik_shst")
37 | @Expose
38 | private String kwikShst;
39 | @SerializedName("server")
40 | @Expose
41 | private String server;
42 |
43 | public Integer getFilesize() {
44 | return filesize;
45 | }
46 |
47 | public void setFilesize(Integer filesize) {
48 | this.filesize = filesize;
49 | }
50 |
51 | public String getCrc32() {
52 | return crc32;
53 | }
54 |
55 | public void setCrc32(String crc32) {
56 | this.crc32 = crc32;
57 | }
58 |
59 | public String getRevision() {
60 | return revision;
61 | }
62 |
63 | public void setRevision(String revision) {
64 | this.revision = revision;
65 | }
66 |
67 | public String getFansub() {
68 | return fansub;
69 | }
70 |
71 | public void setFansub(String fansub) {
72 | this.fansub = fansub;
73 | }
74 |
75 | public String getAudio() {
76 | return audio;
77 | }
78 |
79 | public void setAudio(String audio) {
80 | this.audio = audio;
81 | }
82 |
83 | public String getDisc() {
84 | return disc;
85 | }
86 |
87 | public void setDisc(String disc) {
88 | this.disc = disc;
89 | }
90 |
91 | public Integer getHq() {
92 | return hq;
93 | }
94 |
95 | public void setHq(Integer hq) {
96 | this.hq = hq;
97 | }
98 |
99 | public String getKwik() {
100 | return kwik;
101 | }
102 |
103 | public void setKwik(String kwik) {
104 | this.kwik = kwik;
105 | }
106 |
107 | public String getKwikAdfly() {
108 | return kwikAdfly;
109 | }
110 |
111 | public void setKwikAdfly(String kwikAdfly) {
112 | this.kwikAdfly = kwikAdfly;
113 | }
114 |
115 | public String getKwikShst() {
116 | return kwikShst;
117 | }
118 |
119 | public void setKwikShst(String kwikShst) {
120 | this.kwikShst = kwikShst;
121 | }
122 |
123 | public String getServer() {
124 | return server;
125 | }
126 |
127 | public void setServer(String server) {
128 | this.server = server;
129 | }
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/PaheModel/ResolutionURLs/_480.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class _480 {
8 |
9 | @SerializedName("filesize")
10 | @Expose
11 | private Integer filesize;
12 | @SerializedName("crc32")
13 | @Expose
14 | private String crc32;
15 | @SerializedName("revision")
16 | @Expose
17 | private String revision;
18 | @SerializedName("fansub")
19 | @Expose
20 | private String fansub;
21 | @SerializedName("audio")
22 | @Expose
23 | private String audio;
24 | @SerializedName("disc")
25 | @Expose
26 | private String disc;
27 | @SerializedName("hq")
28 | @Expose
29 | private Integer hq;
30 | @SerializedName("kwik")
31 | @Expose
32 | private String kwik;
33 | @SerializedName("kwik_adfly")
34 | @Expose
35 | private String kwikAdfly;
36 | @SerializedName("kwik_shst")
37 | @Expose
38 | private String kwikShst;
39 | @SerializedName("server")
40 | @Expose
41 | private String server;
42 |
43 | public Integer getFilesize() {
44 | return filesize;
45 | }
46 |
47 | public void setFilesize(Integer filesize) {
48 | this.filesize = filesize;
49 | }
50 |
51 | public String getCrc32() {
52 | return crc32;
53 | }
54 |
55 | public void setCrc32(String crc32) {
56 | this.crc32 = crc32;
57 | }
58 |
59 | public String getRevision() {
60 | return revision;
61 | }
62 |
63 | public void setRevision(String revision) {
64 | this.revision = revision;
65 | }
66 |
67 | public String getFansub() {
68 | return fansub;
69 | }
70 |
71 | public void setFansub(String fansub) {
72 | this.fansub = fansub;
73 | }
74 |
75 | public String getAudio() {
76 | return audio;
77 | }
78 |
79 | public void setAudio(String audio) {
80 | this.audio = audio;
81 | }
82 |
83 | public String getDisc() {
84 | return disc;
85 | }
86 |
87 | public void setDisc(String disc) {
88 | this.disc = disc;
89 | }
90 |
91 | public Integer getHq() {
92 | return hq;
93 | }
94 |
95 | public void setHq(Integer hq) {
96 | this.hq = hq;
97 | }
98 |
99 | public String getKwik() {
100 | return kwik;
101 | }
102 |
103 | public void setKwik(String kwik) {
104 | this.kwik = kwik;
105 | }
106 |
107 | public String getKwikAdfly() {
108 | return kwikAdfly;
109 | }
110 |
111 | public void setKwikAdfly(String kwikAdfly) {
112 | this.kwikAdfly = kwikAdfly;
113 | }
114 |
115 | public String getKwikShst() {
116 | return kwikShst;
117 | }
118 |
119 | public void setKwikShst(String kwikShst) {
120 | this.kwikShst = kwikShst;
121 | }
122 |
123 | public String getServer() {
124 | return server;
125 | }
126 |
127 | public void setServer(String server) {
128 | this.server = server;
129 | }
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/PaheModel/ResolutionURLs/_720.java:
--------------------------------------------------------------------------------
1 |
2 | package net.vapormusic.animexstream.utils.model.PaheModel.ResolutionURLs;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class _720 {
8 |
9 | @SerializedName("filesize")
10 | @Expose
11 | private Integer filesize;
12 | @SerializedName("crc32")
13 | @Expose
14 | private String crc32;
15 | @SerializedName("revision")
16 | @Expose
17 | private String revision;
18 | @SerializedName("fansub")
19 | @Expose
20 | private String fansub;
21 | @SerializedName("audio")
22 | @Expose
23 | private String audio;
24 | @SerializedName("disc")
25 | @Expose
26 | private String disc;
27 | @SerializedName("hq")
28 | @Expose
29 | private Integer hq;
30 | @SerializedName("kwik")
31 | @Expose
32 | private String kwik;
33 | @SerializedName("kwik_adfly")
34 | @Expose
35 | private String kwikAdfly;
36 | @SerializedName("kwik_shst")
37 | @Expose
38 | private String kwikShst;
39 | @SerializedName("server")
40 | @Expose
41 | private String server;
42 |
43 | public Integer getFilesize() {
44 | return filesize;
45 | }
46 |
47 | public void setFilesize(Integer filesize) {
48 | this.filesize = filesize;
49 | }
50 |
51 | public String getCrc32() {
52 | return crc32;
53 | }
54 |
55 | public void setCrc32(String crc32) {
56 | this.crc32 = crc32;
57 | }
58 |
59 | public String getRevision() {
60 | return revision;
61 | }
62 |
63 | public void setRevision(String revision) {
64 | this.revision = revision;
65 | }
66 |
67 | public String getFansub() {
68 | return fansub;
69 | }
70 |
71 | public void setFansub(String fansub) {
72 | this.fansub = fansub;
73 | }
74 |
75 | public String getAudio() {
76 | return audio;
77 | }
78 |
79 | public void setAudio(String audio) {
80 | this.audio = audio;
81 | }
82 |
83 | public String getDisc() {
84 | return disc;
85 | }
86 |
87 | public void setDisc(String disc) {
88 | this.disc = disc;
89 | }
90 |
91 | public Integer getHq() {
92 | return hq;
93 | }
94 |
95 | public void setHq(Integer hq) {
96 | this.hq = hq;
97 | }
98 |
99 | public String getKwik() {
100 | return kwik;
101 | }
102 |
103 | public void setKwik(String kwik) {
104 | this.kwik = kwik;
105 | }
106 |
107 | public String getKwikAdfly() {
108 | return kwikAdfly;
109 | }
110 |
111 | public void setKwikAdfly(String kwikAdfly) {
112 | this.kwikAdfly = kwikAdfly;
113 | }
114 |
115 | public String getKwikShst() {
116 | return kwikShst;
117 | }
118 |
119 | public void setKwikShst(String kwikShst) {
120 | this.kwikShst = kwikShst;
121 | }
122 |
123 | public String getServer() {
124 | return server;
125 | }
126 |
127 | public void setServer(String server) {
128 | this.server = server;
129 | }
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/PaheModel/SessionURLs/Data.java:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model.PaheModel.SessionURLs;
2 |
3 | public class Data
4 | {
5 | private String duration;
6 |
7 | private String episode2;
8 |
9 | private String session;
10 |
11 | private String filler;
12 |
13 | private String edition;
14 |
15 | private String created_at;
16 |
17 | private String episode;
18 |
19 | private String disc;
20 |
21 | private String id;
22 |
23 | private String title;
24 |
25 | private String anime_id;
26 |
27 | private String snapshot;
28 |
29 | public String getDuration ()
30 | {
31 | return duration;
32 | }
33 |
34 | public void setDuration (String duration)
35 | {
36 | this.duration = duration;
37 | }
38 |
39 | public String getEpisode2 ()
40 | {
41 | return episode2;
42 | }
43 |
44 | public void setEpisode2 (String episode2)
45 | {
46 | this.episode2 = episode2;
47 | }
48 |
49 | public String getSession ()
50 | {
51 | return session;
52 | }
53 |
54 | public void setSession (String session)
55 | {
56 | this.session = session;
57 | }
58 |
59 | public String getFiller ()
60 | {
61 | return filler;
62 | }
63 |
64 | public void setFiller (String filler)
65 | {
66 | this.filler = filler;
67 | }
68 |
69 | public String getEdition ()
70 | {
71 | return edition;
72 | }
73 |
74 | public void setEdition (String edition)
75 | {
76 | this.edition = edition;
77 | }
78 |
79 | public String getCreated_at ()
80 | {
81 | return created_at;
82 | }
83 |
84 | public void setCreated_at (String created_at)
85 | {
86 | this.created_at = created_at;
87 | }
88 |
89 | public String getEpisode ()
90 | {
91 | return episode;
92 | }
93 |
94 | public void setEpisode (String episode)
95 | {
96 | this.episode = episode;
97 | }
98 |
99 | public String getDisc ()
100 | {
101 | return disc;
102 | }
103 |
104 | public void setDisc (String disc)
105 | {
106 | this.disc = disc;
107 | }
108 |
109 | public String getId ()
110 | {
111 | return id;
112 | }
113 |
114 | public void setId (String id)
115 | {
116 | this.id = id;
117 | }
118 |
119 | public String getTitle ()
120 | {
121 | return title;
122 | }
123 |
124 | public void setTitle (String title)
125 | {
126 | this.title = title;
127 | }
128 |
129 | public String getAnime_id ()
130 | {
131 | return anime_id;
132 | }
133 |
134 | public void setAnime_id (String anime_id)
135 | {
136 | this.anime_id = anime_id;
137 | }
138 |
139 | public String getSnapshot ()
140 | {
141 | return snapshot;
142 | }
143 |
144 | public void setSnapshot (String snapshot)
145 | {
146 | this.snapshot = snapshot;
147 | }
148 |
149 | @Override
150 | public String toString()
151 | {
152 | return "ClassPojo [duration = "+duration+", episode2 = "+episode2+", session = "+session+", filler = "+filler+", edition = "+edition+", created_at = "+created_at+", episode = "+episode+", disc = "+disc+", id = "+id+", title = "+title+", anime_id = "+anime_id+", snapshot = "+snapshot+"]";
153 | }
154 | }
155 |
156 |
157 |
158 |
159 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/PaheModel/SessionURLs/SessionsURLs.java:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model.PaheModel.SessionURLs;
2 |
3 | public class SessionsURLs
4 | {
5 | private String per_page;
6 |
7 | private String total;
8 |
9 | private Data[] data;
10 |
11 | private String last_page;
12 |
13 | private String next_page_url;
14 |
15 | private String from;
16 |
17 | private String to;
18 |
19 | private String prev_page_url;
20 |
21 | private String current_page;
22 |
23 | public String getPer_page ()
24 | {
25 | return per_page;
26 | }
27 |
28 | public void setPer_page (String per_page)
29 | {
30 | this.per_page = per_page;
31 | }
32 |
33 | public String getTotal ()
34 | {
35 | return total;
36 | }
37 |
38 | public void setTotal (String total)
39 | {
40 | this.total = total;
41 | }
42 |
43 | public Data[] getData ()
44 | {
45 | return data;
46 | }
47 |
48 | public void setData (Data[] data)
49 | {
50 | this.data = data;
51 | }
52 |
53 | public String getLast_page ()
54 | {
55 | return last_page;
56 | }
57 |
58 | public void setLast_page (String last_page)
59 | {
60 | this.last_page = last_page;
61 | }
62 |
63 | public String getNext_page_url ()
64 | {
65 | return next_page_url;
66 | }
67 |
68 | public void setNext_page_url (String next_page_url)
69 | {
70 | this.next_page_url = next_page_url;
71 | }
72 |
73 | public String getFrom ()
74 | {
75 | return from;
76 | }
77 |
78 | public void setFrom (String from)
79 | {
80 | this.from = from;
81 | }
82 |
83 | public String getTo ()
84 | {
85 | return to;
86 | }
87 |
88 | public void setTo (String to)
89 | {
90 | this.to = to;
91 | }
92 |
93 | public String getPrev_page_url ()
94 | {
95 | return prev_page_url;
96 | }
97 |
98 | public void setPrev_page_url (String prev_page_url)
99 | {
100 | this.prev_page_url = prev_page_url;
101 | }
102 |
103 | public String getCurrent_page ()
104 | {
105 | return current_page;
106 | }
107 |
108 | public void setCurrent_page (String current_page)
109 | {
110 | this.current_page = current_page;
111 | }
112 |
113 | @Override
114 | public String toString()
115 | {
116 | return "ClassPojo [per_page = "+per_page+", total = "+total+", data = "+data+", last_page = "+last_page+", next_page_url = "+next_page_url+", from = "+from+", to = "+to+", prev_page_url = "+prev_page_url+", current_page = "+current_page+"]";
117 | }
118 | }
119 |
120 |
121 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/SettingsModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | import io.realm.RealmModel
4 | import io.realm.RealmObject
5 | import io.realm.annotations.PrimaryKey
6 |
7 |
8 | public open class SettingsModel (
9 | // @PrimaryKey
10 | var paheanimeon: Boolean = false,
11 | var nightmodeon: Boolean = false,
12 | var playercontrolson : Boolean = true,
13 | var malsyncon : Boolean = false,
14 | var malaccesstoken : String = "",
15 | var malrefreshtoken : String = "",
16 | var malaccesstime : Int = 0,
17 | var googlecdn: Boolean = false
18 | ): RealmObject()
19 |
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/SuggestionModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | import com.google.gson.annotations.Expose
4 | import com.google.gson.annotations.SerializedName
5 |
6 | class SuggestionModel {
7 | @SerializedName("content")
8 | @Expose
9 | var content: String? = null
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/UpdateModel.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | data class UpdateModel(
4 | val versionCode: Long,
5 | val whatsNew: String
6 | )
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/model/WatchedEpisode.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.model
2 |
3 | import io.realm.RealmObject
4 | import io.realm.annotations.PrimaryKey
5 |
6 | open class WatchedEpisode(
7 | @PrimaryKey
8 | var id: Int = 0,
9 | var watchedDuration: Long? = 0,
10 | var watchedPercentage: Long? = 0,
11 | var animeName: String = ""
12 | ): RealmObject()
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/realm/InitalizeRealm.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.realm
2 |
3 | import android.content.Context
4 | import io.realm.Realm
5 | import io.realm.RealmConfiguration
6 |
7 | class InitalizeRealm{
8 | companion object{
9 |
10 | private lateinit var config: RealmConfiguration
11 | fun initializeRealm(context: Context){
12 | Realm.init(context)
13 | config = RealmConfiguration.Builder().name("animexstream.realm").schemaVersion(1).deleteRealmIfMigrationNeeded().build()
14 | }
15 |
16 | fun getConfig(): RealmConfiguration{
17 | return config
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/net/vapormusic/animexstream/utils/rertofit/RetrofitHelper.java:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream.utils.rertofit;
2 |
3 |
4 | import android.os.Build;
5 | import android.util.Log;
6 |
7 | import net.vapormusic.animexstream.BuildConfig;
8 | import net.vapormusic.animexstream.Tls12SocketFactory;
9 | import net.vapormusic.animexstream.utils.constants.C;
10 |
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | import javax.net.ssl.SSLContext;
16 |
17 | import okhttp3.CipherSuite;
18 | import okhttp3.ConnectionSpec;
19 | import okhttp3.OkHttpClient;
20 | import okhttp3.TlsVersion;
21 | import okhttp3.logging.HttpLoggingInterceptor;
22 | import retrofit2.Retrofit;
23 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
24 | import retrofit2.converter.gson.GsonConverterFactory;
25 |
26 | public class RetrofitHelper {
27 |
28 | private static Retrofit retrofitInstance;
29 |
30 | static {
31 | try {
32 | RetrofitHelper retrofitHelper = new RetrofitHelper();
33 | } catch (Exception e) {
34 | throw new RuntimeException("Exception occurred in creating singleton instance");
35 | }
36 | }
37 |
38 | private RetrofitHelper(){
39 | OkHttpClient.Builder client;
40 |
41 | if(BuildConfig.DEBUG){
42 | HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
43 | interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
44 | client = new OkHttpClient.Builder()
45 | .retryOnConnectionFailure(true)
46 | .addInterceptor(interceptor);
47 |
48 | }else{
49 | client = new OkHttpClient.Builder()
50 | .retryOnConnectionFailure(true);
51 |
52 | }
53 |
54 | retrofitInstance = new Retrofit.Builder()
55 | .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
56 | .client(enableTls12OnPreLollipop2(client).build())
57 | .baseUrl(C.Companion.getBASE_URL())
58 | .addConverterFactory(GsonConverterFactory.create()).build();
59 | }
60 |
61 |
62 | public static Retrofit getRetrofitInstance(){
63 |
64 | return retrofitInstance;
65 |
66 | }
67 | public OkHttpClient.Builder enableTls12OnPreLollipop2(OkHttpClient.Builder client) {
68 | if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
69 | try {
70 | SSLContext sc = SSLContext.getInstance("TLSv1.2");
71 | sc.init(null, null, null);
72 | client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));
73 |
74 | ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
75 | .tlsVersions(TlsVersion.TLS_1_2)
76 | .cipherSuites(
77 | CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
78 | CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
79 | CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
80 | CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
81 | CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
82 | CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
83 | CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
84 | CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
85 | CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
86 | CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
87 | CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
88 | CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
89 | .build();
90 |
91 | List specs = new ArrayList<>();
92 | specs.add(cs);
93 | specs.add(ConnectionSpec.COMPATIBLE_TLS);
94 | specs.add(ConnectionSpec.CLEARTEXT);
95 |
96 |
97 | client.connectionSpecs(specs);
98 | } catch (Exception exc) {
99 | Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
100 | }
101 | }
102 |
103 | return client;
104 | }
105 |
106 | }
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-night/stream.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/drawable-night/stream.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_brightness_3_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_home_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_settings.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_settings_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_brightness.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_error.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_favorite.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_file_download_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_internet.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_media_pause.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_media_play.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_media_seek_backward.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
14 |
18 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_media_seek_forward.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_play_button.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_search.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_unfavorite.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_volume.xml:
--------------------------------------------------------------------------------
1 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/list_selector_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/search_edit_text_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shadow_backgorund.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_sub_dub.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
15 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/splash_drawable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 | -
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/stream.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/drawable/stream.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_video_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/error_screen_video_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
22 |
23 |
38 |
39 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_favourite.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
25 |
26 |
42 |
43 |
52 |
53 |
61 |
62 |
63 |
76 |
77 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
23 |
24 |
38 |
52 |
53 |
64 |
65 |
66 |
76 |
77 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
15 |
16 |
27 |
28 |
38 |
39 |
45 |
46 |
63 |
64 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_video_player_placeholder.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/main_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
22 |
32 |
33 |
34 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycler_anime_common.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
22 |
23 |
28 |
29 |
30 |
47 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycler_anime_mini_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
25 |
26 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycler_anime_popular.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
22 |
23 |
28 |
29 |
30 |
49 |
50 |
65 |
66 |
76 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycler_anime_recent_sub_dub_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
20 |
21 |
27 |
28 |
36 |
37 |
42 |
43 |
44 |
63 |
64 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycler_episode_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
20 |
35 |
36 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycler_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tags_genre.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/web_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
17 |
18 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/bottom_navigation_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Anime X Stream
4 | Descubre
5 | reintentar
6 | Fecha de lanzamiento:
7 | Tipo:
8 | Estado:
9 | Episodio siguiente>
10 | <Episodio anterior
11 | Atras
12 | Buscar…
13 | Algo salió mal
14 | Sin conexión
15 | Favoritos
16 | Algo salió mal
17 | Error del servidor
18 | Añadido a Favoritos
19 | Eliminado de Favoritos
20 | Calidad
21 | ]]>
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | @color/header
4 | #3B3B44
5 | @color/header
6 |
7 | //Total Colors
8 | #0c0c0c
9 | #bababa
10 | #808080
11 | #161616
12 | #212121
13 |
14 | //Home Fragment
15 | @color/header
16 | @color/header
17 | #d63447
18 |
19 | //Recycler Items
20 | @color/media_player_controls_background
21 | @color/header
22 | @color/text_default
23 | @color/recycler_anime_type
24 | @color/recycler_anime_type
25 | @color/secondary_background
26 |
27 | //Recycler mini Header
28 | @color/text_default
29 | @color/recycler_mini_header_title
30 | //Recycler Popular
31 | @color/home_header
32 |
33 | //Search Fragment
34 | @color/favourite_back
35 |
36 |
37 | //Favourite
38 | @color/home_header
39 | @color/recycler_anime_title
40 |
41 | //Anime Info Fragment
42 | @color/favourite_back
43 | @color/recycler_anime_title
44 | @color/text_default
45 | #8f8f8f
46 | #595959
47 |
48 | //AnimeInfo Episodes
49 | #000000
50 | @color/progress
51 | #8f8f8f
52 |
53 |
54 | //Media Player Controls
55 | #ffffff
56 | #60000000
57 |
58 |
59 | //Shimmer Background
60 | #dddddd
61 |
62 | //Suggestion
63 | #32FFFFFF
64 | #0F000000
65 | #0C000000
66 | #0A000000
67 |
68 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | @color/header
4 | #3B3B44
5 | @color/header
6 |
7 | //Total Colors
8 | #FFFFFF
9 | #212121
10 | #808080
11 | #e5e5e5
12 | #EAEAEB
13 |
14 | //Home Fragment
15 | @color/header
16 | @color/header
17 | //Recycler Items
18 | @color/media_player_controls_background
19 | @color/header
20 | @color/text_default
21 | @color/recycler_anime_type
22 | @color/recycler_anime_type
23 | @color/secondary_background
24 |
25 | //Recycler mini Header
26 | @color/text_default
27 | @color/recycler_mini_header_title
28 | //Recycler Popular
29 | @color/home_header
30 |
31 | //Search Fragment
32 | @color/favourite_back
33 |
34 |
35 | //Favourite
36 | @color/home_header
37 | @color/recycler_anime_title
38 | #c9485b
39 |
40 | //Anime Info Fragment
41 | @color/favourite_back
42 | @color/recycler_anime_title
43 | @color/text_default
44 | #776E6E
45 | #3D3838
46 |
47 | //AnimeInfo Episodes
48 | #f8f8f8
49 | @color/progress
50 | #776E6E
51 |
52 |
53 | //Media Player Controls
54 | #ffffff
55 | #60000000
56 |
57 |
58 | //Shimmer Background
59 | #dddddd
60 |
61 | //Suggestion
62 | #32000000
63 | #0FFFFFFF
64 | #0CFFFFFF
65 | #0AFFFFFF
66 |
67 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 6dp
4 | 20dp
5 | 8dp
6 | 20dp
7 | 5dp
8 | 5dp
9 |
10 |
11 | 10dp
12 | 20dp
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Anime X Stream
3 | Browse
4 | retry
5 | Auto
6 | 1x
7 | Released:
8 | Type:
9 | Status:
10 | Next Episode>
11 | <Previous Episode
12 | Back Button
13 | Search
14 | Something Went Wrong
15 |
16 | No Internet Connection
17 | Favourites
18 | Something went Wrong
19 | Server Error
20 | Anime added to Favourites
21 | Anime removed from Favourites
22 | ]]>
23 | Video Quality
24 | Settings
25 | Toggle to Dark Mode
26 | Toggle to Light Mode
27 | Enable AnimePahe
28 | Disable AnimePahe and Use GoGoAnime Only
29 | MAL Sync: On
30 | MAL Sync: Off
31 | Volume/Brightness Control: On
32 | Volume/Brightness Control: Off
33 | Use Google Server (faster,1080p only)
34 | Use Default Server (multiple resolutions)
35 | Home
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
16 |
17 |
23 |
24 |
29 |
30 |
39 |
40 |
43 |
44 |
50 |
51 |
56 |
57 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/motion_scene.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
15 |
16 |
17 |
18 |
19 |
31 |
34 |
35 |
36 |
37 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
67 |
70 |
71 |
72 |
73 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/motion_scene_favourites.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
10 |
16 |
17 |
18 |
19 |
20 |
29 |
30 |
31 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
64 |
65 |
66 |
67 |
68 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/app/src/test/java/net/xblacky/animexstream/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package net.vapormusic.animexstream
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.71'
5 | repositories {
6 | google()
7 | jcenter()
8 |
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:4.0.0'
12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13 | classpath "io.realm:realm-gradle-plugin:6.0.2"
14 | def nav_version = "2.3.0-alpha04"
15 | classpath 'com.google.gms:google-services:4.3.3'
16 | classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
17 | classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta03'
18 | // NOTE: Do not place your application dependencies here; they belong
19 | // in the individual module build.gradle files
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | google()
26 | jcenter()
27 | maven{ url "https://dl.bintray.com/google/exoplayer/"}
28 | maven {
29 | url "https://jitpack.io"
30 | }
31 | }
32 | }
33 |
34 | task clean(type: Delete) {
35 | delete rootProject.buildDir
36 | }
37 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## For more details on how to configure your build environment visit
2 | # http://www.gradle.org/docs/current/userguide/build_environment.html
3 | #
4 | # Specifies the JVM arguments used for the daemon process.
5 | # The setting is particularly useful for tweaking memory settings.
6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
8 | #
9 | # When configured, Gradle will run in incubating parallel mode.
10 | # This option should only be used with decoupled projects. More details, visit
11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
12 | # org.gradle.parallel=true
13 | #Mon Jun 08 23:15:51 IST 2020
14 | android.enableJetifier=true
15 | android.useAndroidX=true
16 | kotlin.code.style=official
17 | org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jun 08 23:14:13 IST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/meta/android/animexstream.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/animexstream.png
--------------------------------------------------------------------------------
/meta/android/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/download.png
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_01.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_02.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_03.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_04.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_05.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_05.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_06.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_06.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_07.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_07.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_08.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_08.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_09.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_09.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_10.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_11.jpg
--------------------------------------------------------------------------------
/meta/android/screenshots/screenshot_12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/androiddevnotesforks/AnimeXStream/ea8a900769abaff526f934be65eafe871209ca66/meta/android/screenshots/screenshot_12.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | rootProject.name='Anime X Stream'
3 |
--------------------------------------------------------------------------------