├── .gitignore
├── .idea
├── .gitignore
├── appInsightsSettings.xml
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── compiler.xml
├── deploymentTargetDropDown.xml
├── deploymentTargetSelector.xml
├── gradle.xml
├── kotlinc.xml
├── migrations.xml
├── misc.xml
├── other.xml
└── vcs.xml
├── Database
├── .gitignore
├── build.gradle.kts
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── google
│ │ └── android
│ │ └── piyush
│ │ └── database
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ └── com
│ │ └── google
│ │ └── android
│ │ └── piyush
│ │ └── database
│ │ ├── DopamineDatabase.kt
│ │ ├── dao
│ │ └── DopamineDao.kt
│ │ ├── entities
│ │ ├── EntityFavouritePlaylist.kt
│ │ ├── EntityRecentVideos.kt
│ │ └── EntityVideoSearch.kt
│ │ ├── model
│ │ ├── CustomPlaylistView.kt
│ │ └── CustomPlaylists.kt
│ │ ├── repository
│ │ └── DopamineDatabaseRepository.kt
│ │ └── viewModel
│ │ └── DatabaseViewModel.kt
│ └── test
│ └── java
│ └── com
│ └── google
│ └── android
│ └── piyush
│ └── database
│ └── ExampleUnitTest.kt
├── README.md
├── Youtube
├── .gitignore
├── build.gradle.kts
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── google
│ │ └── android
│ │ └── piyush
│ │ └── youtube
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ └── com
│ │ └── google
│ │ └── android
│ │ └── piyush
│ │ └── youtube
│ │ ├── model
│ │ ├── ContentDetails.kt
│ │ ├── Item.kt
│ │ ├── SearchTube.kt
│ │ ├── SearchTubeItems.kt
│ │ ├── Shorts.kt
│ │ ├── Snippet.kt
│ │ ├── Youtube.kt
│ │ ├── channelDetails
│ │ │ └── YoutubeChannel.kt
│ │ └── channelPlaylists
│ │ │ └── ChannelPlaylists.kt
│ │ ├── repository
│ │ ├── YoutubeRepository.kt
│ │ └── YoutubeRepositoryImpl.kt
│ │ ├── utilities
│ │ ├── YoutubeClient.kt
│ │ └── YoutubeResource.kt
│ │ └── viewModels
│ │ ├── HomeViewModel.kt
│ │ ├── LibraryViewModel.kt
│ │ └── ShortsViewModel.kt
│ └── test
│ └── java
│ └── com
│ └── google
│ └── android
│ └── piyush
│ └── youtube
│ └── ExampleUnitTest.kt
├── app
├── .gitignore
├── 1.jpeg
├── 10.jpg
├── 11.jpg
├── 12.jpg
├── 13.jpg
├── 14.jpg
├── 15.jpg
├── 16.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
├── 5.jpg
├── 6.jpg
├── 7.jpg
├── 8.jpg
├── 9.jpg
├── build.gradle.kts
├── google-services.json
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── google
│ │ └── android
│ │ └── piyush
│ │ └── dopamine
│ │ └── ExampleInstrumentedTest.kt
│ ├── google-services.json
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── google
│ │ │ └── android
│ │ │ └── piyush
│ │ │ └── dopamine
│ │ │ ├── DopamineApp.kt
│ │ │ ├── activities
│ │ │ ├── AboutDeveloper.kt
│ │ │ ├── AboutDopamine.kt
│ │ │ ├── AboutUs.kt
│ │ │ ├── CVPlaylist.kt
│ │ │ ├── DopamineHome.kt
│ │ │ ├── DopamineUserProfile.kt
│ │ │ ├── DopamineVideoWatchHistory.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── YoutubeChannel.kt
│ │ │ ├── YoutubeChannelPlaylistsVideos.kt
│ │ │ └── YoutubePlayer.kt
│ │ │ ├── adapters
│ │ │ ├── CustomPlayListVAdapter.kt
│ │ │ ├── CustomPlaylistsAdapter.kt
│ │ │ ├── CustomPlaylistsVDataAdapter.kt
│ │ │ ├── HomeAdapter.kt
│ │ │ ├── LibraryAdapter.kt
│ │ │ ├── RecentVideosAdapter.kt
│ │ │ ├── SearchAdapter.kt
│ │ │ ├── SearchHistoryAdapter.kt
│ │ │ ├── ShortsAdapter.kt
│ │ │ ├── YourFavouriteVideosAdapter.kt
│ │ │ ├── YoutubeChannelPlaylistsAdapter.kt
│ │ │ └── YoutubePlaylistsVideosAdapter.kt
│ │ │ ├── authentication
│ │ │ ├── User.kt
│ │ │ ├── repository
│ │ │ │ └── UserAuthRepositoryImpl.kt
│ │ │ ├── utilities
│ │ │ │ └── AuthUtility.kt
│ │ │ └── viewModel
│ │ │ │ └── UserAuthViewModel.kt
│ │ │ ├── beta
│ │ │ └── DopamineApp.kt
│ │ │ ├── fragments
│ │ │ ├── Home.kt
│ │ │ ├── Library.kt
│ │ │ ├── Search.kt
│ │ │ └── Shorts.kt
│ │ │ ├── utilities
│ │ │ └── DopamineUtilities.kt
│ │ │ ├── viewHolders
│ │ │ ├── CustomPlayListVHolder.kt
│ │ │ ├── CustomPlaylistsVDataHolder.kt
│ │ │ ├── CustomPlaylistsViewHolder.kt
│ │ │ ├── HomeViewHolder.kt
│ │ │ ├── LibraryViewHolder.kt
│ │ │ ├── RecentVideosViewHolder.kt
│ │ │ ├── SearchHistoryViewHolder.kt
│ │ │ ├── SearchViewHolder.kt
│ │ │ ├── ShortsViewHolder.kt
│ │ │ ├── YourFavouriteVideosViewHolder.kt
│ │ │ ├── YoutubeChannelPlaylistsViewHolder.kt
│ │ │ └── YoutubePlaylistsVideosViewHolder.kt
│ │ │ └── viewModels
│ │ │ ├── DopamineHomeViewModel.kt
│ │ │ ├── SearchViewModel.kt
│ │ │ ├── SharedViewModel.kt
│ │ │ ├── YoutubeChannelPlaylistsVideosViewModel.kt
│ │ │ ├── YoutubeChannelViewModel.kt
│ │ │ └── YoutubePlayerViewModel.kt
│ └── res
│ │ ├── drawable
│ │ ├── checked.xml
│ │ ├── clear.xml
│ │ ├── default_user.xml
│ │ ├── done.xml
│ │ ├── download_circle.xml
│ │ ├── facebook.xml
│ │ ├── get_data_problem.xml
│ │ ├── github.xml
│ │ ├── google_material_design_logo.xml
│ │ ├── ic_add.xml
│ │ ├── ic_alert.xml
│ │ ├── ic_android.xml
│ │ ├── ic_back.xml
│ │ ├── ic_beta_app.xml
│ │ ├── ic_copy_text.xml
│ │ ├── ic_dialog_error.xml
│ │ ├── ic_dopamine.xml
│ │ ├── ic_download.xml
│ │ ├── ic_facebook.xml
│ │ ├── ic_favourite.xml
│ │ ├── ic_favourite_videos_fill.xml
│ │ ├── ic_favourite_videos_out.xml
│ │ ├── ic_google.xml
│ │ ├── ic_history.xml
│ │ ├── ic_home.xml
│ │ ├── ic_home_fill.xml
│ │ ├── ic_home_out.xml
│ │ ├── ic_info.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_launcher_foreground.xml
│ │ ├── ic_library.xml
│ │ ├── ic_library_fill.xml
│ │ ├── ic_library_out.xml
│ │ ├── ic_like_video.xml
│ │ ├── ic_picture_in_picture.xml
│ │ ├── ic_search.xml
│ │ ├── ic_search_background.xml
│ │ ├── ic_select.xml
│ │ ├── ic_settings.xml
│ │ ├── ic_shorts.xml
│ │ ├── ic_shorts_fill.xml
│ │ ├── ic_shorts_out.xml
│ │ ├── ic_sign_out.xml
│ │ ├── ic_theme.xml
│ │ ├── ic_update.xml
│ │ ├── ic_view.xml
│ │ ├── ic_voice_search.xml
│ │ ├── idcard.xml
│ │ ├── instagram.xml
│ │ ├── location.xml
│ │ ├── mail.xml
│ │ ├── mail_outline.xml
│ │ ├── memory.xml
│ │ ├── phone.xml
│ │ ├── round_add_24.xml
│ │ ├── round_download_24.xml
│ │ ├── round_local_phone_24.xml
│ │ ├── round_sd_storage_24.xml
│ │ ├── share.xml
│ │ ├── unchecked.xml
│ │ ├── video.xml
│ │ ├── website.xml
│ │ ├── whatsapp.xml
│ │ └── wifi_off.xml
│ │ ├── font
│ │ ├── circular_spotify.otf
│ │ ├── circular_std.otf
│ │ ├── gotham.ttf
│ │ └── proxima_nova.otf
│ │ ├── layout-land
│ │ └── activity_main.xml
│ │ ├── layout
│ │ ├── activity_about_developer.xml
│ │ ├── activity_about_dopamine.xml
│ │ ├── activity_about_us.xml
│ │ ├── activity_cvplaylist.xml
│ │ ├── activity_dopamine_home.xml
│ │ ├── activity_dopamine_user_profile.xml
│ │ ├── activity_dopamine_video_watch_history.xml
│ │ ├── activity_main.xml
│ │ ├── activity_youtube_channel.xml
│ │ ├── activity_youtube_channel_playlists_videos.xml
│ │ ├── activity_youtube_player.xml
│ │ ├── app_dopamine_image.xml
│ │ ├── bottom_sheet_add_playlist.xml
│ │ ├── bottom_sheet_add_to_a_playlist.xml
│ │ ├── fragment_home.xml
│ │ ├── fragment_library.xml
│ │ ├── fragment_search.xml
│ │ ├── fragment_shorts.xml
│ │ ├── item_activity_video_views_history.xml
│ │ ├── item_activity_youtube_channel_playlists.xml
│ │ ├── item_activity_youtube_playlists_videos.xml
│ │ ├── item_custom_dialog.xml
│ │ ├── item_custom_playlists_view.xml
│ │ ├── item_frag_cust_lst_view.xml
│ │ ├── item_fragment_home.xml
│ │ ├── item_fragment_library.xml
│ │ ├── item_fragment_library_favorites_shimmer.xml
│ │ ├── item_fragment_library_your_favourite_videos.xml
│ │ ├── item_fragment_search.xml
│ │ ├── item_fragment_search_videos.xml
│ │ ├── item_fragment_shorts.xml
│ │ ├── shimmer_item_fragment_home.xml
│ │ ├── shimmer_item_fragment_library.xml
│ │ └── shimmer_item_fragment_shorts.xml
│ │ ├── menu
│ │ ├── bottom_nav_menu.xml
│ │ ├── search_menu.xml
│ │ └── user_profile_menu.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── raw
│ │ └── auth.json
│ │ ├── values-night
│ │ └── themes.xml
│ │ ├── values
│ │ ├── arrays.xml
│ │ ├── colors.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ ├── data_extraction_rules.xml
│ │ └── provider_paths.xml
│ └── test
│ └── java
│ └── com
│ └── google
│ └── android
│ └── piyush
│ └── dopamine
│ └── ExampleUnitTest.kt
├── build.gradle.kts
├── google-services.json
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle.kts
└── version.json
/.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 | local.properties
16 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/appInsightsSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
26 |
27 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetDropDown.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetSelector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/other.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Database/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/Database/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.library)
3 | alias(libs.plugins.jetbrains.kotlin.android)
4 | id("com.google.devtools.ksp")
5 | }
6 |
7 | android {
8 | namespace = "com.google.android.piyush.database"
9 | compileSdk = 34
10 |
11 | defaultConfig {
12 | minSdk = 24
13 |
14 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles("consumer-rules.pro")
16 | }
17 |
18 | buildTypes {
19 | release {
20 | isMinifyEnabled = false
21 | proguardFiles(
22 | getDefaultProguardFile("proguard-android-optimize.txt"),
23 | "proguard-rules.pro"
24 | )
25 | }
26 | }
27 | compileOptions {
28 | sourceCompatibility = JavaVersion.VERSION_1_8
29 | targetCompatibility = JavaVersion.VERSION_1_8
30 | }
31 | kotlinOptions {
32 | jvmTarget = "1.8"
33 | }
34 | }
35 |
36 | dependencies {
37 |
38 | implementation(libs.androidx.core.ktx)
39 | implementation(libs.androidx.appcompat)
40 | implementation(libs.material)
41 | implementation(libs.androidx.room.ktx)
42 | implementation(libs.androidx.room.runtime)
43 | implementation(libs.firebase.auth.ktx)
44 | ksp(libs.androidx.room.compiler)
45 | implementation(libs.androidx.lifecycle.viewmodel.ktx)
46 | testImplementation(libs.junit)
47 | androidTestImplementation(libs.androidx.junit)
48 | androidTestImplementation(libs.androidx.espresso.core)
49 | }
--------------------------------------------------------------------------------
/Database/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/Database/consumer-rules.pro
--------------------------------------------------------------------------------
/Database/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
--------------------------------------------------------------------------------
/Database/src/androidTest/java/com/google/android/piyush/database/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.google.android.piyush.database.test", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/Database/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Database/src/main/java/com/google/android/piyush/database/DopamineDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database
2 |
3 | import android.content.Context
4 | import androidx.room.Database
5 | import androidx.room.Room
6 | import androidx.room.RoomDatabase
7 | import com.google.android.piyush.database.dao.DopamineDao
8 | import com.google.android.piyush.database.entities.EntityFavouritePlaylist
9 | import com.google.android.piyush.database.entities.EntityRecentVideos
10 | import com.google.android.piyush.database.entities.EntityVideoSearch
11 |
12 | @Database(entities = [EntityVideoSearch::class, EntityRecentVideos::class,EntityFavouritePlaylist::class], version = 1, exportSchema = false)
13 | abstract class DopamineDatabase : RoomDatabase() {
14 | abstract fun dopamineDao(): DopamineDao
15 | companion object {
16 | @Volatile
17 | private var INSTANCE: DopamineDatabase? = null
18 | private const val DATABASE_NAME = "dopamine_database"
19 |
20 | fun getDatabase(context: Context): DopamineDatabase {
21 | return INSTANCE ?: synchronized(this) {
22 | val instance = Room.databaseBuilder(
23 | context.applicationContext,
24 | DopamineDatabase::class.java,
25 | DATABASE_NAME
26 | ).build()
27 | INSTANCE = instance
28 | instance
29 | }
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Database/src/main/java/com/google/android/piyush/database/dao/DopamineDao.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database.dao
2 |
3 | import androidx.room.Dao
4 | import androidx.room.Insert
5 | import androidx.room.Query
6 | import com.google.android.piyush.database.entities.EntityFavouritePlaylist
7 | import com.google.android.piyush.database.entities.EntityRecentVideos
8 | import com.google.android.piyush.database.entities.EntityVideoSearch
9 |
10 | @Dao
11 | interface DopamineDao {
12 | @Insert
13 | suspend fun insertSearchVideos(vararg searchVideo: EntityVideoSearch)
14 | @Query("SELECT * FROM search_table")
15 | suspend fun getSearchVideoList(): List
16 | @Query("DELETE FROM search_table")
17 | suspend fun deleteSearchVideoList()
18 | @Insert
19 | suspend fun insertFavouriteVideos(vararg favouriteVideo : EntityFavouritePlaylist)
20 | @Query("SELECT videoId FROM favorite_playlist WHERE videoId = :videoId")
21 | suspend fun isFavouriteVideo (videoId : String) : String
22 |
23 | @Query("DELETE FROM favorite_playlist WHERE videoId = :videoId")
24 | suspend fun deleteFavouriteVideo(videoId : String)
25 | @Query("Select * FROM favorite_playlist")
26 | suspend fun getFavouritePlayList(): List
27 | @Insert
28 | suspend fun insertRecentVideos(vararg fav: EntityRecentVideos)
29 | @Query("Select * FROM recent_videos")
30 | suspend fun getRecentVideos(): List
31 | @Query("SELECT videoId FROM recent_videos WHERE videoId = :videoId")
32 | suspend fun isRecentVideo(videoId : String) : String
33 | @Query("Update recent_videos SET timing = :time WHERE videoId = :videoId")
34 | suspend fun updateRecentVideo(videoId: String, time: String)
35 | @Query("DELETE FROM recent_videos")
36 | suspend fun deleteRecentVideo()
37 |
38 | }
--------------------------------------------------------------------------------
/Database/src/main/java/com/google/android/piyush/database/entities/EntityFavouritePlaylist.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database.entities
2 |
3 | import androidx.room.Entity
4 | import androidx.room.PrimaryKey
5 |
6 | @Entity(tableName = "favorite_playlist")
7 | data class EntityFavouritePlaylist (
8 | @PrimaryKey val videoId: String,
9 | val title: String?,
10 | val thumbnail: String?,
11 | val channelTitle: String?,
12 | val channelId : String? = null
13 | )
--------------------------------------------------------------------------------
/Database/src/main/java/com/google/android/piyush/database/entities/EntityRecentVideos.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database.entities
2 |
3 | import androidx.room.Entity
4 | import androidx.room.PrimaryKey
5 |
6 | @Entity(tableName = "recent_videos")
7 | data class EntityRecentVideos(
8 | @PrimaryKey val id : Int,
9 | val videoId: String?,
10 | val title: String?,
11 | val thumbnail: String?,
12 | val timing : String?,
13 | val channelId : String? = null,
14 | )
15 |
--------------------------------------------------------------------------------
/Database/src/main/java/com/google/android/piyush/database/entities/EntityVideoSearch.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database.entities
2 |
3 | import androidx.room.ColumnInfo
4 | import androidx.room.Entity
5 | import androidx.room.PrimaryKey
6 |
7 | @Entity(tableName = "search_table")
8 | data class EntityVideoSearch(
9 | @PrimaryKey(autoGenerate = true)
10 | @ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER) val id: Int,
11 | @ColumnInfo(name = "search", typeAffinity = ColumnInfo.TEXT) val search: String?
12 | )
--------------------------------------------------------------------------------
/Database/src/main/java/com/google/android/piyush/database/model/CustomPlaylistView.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database.model
2 |
3 | data class CustomPlaylistView(
4 | val playListName : String,
5 | val playListDescription : String
6 | )
7 |
--------------------------------------------------------------------------------
/Database/src/main/java/com/google/android/piyush/database/model/CustomPlaylists.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database.model
2 |
3 | data class CustomPlaylists (
4 | val videoId: String,
5 | val title: String?,
6 | val thumbnail: String?,
7 | val channelId : String?,
8 | val publishedAt : String?,
9 | val viewCount : String?,
10 | val channelTitle : String?,
11 | val duration : String?
12 | )
--------------------------------------------------------------------------------
/Database/src/main/java/com/google/android/piyush/database/repository/DopamineDatabaseRepository.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database.repository
2 |
3 | import com.google.android.piyush.database.dao.DopamineDao
4 | import com.google.android.piyush.database.entities.EntityFavouritePlaylist
5 | import com.google.android.piyush.database.entities.EntityRecentVideos
6 | import com.google.android.piyush.database.entities.EntityVideoSearch
7 |
8 | class DopamineDatabaseRepository(
9 | private val dopamineDao: DopamineDao
10 | ) {
11 | suspend fun insertSearchVideos(vararg searchVideo: EntityVideoSearch) {
12 | dopamineDao.insertSearchVideos(*searchVideo)
13 | }
14 |
15 | suspend fun getSearchVideoList(): List {
16 | return dopamineDao.getSearchVideoList()
17 | }
18 |
19 | suspend fun deleteSearchVideoList() {
20 | dopamineDao.deleteSearchVideoList()
21 | }
22 |
23 | suspend fun insertFavouriteVideos(vararg favouriteVideo: EntityFavouritePlaylist) {
24 | dopamineDao.insertFavouriteVideos(*favouriteVideo)
25 | }
26 |
27 | suspend fun isFavouriteVideo(videoId: String): String {
28 | return dopamineDao.isFavouriteVideo(videoId)
29 | }
30 |
31 | suspend fun deleteFavouriteVideo(videoId: String) {
32 | dopamineDao.deleteFavouriteVideo(videoId)
33 | }
34 |
35 | suspend fun getFavouritePlayList(): List {
36 | return dopamineDao.getFavouritePlayList()
37 | }
38 |
39 | suspend fun insertRecentVideos(vararg recentVideos: EntityRecentVideos) {
40 | dopamineDao.insertRecentVideos(*recentVideos)
41 | }
42 |
43 | suspend fun getRecentVideos(): List {
44 | return dopamineDao.getRecentVideos()
45 | }
46 |
47 | suspend fun isRecentVideo(videoId: String): String {
48 | return dopamineDao.isRecentVideo(videoId)
49 | }
50 |
51 | suspend fun updateRecentVideo(videoId: String, time: String) {
52 | dopamineDao.updateRecentVideo(videoId, time)
53 | }
54 | suspend fun deleteRecentVideo() {
55 | dopamineDao.deleteRecentVideo()
56 | }
57 | }
--------------------------------------------------------------------------------
/Database/src/test/java/com/google/android/piyush/database/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.database
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 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dopamine (YouTube Clone)
2 |
3 | Dopamine is a YouTube clone that aims to replicate the functionality and features of the popular video-sharing platform.
4 |
5 | ## Authors
6 | 🌊 [Rajat_Kevat](https://kotlindevs.github.io)
7 |
8 | ## Logo of the application
9 | 
10 |
11 | ## App Screenshots
12 |
13 | Below are some screenshots of the Dopamine application showcasing its features and user interface:
14 |
15 | | Screenshot 1 | Screenshot 2 | Screenshot 3 |
16 | |-------------------|-------------------|-------------------|
17 | |  |  |  |
18 |
19 | | Screenshot 4 | Screenshot 5 | Screenshot 6 |
20 | |-------------------|-------------------|-------------------|
21 | |  |  |  |
22 |
23 | ## Support
24 |
25 | For support, email [kotlindevslife@gmail.com](mailto:kotlindevslife@gmail.com)!
26 |
27 |
--------------------------------------------------------------------------------
/Youtube/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/Youtube/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.library)
3 | alias(libs.plugins.jetbrains.kotlin.android)
4 | kotlin("plugin.serialization") version "1.9.23"
5 | }
6 |
7 | android {
8 | namespace = "com.google.android.piyush.youtube"
9 | compileSdk = 34
10 |
11 | defaultConfig {
12 | minSdk = 24
13 |
14 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles("consumer-rules.pro")
16 | }
17 |
18 | buildTypes {
19 | release {
20 | isMinifyEnabled = false
21 | proguardFiles(
22 | getDefaultProguardFile("proguard-android-optimize.txt"),
23 | "proguard-rules.pro"
24 | )
25 | }
26 | }
27 | compileOptions {
28 | sourceCompatibility = JavaVersion.VERSION_1_8
29 | targetCompatibility = JavaVersion.VERSION_1_8
30 | }
31 | kotlinOptions {
32 | jvmTarget = "1.8"
33 | }
34 | }
35 |
36 | dependencies {
37 |
38 | implementation(libs.androidx.core.ktx)
39 | implementation(libs.androidx.appcompat)
40 | implementation(libs.material)
41 | implementation(libs.ktor.client.core)
42 | implementation(libs.ktor.client.cio)
43 | implementation(libs.ktor.client.content.negotiation)
44 | implementation(libs.kotlinx.serialization.json)
45 | implementation(libs.ktor.serialization.kotlinx.json)
46 | implementation(libs.androidx.lifecycle.viewmodel.ktx)
47 | testImplementation(libs.junit)
48 | androidTestImplementation(libs.androidx.junit)
49 | androidTestImplementation(libs.androidx.espresso.core)
50 | }
--------------------------------------------------------------------------------
/Youtube/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/Youtube/consumer-rules.pro
--------------------------------------------------------------------------------
/Youtube/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
--------------------------------------------------------------------------------
/Youtube/src/androidTest/java/com/google/android/piyush/youtube/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.google.android.piyush.youtube.test", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/Youtube/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/model/ContentDetails.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class ContentDetails(
7 | val duration: String? = null,
8 | val videoPublishedAt: String? = null,
9 | val videoId: String? = null
10 | )
11 |
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/model/Item.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.model
2 |
3 | import com.google.android.piyush.youtube.model.channelDetails.BrandingSettings
4 | import kotlinx.serialization.Serializable
5 |
6 | @Serializable
7 | data class Item(
8 | val contentDetails: ContentDetails? = null,
9 | val snippet: Snippet? = null,
10 | val id: String? = null,
11 | val kind: String? = null,
12 | val statistics: Statistics? = null,
13 | val brandingSettings: BrandingSettings? = null
14 | )
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/model/SearchTube.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class SearchTube(
7 | val regionCode: String? = null,
8 | val items: List? = null
9 | )
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/model/SearchTubeItems.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class SearchTubeItems(
7 | val contentDetails: ContentDetails? = null,
8 | val snippet: Snippet? = null,
9 | val id: Id? = null,
10 | val kind: String? = null,
11 | val statistics: Statistics? = null
12 | )
13 |
14 | @Serializable
15 | data class Id(
16 | val kind: String? = null,
17 | val videoId: String? = null
18 | )
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/model/Shorts.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class Shorts(
7 | val videoId: String? = null
8 | )
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/model/Snippet.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class Snippet(
7 | val channelId: String? = null,
8 | val channelTitle: String? = null,
9 | val customUrl: String? = null,
10 | val thumbnails: Thumbnails? = null,
11 | val publishedAt: String? = null,
12 | val kind: String? = null,
13 | val description: String? = null,
14 | val tags: List? = null,
15 | val title: String? = null
16 | )
17 |
18 |
19 | @Serializable
20 | data class Thumbnails(
21 | val default: Default? = null,
22 | val medium: Medium? = null,
23 | val high: High? = null,
24 | val standard: Standard? = null
25 | )
26 |
27 | @Serializable
28 | data class Statistics(
29 | val viewCount: Int? = 0,
30 | val subscriberCount: Int? = 0,
31 | val likeCount: Int? = 0
32 | )
33 |
34 | @Serializable
35 | data class Standard(
36 | val url: String? = null,
37 | )
38 |
39 | @Serializable
40 | data class High(
41 | val url: String? = null,
42 | )
43 |
44 | @Serializable
45 | data class Default(
46 | val url: String? = null,
47 | )
48 |
49 | @Serializable
50 | data class Medium(
51 | val url: String? = null,
52 | )
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/model/Youtube.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class Youtube(
7 | val regionCode: String? = null,
8 | val items: List- ? = null
9 | )
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/model/channelDetails/YoutubeChannel.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.model.channelDetails
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class YoutubeChannel(
7 | val items : List
- ? = null
8 | )
9 |
10 | @Serializable
11 | data class Item(
12 | val kind : String? = null,
13 | val id : String? = null,
14 | val snippet : Snippet? = null,
15 | val statistics : Statistics? = null,
16 | val brandingSettings : BrandingSettings? = null,
17 | )
18 |
19 |
20 | @Serializable
21 | data class Snippet(
22 | val title : String? = null,
23 | val description : String? = null,
24 | val customUrl : String? = null,
25 | val publishedAt : String? = null,
26 | val thumbnails : Thumbnails? = null,
27 | val country : String? = null,
28 | )
29 |
30 | @Serializable
31 | data class Thumbnails(
32 | val default : Default? = null,
33 | )
34 |
35 | @Serializable
36 | data class Default(
37 | val url : String? = null,
38 | val width : Int? = null,
39 | val height : Int? = null
40 | )
41 |
42 | @Serializable
43 | data class Statistics(
44 | val viewCount: String? = null,
45 | val subscriberCount: String? = null,
46 | val likeCount: String? = null
47 | )
48 |
49 | @Serializable
50 | data class BrandingSettings(
51 | val image : Image? = null
52 | )
53 |
54 | @Serializable
55 | data class Image(
56 | val bannerExternalUrl : String? = null
57 | )
58 |
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/model/channelPlaylists/ChannelPlaylists.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.model.channelPlaylists
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class ChannelPlaylists(
7 | val nextPageToken: String? = null,
8 | val pageInfo: PageInfo? = null,
9 | val items: List
- ? = null
10 | )
11 |
12 | @Serializable
13 | data class Item(
14 | val id: String? = null,
15 | val snippet: Snippet? = null,
16 | val contentDetails: ContentDetails? = null
17 | )
18 |
19 | @Serializable
20 | data class PageInfo(
21 | val totalResults: Int? = null,
22 | val resultsPerPage: Int? = null
23 | )
24 |
25 | @Serializable
26 | data class Snippet(
27 | val publishedAt: String? = null,
28 | val channelId: String? = null,
29 | val title: String? = null,
30 | val description: String? = null,
31 | val thumbnails: Thumbnails? = null,
32 | val channelTitle: String? = null,
33 | )
34 |
35 | @Serializable
36 | data class ContentDetails(
37 | val itemCount: Int? = null
38 | )
39 |
40 | @Serializable
41 | data class Thumbnails(
42 | val default: Default? = null,
43 | val medium: Medium? = null,
44 | val high: High? = null
45 | )
46 |
47 | @Serializable
48 | data class Default(
49 | val url: String? = null,
50 | val width: Int? = null,
51 | val height: Int? = null
52 | )
53 |
54 | @Serializable
55 | data class Medium(
56 | val url: String? = null,
57 | val width: Int? = null,
58 | val height: Int? = null
59 | )
60 |
61 | @Serializable
62 | data class High(
63 | val url: String? = null,
64 | val width: Int? = null,
65 | val height: Int? = null
66 | )
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/repository/YoutubeRepository.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.repository
2 |
3 | import com.google.android.piyush.youtube.model.SearchTube
4 | import com.google.android.piyush.youtube.model.Shorts
5 | import com.google.android.piyush.youtube.model.Youtube
6 | import com.google.android.piyush.youtube.model.channelDetails.YoutubeChannel
7 | import com.google.android.piyush.youtube.model.channelPlaylists.ChannelPlaylists
8 |
9 | interface YoutubeRepository {
10 | suspend fun getHomeVideos() : Youtube
11 | suspend fun getLibraryVideos(playListId : String) : Youtube
12 | suspend fun getSearchVideos(query : String) : SearchTube
13 | suspend fun getYoutubeShorts() : List
14 | suspend fun getChannelDetails(channelId : String) : YoutubeChannel
15 | suspend fun getChannelsPlaylists(channelId : String) : ChannelPlaylists
16 | suspend fun getPlaylistVideos(playListId : String) : Youtube
17 | suspend fun getVideoDetails(videoId : String) : Youtube
18 | }
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/utilities/YoutubeResource.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.utilities
2 |
3 | sealed class YoutubeResource {
4 |
5 | data class Success(
6 | val data: T
7 | ) : YoutubeResource()
8 |
9 | data class Error(
10 | val exception: Exception
11 | ) : YoutubeResource()
12 |
13 | data object Loading : YoutubeResource()
14 |
15 | override fun toString(): String {
16 | return when(this){
17 | is Success<*> -> "Success[data=$data]"
18 | is Error -> "Error[exception=$exception]"
19 | Loading -> "Loading"
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/Youtube/src/main/java/com/google/android/piyush/youtube/viewModels/ShortsViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube.viewModels
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import androidx.lifecycle.ViewModelProvider
7 | import androidx.lifecycle.viewModelScope
8 | import com.google.android.piyush.youtube.model.Shorts
9 | import com.google.android.piyush.youtube.repository.YoutubeRepositoryImpl
10 | import com.google.android.piyush.youtube.utilities.YoutubeResource
11 | import kotlinx.coroutines.launch
12 |
13 | class ShortsViewModel(
14 | private val youtubeRepositoryImpl: YoutubeRepositoryImpl
15 | ) : ViewModel() {
16 |
17 | private val _shorts : MutableLiveData>> = MutableLiveData()
18 | val shorts : LiveData>> = _shorts
19 |
20 | init {
21 | viewModelScope.launch {
22 | try {
23 | _shorts.postValue(YoutubeResource.Loading)
24 | val response = youtubeRepositoryImpl.getYoutubeShorts()
25 | if(response.isEmpty()){
26 | _shorts.postValue(
27 | YoutubeResource.Error(
28 | Exception("No Shorts Found")
29 | )
30 | )
31 | }else{
32 | _shorts.postValue(YoutubeResource.Success(response))
33 | }
34 | }catch (e : Exception){
35 | _shorts.postValue(YoutubeResource.Error(e))
36 | }
37 | }
38 | }
39 | }
40 |
41 | class ShortsViewModelFactory(
42 | private val youtubeRepositoryImpl: YoutubeRepositoryImpl
43 | ) : ViewModelProvider.Factory{
44 | override fun create(modelClass: Class): T {
45 | if(modelClass.isAssignableFrom(ShortsViewModel::class.java)){
46 | @Suppress("UNCHECKED_CAST")
47 | return ShortsViewModel(youtubeRepositoryImpl) as T
48 | }else{
49 | throw IllegalArgumentException("Unknown ViewModel class")
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/Youtube/src/test/java/com/google/android/piyush/youtube/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.youtube
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 | }
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/1.jpeg
--------------------------------------------------------------------------------
/app/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/10.jpg
--------------------------------------------------------------------------------
/app/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/11.jpg
--------------------------------------------------------------------------------
/app/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/12.jpg
--------------------------------------------------------------------------------
/app/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/13.jpg
--------------------------------------------------------------------------------
/app/14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/14.jpg
--------------------------------------------------------------------------------
/app/15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/15.jpg
--------------------------------------------------------------------------------
/app/16.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/16.jpg
--------------------------------------------------------------------------------
/app/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/2.jpg
--------------------------------------------------------------------------------
/app/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/3.jpg
--------------------------------------------------------------------------------
/app/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/4.jpg
--------------------------------------------------------------------------------
/app/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/5.jpg
--------------------------------------------------------------------------------
/app/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/6.jpg
--------------------------------------------------------------------------------
/app/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/7.jpg
--------------------------------------------------------------------------------
/app/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/8.jpg
--------------------------------------------------------------------------------
/app/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/9.jpg
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.application)
3 | alias(libs.plugins.jetbrains.kotlin.android)
4 | alias(libs.plugins.google.gms.google.services)
5 | }
6 |
7 | android {
8 | namespace = "com.google.android.piyush.dopamine"
9 | compileSdk = 34
10 |
11 | defaultConfig {
12 | applicationId = "com.google.android.piyush.dopamine"
13 | minSdk = 24
14 | targetSdk = 34
15 | versionCode = 1
16 | versionName = "version dopamine_20240704_01.phone.stable.dynamic"
17 |
18 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
19 | }
20 |
21 | buildTypes {
22 | release {
23 | isMinifyEnabled = false
24 | proguardFiles(
25 | getDefaultProguardFile("proguard-android-optimize.txt"),
26 | "proguard-rules.pro"
27 | )
28 | signingConfig = signingConfigs.getByName("debug")
29 | }
30 | }
31 | compileOptions {
32 | sourceCompatibility = JavaVersion.VERSION_17
33 | targetCompatibility = JavaVersion.VERSION_17
34 | }
35 | kotlinOptions {
36 | jvmTarget = "17"
37 | }
38 | buildFeatures {
39 | viewBinding = true
40 | }
41 |
42 | splits {
43 | abi {
44 | isEnable = true
45 | reset()
46 | include("x86", "x86_64", "armeabi-v7a", "arm64-v8a")
47 | isUniversalApk = true
48 | }
49 | }
50 | packagingOptions {
51 | jniLibs {
52 | useLegacyPackaging = true
53 | }
54 | }
55 |
56 | }
57 |
58 | dependencies {
59 |
60 | implementation(libs.androidx.core.ktx)
61 | implementation(libs.androidx.appcompat)
62 | implementation(libs.material)
63 | implementation(libs.androidx.activity)
64 | implementation(libs.androidx.constraintlayout)
65 | implementation(libs.firebase.auth)
66 | implementation(libs.play.services.auth)
67 | implementation(libs.androidx.legacy.support.v4)
68 | implementation(libs.androidx.lifecycle.livedata.ktx)
69 | implementation(libs.androidx.lifecycle.viewmodel.ktx)
70 | implementation(libs.androidx.fragment.ktx)
71 | implementation(libs.shimmer)
72 | implementation(libs.glide)
73 | implementation(libs.core)
74 | implementation(libs.lottie)
75 | implementation (libs.exomedia)
76 | implementation(project(":Youtube"))
77 | implementation(project(":Database"))
78 | implementation(libs.androidx.preference)
79 | testImplementation(libs.junit)
80 | androidTestImplementation(libs.androidx.junit)
81 | androidTestImplementation(libs.androidx.espresso.core)
82 | }
--------------------------------------------------------------------------------
/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "929480757734",
4 | "project_id": "kotlinprojects-cr7",
5 | "storage_bucket": "kotlinprojects-cr7.firebasestorage.app"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:929480757734:android:09164c78fc362b32388627",
11 | "android_client_info": {
12 | "package_name": "com.google.android.piyush.dopamine"
13 | }
14 | },
15 | "oauth_client": [
16 | {
17 | "client_id": "929480757734-du8f823uda1upcdpf0ptpsc9terih1bp.apps.googleusercontent.com",
18 | "client_type": 3
19 | }
20 | ],
21 | "api_key": [
22 | {
23 | "current_key": "AIzaSyAB8bbHqixtjJtcIosMwaD6D3lcc_67rFM"
24 | }
25 | ],
26 | "services": {
27 | "appinvite_service": {
28 | "other_platform_oauth_client": [
29 | {
30 | "client_id": "929480757734-du8f823uda1upcdpf0ptpsc9terih1bp.apps.googleusercontent.com",
31 | "client_type": 3
32 | }
33 | ]
34 | }
35 | }
36 | }
37 | ],
38 | "configuration_version": "1"
39 | }
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/google/android/piyush/dopamine/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.google.android.piyush.dopamine", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "929480757734",
4 | "project_id": "kotlinprojects-cr7",
5 | "storage_bucket": "kotlinprojects-cr7.firebasestorage.app"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:929480757734:android:09164c78fc362b32388627",
11 | "android_client_info": {
12 | "package_name": "com.google.android.piyush.dopamine"
13 | }
14 | },
15 | "oauth_client": [
16 | {
17 | "client_id": "929480757734-du8f823uda1upcdpf0ptpsc9terih1bp.apps.googleusercontent.com",
18 | "client_type": 3
19 | }
20 | ],
21 | "api_key": [
22 | {
23 | "current_key": "AIzaSyAB8bbHqixtjJtcIosMwaD6D3lcc_67rFM"
24 | }
25 | ],
26 | "services": {
27 | "appinvite_service": {
28 | "other_platform_oauth_client": [
29 | {
30 | "client_id": "929480757734-du8f823uda1upcdpf0ptpsc9terih1bp.apps.googleusercontent.com",
31 | "client_type": 3
32 | }
33 | ]
34 | }
35 | }
36 | }
37 | ],
38 | "configuration_version": "1"
39 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
28 |
31 |
34 |
37 |
40 |
43 |
48 |
51 |
54 |
57 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
72 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/DopamineApp.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine
2 |
3 | import android.app.Application
4 | import android.os.StrictMode
5 | import androidx.appcompat.app.AppCompatDelegate
6 | import com.google.android.material.color.DynamicColors
7 | import com.google.android.material.color.DynamicColorsOptions
8 | import com.google.android.piyush.dopamine.utilities.Utilities
9 |
10 |
11 | class DopamineApp : Application() {
12 | override fun onCreate() {
13 | super.onCreate()
14 |
15 | val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
16 |
17 | StrictMode.setThreadPolicy(policy)
18 |
19 | DynamicColors.applyToActivitiesIfAvailable(
20 | this, DynamicColorsOptions.Builder().build()
21 | )
22 |
23 | val dopamineApp = applicationContext.getSharedPreferences("DopamineApp", MODE_PRIVATE)
24 |
25 | if(dopamineApp.getString("Theme", Utilities.LIGHT_MODE) == Utilities.LIGHT_MODE){
26 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
27 | }else if(dopamineApp.getString("Theme", Utilities.DARK_MODE) == Utilities.DARK_MODE){
28 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
29 | }else{
30 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
31 | }
32 |
33 | if(dopamineApp.getBoolean("ExperimentalUserColor", false)){
34 | DynamicColors.applyToActivitiesIfAvailable(this)
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/activities/CVPlaylist.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.activities
2 |
3 | import android.content.ContentValues.TAG
4 | import android.os.Bundle
5 | import android.util.Log
6 | import androidx.activity.enableEdgeToEdge
7 | import androidx.appcompat.app.AppCompatActivity
8 | import androidx.core.view.ViewCompat
9 | import androidx.core.view.WindowInsetsCompat
10 | import com.google.android.piyush.database.viewModel.DatabaseViewModel
11 | import com.google.android.piyush.dopamine.R
12 | import com.google.android.piyush.dopamine.adapters.CustomPlaylistsVDataAdapter
13 | import com.google.android.piyush.dopamine.databinding.ActivityCvplaylistBinding
14 |
15 | class CVPlaylist : AppCompatActivity() {
16 | private lateinit var databaseViewModel: DatabaseViewModel
17 | private lateinit var binding : ActivityCvplaylistBinding
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | databaseViewModel = DatabaseViewModel(applicationContext)
21 | binding = ActivityCvplaylistBinding.inflate(layoutInflater)
22 | setContentView(binding.root)
23 | enableEdgeToEdge()
24 | ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
25 | val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
26 | v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
27 | insets
28 | }
29 |
30 | val playlist = intent.getStringExtra("playlistName")
31 | if(playlist != null) {
32 | binding.materialTextView.text = playlist
33 | binding.customPlayListVideos.apply {
34 | setHasFixedSize(false)
35 | layoutManager = androidx.recyclerview.widget.LinearLayoutManager(context)
36 | adapter = CustomPlaylistsVDataAdapter(databaseViewModel.getPlaylistData(playlist),context)
37 | }
38 | Log.d(TAG, " -> Activity : CVPlaylist || PlaylistData : $playlist")
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/activities/DopamineVideoWatchHistory.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.activities
2 |
3 | import android.content.ContentValues
4 | import android.os.Bundle
5 | import android.util.Log
6 | import androidx.activity.enableEdgeToEdge
7 | import androidx.appcompat.app.AppCompatActivity
8 | import androidx.core.view.ViewCompat
9 | import androidx.core.view.WindowInsetsCompat
10 | import com.google.android.material.snackbar.Snackbar
11 | import com.google.android.piyush.database.viewModel.DatabaseViewModel
12 | import com.google.android.piyush.dopamine.R
13 | import com.google.android.piyush.dopamine.adapters.RecentVideosAdapter
14 | import com.google.android.piyush.dopamine.databinding.ActivityDopamineVideoWatchHistoryBinding
15 |
16 | class DopamineVideoWatchHistory : AppCompatActivity() {
17 |
18 | private lateinit var binding: ActivityDopamineVideoWatchHistoryBinding
19 | private lateinit var databaseViewModel: DatabaseViewModel
20 |
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 |
24 | binding = ActivityDopamineVideoWatchHistoryBinding.inflate(layoutInflater)
25 | databaseViewModel = DatabaseViewModel(context = applicationContext)
26 | setContentView(binding.root)
27 |
28 | enableEdgeToEdge()
29 | ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
30 | val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
31 | v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
32 | insets
33 | }
34 |
35 | databaseViewModel.getRecentVideos()
36 |
37 | databaseViewModel.recentVideos.observe(this) { recentVideos ->
38 | binding.recyclerView.apply {
39 | setHasFixedSize(true)
40 | layoutManager = androidx.recyclerview.widget.LinearLayoutManager(context)
41 | adapter = RecentVideosAdapter(context,recentVideos)
42 | }
43 | if(recentVideos.isNullOrEmpty()){
44 | binding.recyclerView.visibility = android.view.View.GONE
45 | binding.clearWatchHistory.visibility = android.view.View.GONE
46 | binding.lottieAnimationView.apply {
47 | visibility = android.view.View.VISIBLE
48 | setAnimation(R.raw.auth)
49 | loop(true)
50 | }
51 | }
52 | Log.d(ContentValues.TAG, " -> Activity : DopamineVideoWatchHistory || recentVideos : $recentVideos")
53 | }
54 |
55 | binding.topAppBar.setNavigationOnClickListener{
56 | finish()
57 | }
58 |
59 | binding.clearWatchHistory.setOnClickListener {
60 | databaseViewModel.deleteRecentVideo()
61 | Snackbar.make(binding.root, "Watch History Cleared", Snackbar.LENGTH_SHORT).show()
62 | binding.recyclerView.visibility = android.view.View.GONE
63 | binding.clearWatchHistory.visibility = android.view.View.GONE
64 | binding.lottieAnimationView.apply {
65 | visibility = android.view.View.VISIBLE
66 | setAnimation(R.raw.auth)
67 | @Suppress("DEPRECATION")
68 | loop(true)
69 | playAnimation()
70 | }
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/adapters/CustomPlayListVAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.adapters
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.graphics.Color
6 | import android.util.Log
7 | import android.view.LayoutInflater
8 | import android.view.ViewGroup
9 | import androidx.recyclerview.widget.RecyclerView
10 | import com.google.android.piyush.database.model.CustomPlaylistView
11 | import com.google.android.piyush.dopamine.R
12 | import com.google.android.piyush.dopamine.activities.CVPlaylist
13 | import com.google.android.piyush.dopamine.viewHolders.CustomPlayListVHolder
14 | import kotlin.random.Random
15 |
16 |
17 | class CustomPlayListVAdapter(
18 | private val context: Context,
19 | private var playlists: List?,
20 | ) : RecyclerView.Adapter() {
21 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomPlayListVHolder {
22 | return CustomPlayListVHolder(
23 | LayoutInflater.from(
24 | parent.context
25 | )
26 | .inflate(
27 | R.layout.item_frag_cust_lst_view, parent, false
28 | )
29 | )
30 | }
31 |
32 | override fun getItemCount(): Int {
33 | return playlists?.size!!
34 | }
35 |
36 | override fun onBindViewHolder(holder: CustomPlayListVHolder, position: Int) {
37 | val playlistName = playlists?.get(position)?.playListName.toString()
38 | val playlistDescription = playlists?.get(position)?.playListDescription
39 |
40 | Log.d("playlistName", playlistName)
41 |
42 | val getColor = Color.argb(
43 | 255,
44 | Random.nextInt(256),
45 | Random.nextInt(256),
46 | Random.nextInt(256)
47 | )
48 |
49 | holder.image.background.setTint(getColor)
50 |
51 | holder.title1.text = getString(playlistName)
52 | holder.title.text = playlistName
53 | holder.description.text = playlistDescription
54 | holder.playlist.setOnClickListener {
55 | val intent = Intent(context, CVPlaylist::class.java)
56 | intent.putExtra("playlistName", playlistName)
57 | context.startActivity(intent)
58 | }
59 | }
60 |
61 | private fun getString(name: String): String {
62 | if(name.isEmpty()){
63 | return "🧿"
64 | }else{
65 | var initials = ""
66 | val nameParts = name.split(" ")
67 | for (i in 0 until minOf(nameParts.size, 2)) {
68 | initials += nameParts[i][0].uppercase()
69 | }
70 | return initials
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/adapters/LibraryAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.adapters
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.view.LayoutInflater
6 | import android.view.ViewGroup
7 | import androidx.recyclerview.widget.RecyclerView
8 | import com.bumptech.glide.Glide
9 | import com.google.android.piyush.dopamine.R
10 | import com.google.android.piyush.dopamine.activities.YoutubePlayer
11 | import com.google.android.piyush.dopamine.viewHolders.LibraryViewHolder
12 | import com.google.android.piyush.youtube.model.Youtube
13 |
14 | class LibraryAdapter(
15 | private val context: Context,
16 | private var youtube: Youtube?
17 | ) : RecyclerView.Adapter() {
18 |
19 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LibraryViewHolder {
20 | return LibraryViewHolder(
21 | LayoutInflater
22 | .from(parent.context)
23 | .inflate(R.layout.item_fragment_library, parent, false)
24 | )
25 | }
26 |
27 | override fun getItemCount(): Int {
28 | return youtube?.items?.size!!
29 | }
30 |
31 | override fun onBindViewHolder(holder: LibraryViewHolder, position: Int) {
32 | val videos = youtube?.items?.get(position)
33 | Glide.with(context)
34 | .load(videos?.snippet?.thumbnails?.standard?.url)
35 | .into(holder.image)
36 | holder.title.text = videos?.snippet?.title
37 | holder.subtitle.text = videos?.snippet?.publishedAt
38 | holder.video.setOnClickListener {
39 | context.startActivity(
40 | Intent(context, YoutubePlayer::class.java)
41 | .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
42 | .putExtra("videoId",videos?.contentDetails?.videoId)
43 | .putExtra("channelId",videos?.snippet?.channelId)
44 | )
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/adapters/RecentVideosAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.adapters
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.view.LayoutInflater
6 | import android.view.ViewGroup
7 | import androidx.recyclerview.widget.RecyclerView
8 | import com.bumptech.glide.Glide
9 | import com.google.android.piyush.database.entities.EntityRecentVideos
10 | import com.google.android.piyush.dopamine.R
11 | import com.google.android.piyush.dopamine.activities.YoutubePlayer
12 | import com.google.android.piyush.dopamine.viewHolders.RecentVideosViewHolder
13 |
14 | class RecentVideosAdapter(
15 | private val context: Context,
16 | private val videos: List?
17 | ) : RecyclerView.Adapter() {
18 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentVideosViewHolder {
19 | return RecentVideosViewHolder(
20 | LayoutInflater.from(parent.context)
21 | .inflate(R.layout.item_activity_video_views_history, parent, false)
22 | )
23 | }
24 |
25 | override fun getItemCount(): Int {
26 | return videos?.size!!
27 | }
28 |
29 | override fun onBindViewHolder(holder: RecentVideosViewHolder, position: Int) {
30 | val recentVideo = videos?.get(position)
31 | holder.title.text = recentVideo?.title
32 | holder.customName.text = recentVideo?.timing
33 | Glide.with(context).load(recentVideo?.thumbnail).into(holder.image)
34 | holder.videoCard.setOnClickListener {
35 | context.startActivity(
36 | Intent(context, YoutubePlayer::class.java)
37 | .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
38 | .putExtra("videoId",recentVideo?.videoId)
39 | .putExtra("channelId",recentVideo?.channelId)
40 | )
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/adapters/SearchHistoryAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.adapters
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.google.android.piyush.database.entities.EntityVideoSearch
7 | import com.google.android.piyush.dopamine.R
8 | import com.google.android.piyush.dopamine.viewHolders.SearchHistoryViewHolder
9 |
10 | class SearchHistoryAdapter(
11 | private val searchHistoryItem : List?
12 | ) : RecyclerView.Adapter() {
13 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchHistoryViewHolder {
14 | return SearchHistoryViewHolder(
15 | LayoutInflater
16 | .from(parent.context)
17 | .inflate(R.layout.item_fragment_search, parent, false)
18 | )
19 | }
20 |
21 | override fun getItemCount(): Int {
22 | return searchHistoryItem?.size!!
23 | }
24 |
25 | override fun onBindViewHolder(holder: SearchHistoryViewHolder, position: Int) {
26 | holder.searchHistoryItem.text = searchHistoryItem?.get(position)?.search
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/adapters/ShortsAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.adapters
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.google.android.piyush.dopamine.R
7 | import com.google.android.piyush.dopamine.viewHolders.ShortsViewHolder
8 | import com.google.android.piyush.youtube.model.Shorts
9 | import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
10 | import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerCallback
11 | import kotlin.random.Random
12 |
13 | class ShortsAdapter(
14 | private val shorts: List?
15 | ) : RecyclerView.Adapter(){
16 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShortsViewHolder {
17 | return ShortsViewHolder(
18 | LayoutInflater
19 | .from(parent.context)
20 | .inflate(R.layout.item_fragment_shorts, parent, false)
21 | )
22 | }
23 |
24 | override fun getItemCount(): Int {
25 | return shorts?.size!!
26 | }
27 |
28 | override fun onBindViewHolder(holder: ShortsViewHolder, position: Int) {
29 | var uniqueRandomPosition = Random.nextInt(0, shorts?.size!!)
30 | while (uniqueRandomPosition == position) {
31 | uniqueRandomPosition = Random.nextInt(0,shorts.size)
32 | }
33 | val short = shorts[uniqueRandomPosition].videoId
34 | holder.shortsPlayer.getYouTubePlayerWhenReady(
35 | object : YouTubePlayerCallback {
36 | override fun onYouTubePlayer(youTubePlayer: YouTubePlayer) {
37 | youTubePlayer.cueVideo(short!!, 1f)
38 | }
39 | }
40 | )
41 | }
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/adapters/YourFavouriteVideosAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.adapters
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.view.LayoutInflater
6 | import android.view.ViewGroup
7 | import androidx.recyclerview.widget.RecyclerView
8 | import com.bumptech.glide.Glide
9 | import com.google.android.piyush.database.entities.EntityFavouritePlaylist
10 | import com.google.android.piyush.dopamine.R
11 | import com.google.android.piyush.dopamine.activities.YoutubePlayer
12 | import com.google.android.piyush.dopamine.viewHolders.YourFavouriteVideosViewHolder
13 |
14 | class YourFavouriteVideosAdapter(
15 | private val context: Context,
16 | private val videos: List?
17 | ) : RecyclerView.Adapter() {
18 | override fun onCreateViewHolder(
19 | parent: ViewGroup,
20 | viewType: Int
21 | ): YourFavouriteVideosViewHolder {
22 | return YourFavouriteVideosViewHolder(
23 | LayoutInflater.from(
24 | parent.context
25 | ).inflate(R.layout.item_fragment_library_your_favourite_videos, parent, false)
26 | )
27 | }
28 |
29 | override fun getItemCount(): Int {
30 | return videos?.size!!
31 | }
32 |
33 | override fun onBindViewHolder(holder: YourFavouriteVideosViewHolder, position: Int) {
34 | val favouriteVideo = videos?.get(position)
35 | holder.title.text = favouriteVideo?.title
36 | holder.customName.text = favouriteVideo?.channelTitle
37 | Glide.with(context).load(favouriteVideo?.thumbnail).into(holder.image)
38 | holder.videoCard.setOnClickListener {
39 | context.startActivity(
40 | Intent(context, YoutubePlayer::class.java)
41 | .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
42 | .putExtra("videoId",favouriteVideo?.videoId)
43 | .putExtra("channelId",favouriteVideo?.channelId)
44 | )
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/adapters/YoutubeChannelPlaylistsAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.adapters
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.view.LayoutInflater
6 | import android.view.ViewGroup
7 | import androidx.recyclerview.widget.RecyclerView
8 | import com.bumptech.glide.Glide
9 | import com.google.android.piyush.dopamine.R
10 | import com.google.android.piyush.dopamine.activities.YoutubeChannelPlaylistsVideos
11 | import com.google.android.piyush.dopamine.viewHolders.YoutubeChannelPlaylistsViewHolder
12 | import com.google.android.piyush.youtube.model.channelPlaylists.ChannelPlaylists
13 |
14 | class YoutubeChannelPlaylistsAdapter(
15 | private val context: Context,
16 | private val playlists: ChannelPlaylists?
17 | ) : RecyclerView.Adapter() {
18 | override fun onCreateViewHolder(
19 | parent: ViewGroup,
20 | viewType: Int
21 | ): YoutubeChannelPlaylistsViewHolder {
22 | return YoutubeChannelPlaylistsViewHolder(
23 | LayoutInflater.from(parent.context).inflate(
24 | R.layout.item_activity_youtube_channel_playlists, parent, false
25 | )
26 | )
27 | }
28 |
29 | override fun getItemCount(): Int {
30 | return playlists?.items?.size!!
31 | }
32 |
33 | override fun onBindViewHolder(holder: YoutubeChannelPlaylistsViewHolder, position: Int) {
34 | val playListData = playlists?.items?.get(position)
35 | val playlistImage = playListData?.snippet?.thumbnails?.default?.url
36 | val playlistTitle = playListData?.snippet?.title
37 | val playlistChannelTitle = playListData?.snippet?.channelTitle
38 |
39 | Glide.with(context).load(playlistImage).into(holder.playlistImage)
40 |
41 | holder.playlistTitle.text = playlistTitle
42 | holder.playlistChannelTitle.text = playlistChannelTitle
43 | holder.playlist.setOnClickListener {
44 | if (!playlists?.items.isNullOrEmpty()) {
45 | context.startActivity(
46 | Intent(
47 | context, YoutubeChannelPlaylistsVideos::class.java
48 | ).addFlags(
49 | Intent.FLAG_ACTIVITY_NEW_TASK
50 | ).putExtra(
51 | "playlistId", playListData?.id
52 | )
53 | )
54 | }
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/adapters/YoutubePlaylistsVideosAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.adapters
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.view.LayoutInflater
6 | import android.view.ViewGroup
7 | import androidx.recyclerview.widget.RecyclerView
8 | import com.bumptech.glide.Glide
9 | import com.google.android.piyush.dopamine.R
10 | import com.google.android.piyush.dopamine.activities.YoutubePlayer
11 | import com.google.android.piyush.dopamine.viewHolders.YoutubePlaylistsVideosViewHolder
12 | import com.google.android.piyush.youtube.model.Youtube
13 |
14 | class YoutubePlaylistsVideosAdapter(
15 | private val context: Context,
16 | private val playlistVideos: Youtube?
17 | ) : RecyclerView.Adapter() {
18 | override fun onCreateViewHolder(
19 | parent: ViewGroup,
20 | viewType: Int
21 | ): YoutubePlaylistsVideosViewHolder {
22 | return YoutubePlaylistsVideosViewHolder(
23 | LayoutInflater.from(parent.context).inflate(
24 | R.layout.item_activity_youtube_playlists_videos, parent, false
25 | )
26 | )
27 | }
28 |
29 | override fun getItemCount(): Int {
30 | return playlistVideos?.items?.size!!
31 | }
32 |
33 | override fun onBindViewHolder(holder: YoutubePlaylistsVideosViewHolder, position: Int) {
34 | val videos = playlistVideos?.items?.get(position)
35 | Glide.with(context)
36 | .load(videos?.snippet?.thumbnails?.high?.url)
37 | .into(holder.image)
38 | holder.text1.text = videos?.snippet?.title
39 | holder.text2.text = videos?.snippet?.publishedAt
40 | holder.video.setOnClickListener {
41 | if (videos != null) {
42 | context.startActivity(
43 | Intent(
44 | context, YoutubePlayer::class.java
45 | ).addFlags(
46 | Intent.FLAG_ACTIVITY_NEW_TASK
47 | ).putExtra(
48 | "videoId",videos.contentDetails?.videoId
49 | ).putExtra(
50 | "channelId",videos.snippet?.channelId
51 | )
52 | )
53 | }
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/authentication/User.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.authentication
2 |
3 | data class SignInResult(
4 | val userData : User?,
5 | val errorMessage : String?
6 | )
7 |
8 | data class User(
9 | val userId : String,
10 | val userName : String,
11 | val userEmail : String,
12 | val userImage : String?
13 | )
14 |
15 | data class SignInState(
16 | val isSignInSuccessful : Boolean = false,
17 | val signInError : String? = null
18 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/authentication/utilities/AuthUtility.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.authentication.utilities
2 |
3 | sealed class GoogleAuth(
4 | val data : T? = null,
5 | val message : String? = null
6 | ) {
7 | class Success(data : T) : GoogleAuth(data)
8 | class Error(message: String?,data: T? = null) : GoogleAuth(data,message)
9 | class Loading(data: T? = null) : GoogleAuth(data)
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/authentication/viewModel/UserAuthViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.authentication.viewModel
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import com.google.android.piyush.dopamine.authentication.SignInResult
6 | import com.google.android.piyush.dopamine.authentication.SignInState
7 | import com.google.android.piyush.dopamine.authentication.repository.UserAuthRepositoryImpl
8 | import com.google.firebase.auth.FirebaseUser
9 | import kotlinx.coroutines.flow.MutableStateFlow
10 | import kotlinx.coroutines.flow.asStateFlow
11 | import kotlinx.coroutines.flow.update
12 |
13 | class UserAuthViewModel(
14 | private val userAuthRepositoryImpl: UserAuthRepositoryImpl
15 | ) : ViewModel() {
16 |
17 | private val _state : MutableStateFlow = MutableStateFlow(
18 | SignInState()
19 | )
20 | val state = _state.asStateFlow()
21 |
22 | fun currentUser() : FirebaseUser? {
23 | return userAuthRepositoryImpl.currentUser()
24 | }
25 |
26 | fun onSignInResult(result : SignInResult) {
27 | _state.update {
28 | it.copy(
29 | isSignInSuccessful = result.userData != null,
30 | signInError = result.errorMessage
31 | )
32 | }
33 | }
34 |
35 | fun resetSignInState() {
36 | _state.update { SignInState() }
37 | }
38 | }
39 |
40 | class UserAuthViewModelFactory(
41 | private val userAuthRepositoryImpl: UserAuthRepositoryImpl
42 | ) : ViewModelProvider.Factory{
43 | override fun create(modelClass: Class): T {
44 | if(modelClass.isAssignableFrom(UserAuthViewModel::class.java)) {
45 | @Suppress("UNCHECKED_CAST")
46 | return UserAuthViewModel(userAuthRepositoryImpl) as T
47 | } else {
48 | throw IllegalArgumentException("Unknown ViewModel class")
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/beta/DopamineApp.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.beta
2 |
3 | import android.app.Application
4 | import android.content.ContentValues.TAG
5 | import android.graphics.Bitmap
6 | import android.graphics.BitmapFactory
7 | import android.util.Log
8 | import androidx.appcompat.app.AppCompatDelegate
9 | import com.google.android.material.color.DynamicColors
10 | import com.google.android.piyush.dopamine.utilities.Utilities
11 | import java.io.IOException
12 | import java.net.URL
13 |
14 |
15 | class DopamineApp : Application() {
16 | override fun onCreate() {
17 | super.onCreate()
18 | /*
19 | val policy = ThreadPolicy.Builder().permitAll().build()
20 |
21 | StrictMode.setThreadPolicy(policy)
22 | val image = getBitmapFromUrl(FirebaseAuth.getInstance().currentUser?.photoUrl.toString())
23 |
24 | if(image != null) {
25 | DynamicColors.applyToActivitiesIfAvailable(
26 | this, DynamicColorsOptions.Builder().setContentBasedSource(
27 | image
28 | ).build()
29 | )
30 | } */
31 |
32 | val dopamineApp = applicationContext.getSharedPreferences("DopamineApp", MODE_PRIVATE)
33 |
34 | if(dopamineApp.getString("Theme", Utilities.LIGHT_MODE) == Utilities.LIGHT_MODE){
35 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
36 | }else if(dopamineApp.getString("Theme", Utilities.DARK_MODE) == Utilities.DARK_MODE){
37 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
38 | }else{
39 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
40 | }
41 |
42 | if(dopamineApp.getBoolean("ExperimentalUserColor", false).equals(true)){
43 | DynamicColors.applyToActivitiesIfAvailable(this)
44 | }
45 | }
46 |
47 |
48 | private fun getBitmapFromUrl(imageUrl: String): Bitmap? {
49 | try {
50 | val url = URL(imageUrl)
51 | val inputStream = url.openStream()
52 | return BitmapFactory.decodeStream(inputStream)
53 | } catch (e: IOException) {
54 | Log.e(TAG, "Error downloading image", e)
55 | return null
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/fragments/Shorts.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.fragments
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import androidx.lifecycle.ViewModelProvider
9 | import com.google.android.piyush.dopamine.R
10 | import com.google.android.piyush.dopamine.adapters.ShortsAdapter
11 | import com.google.android.piyush.dopamine.databinding.FragmentShortsBinding
12 | import com.google.android.piyush.dopamine.utilities.NetworkUtilities
13 | import com.google.android.piyush.youtube.repository.YoutubeRepositoryImpl
14 | import com.google.android.piyush.youtube.utilities.YoutubeResource
15 | import com.google.android.piyush.youtube.viewModels.ShortsViewModel
16 | import com.google.android.piyush.youtube.viewModels.ShortsViewModelFactory
17 |
18 | class Shorts : Fragment() {
19 |
20 | private var shortsFragmentBinding: FragmentShortsBinding? = null
21 | private lateinit var youtubeRepositoryImpl: YoutubeRepositoryImpl
22 | private lateinit var shortsViewModel: ShortsViewModel
23 | private lateinit var shortsViewModelFactory: ShortsViewModelFactory
24 |
25 | override fun onCreateView(
26 | inflater: LayoutInflater, container: ViewGroup?,
27 | savedInstanceState: Bundle?
28 | ): View {
29 | return inflater.inflate(R.layout.fragment_shorts, container, false)
30 | }
31 |
32 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
33 | super.onViewCreated(view, savedInstanceState)
34 |
35 | val binding = FragmentShortsBinding.bind(view)
36 | shortsFragmentBinding = binding
37 | youtubeRepositoryImpl = YoutubeRepositoryImpl()
38 | shortsViewModelFactory = ShortsViewModelFactory(youtubeRepositoryImpl)
39 | shortsViewModel = ViewModelProvider(this, shortsViewModelFactory)[ShortsViewModel::class.java]
40 |
41 | if(NetworkUtilities.isNetworkAvailable(requireContext())){
42 | shortsViewModel.shorts.observe(viewLifecycleOwner){ shorts ->
43 | when(shorts){
44 | is YoutubeResource.Loading -> {}
45 | is YoutubeResource.Success -> {
46 | if(shorts.data.isEmpty()){
47 | binding.playWithShortsEffect.apply {
48 | startShimmer()
49 | visibility = View.VISIBLE
50 | }
51 | }else{
52 | binding.playWithShortsEffect.apply {
53 | stopShimmer()
54 | visibility = View.GONE
55 | }
56 | binding.playWithShorts.apply {
57 | adapter = ShortsAdapter(
58 | shorts.data
59 | )
60 | }
61 | }
62 | }
63 | is YoutubeResource.Error -> {
64 | binding.playWithShortsEffect.apply {
65 | startShimmer()
66 | visibility = View.VISIBLE
67 | }
68 | }
69 | }
70 | }
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/CustomPlayListVHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.card.MaterialCardView
6 | import com.google.android.material.textview.MaterialTextView
7 | import com.google.android.piyush.dopamine.R
8 |
9 | class CustomPlayListVHolder (
10 | itemView : View
11 | ) : RecyclerView.ViewHolder(itemView) {
12 | val image : MaterialCardView = itemView.findViewById(R.id.custom_playlist_image)
13 | val title1: MaterialTextView = itemView.findViewById(R.id.playlist_logo_name)
14 | val title: MaterialTextView = itemView.findViewById(R.id.playlist_name)
15 | val description: MaterialTextView = itemView.findViewById(R.id.playlist_description)
16 | val playlist: MaterialCardView = itemView.findViewById(R.id.playlist)
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/CustomPlaylistsVDataHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.card.MaterialCardView
6 | import com.google.android.material.imageview.ShapeableImageView
7 | import com.google.android.material.textview.MaterialTextView
8 | import com.google.android.piyush.dopamine.R
9 |
10 | class CustomPlaylistsVDataHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
11 | val youTubePlayerView : ShapeableImageView = itemView.findViewById(R.id.youtube_player_view)
12 | val imageView : ShapeableImageView = itemView.findViewById(R.id.channel_image)
13 | val videoTitle : MaterialTextView = itemView.findViewById(R.id.video_title)
14 | val channelTitle : MaterialTextView = itemView.findViewById(R.id.channel_title)
15 | val videoDuration : MaterialTextView = itemView.findViewById(R.id.video_duration)
16 | val youTubePlayer : MaterialCardView = itemView.findViewById(R.id.video_card)
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/CustomPlaylistsViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.checkbox.MaterialCheckBox
6 | import com.google.android.material.textview.MaterialTextView
7 | import com.google.android.piyush.dopamine.R
8 |
9 | class CustomPlaylistsViewHolder(
10 | itemView : View
11 | ) : RecyclerView.ViewHolder(itemView) {
12 |
13 | val title: MaterialTextView = itemView.findViewById(R.id.title)
14 | val description: MaterialTextView = itemView.findViewById(R.id.description)
15 | val selectedPlaylistItem : MaterialCheckBox = itemView.findViewById(R.id.selectedPlaylistItem)
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/HomeViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.card.MaterialCardView
6 | import com.google.android.material.imageview.ShapeableImageView
7 | import com.google.android.material.textview.MaterialTextView
8 | import com.google.android.piyush.dopamine.R
9 |
10 | class HomeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
11 | val youTubePlayerView : ShapeableImageView = itemView.findViewById(R.id.youtube_player_view)
12 | val imageView : ShapeableImageView = itemView.findViewById(R.id.channel_image)
13 | val videoTitle : MaterialTextView = itemView.findViewById(R.id.video_title)
14 | val channelTitle : MaterialTextView = itemView.findViewById(R.id.channel_title)
15 | val videoDuration : MaterialTextView = itemView.findViewById(R.id.video_duration)
16 | val youTubePlayer : MaterialCardView = itemView.findViewById(R.id.video_card)
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/LibraryViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.card.MaterialCardView
6 | import com.google.android.material.imageview.ShapeableImageView
7 | import com.google.android.material.textview.MaterialTextView
8 | import com.google.android.piyush.dopamine.R
9 |
10 | class LibraryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
11 |
12 | val video : MaterialCardView = itemView.findViewById(R.id.video)
13 | val image : ShapeableImageView = itemView.findViewById(R.id.image)
14 | val title : MaterialTextView = itemView.findViewById(R.id.text1)
15 | val subtitle : MaterialTextView = itemView.findViewById(R.id.text2)
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/RecentVideosViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.card.MaterialCardView
6 | import com.google.android.material.imageview.ShapeableImageView
7 | import com.google.android.material.textview.MaterialTextView
8 | import com.google.android.piyush.dopamine.R
9 |
10 | class RecentVideosViewHolder(
11 | itemView: View
12 | ) : RecyclerView.ViewHolder(itemView) {
13 | val image : ShapeableImageView = itemView.findViewById(R.id.image)
14 | val title : MaterialTextView = itemView.findViewById(R.id.text)
15 | val customName : MaterialTextView = itemView.findViewById(R.id.text1)
16 | val videoCard : MaterialCardView = itemView.findViewById(R.id.video_card)
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/SearchHistoryViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.textview.MaterialTextView
6 | import com.google.android.piyush.dopamine.R
7 |
8 | class SearchHistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
9 | val searchHistoryItem : MaterialTextView = itemView.findViewById(R.id.textView)
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/SearchViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.button.MaterialButton
6 | import com.google.android.material.card.MaterialCardView
7 | import com.google.android.material.imageview.ShapeableImageView
8 | import com.google.android.material.textview.MaterialTextView
9 | import com.google.android.piyush.dopamine.R
10 |
11 | class SearchViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
12 |
13 | var image : ShapeableImageView = itemView.findViewById(R.id.image)
14 | var text1 : MaterialTextView = itemView.findViewById(R.id.text1)
15 | var text2 : MaterialTextView = itemView.findViewById(R.id.text2)
16 | var video : MaterialCardView = itemView.findViewById(R.id.video)
17 | var channelview : MaterialButton = itemView.findViewById(R.id.ChannelView)
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/ShortsViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.piyush.dopamine.R
6 | import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
7 |
8 | class ShortsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
9 | val shortsPlayer : YouTubePlayerView = itemView.findViewById(R.id.shortsPlayer)
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/YourFavouriteVideosViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.card.MaterialCardView
6 | import com.google.android.material.imageview.ShapeableImageView
7 | import com.google.android.material.textview.MaterialTextView
8 | import com.google.android.piyush.dopamine.R
9 |
10 | class YourFavouriteVideosViewHolder(
11 | itemView: View
12 | ) : RecyclerView.ViewHolder(itemView) {
13 |
14 | val image : ShapeableImageView = itemView.findViewById(R.id.image)
15 | val title : MaterialTextView = itemView.findViewById(R.id.text)
16 | val customName : MaterialTextView = itemView.findViewById(R.id.text1)
17 | val videoCard : MaterialCardView = itemView.findViewById(R.id.video_card)
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/YoutubeChannelPlaylistsViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import android.widget.ImageView
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.google.android.material.card.MaterialCardView
7 | import com.google.android.material.textview.MaterialTextView
8 | import com.google.android.piyush.dopamine.R
9 |
10 | class YoutubeChannelPlaylistsViewHolder(
11 | itemView: View
12 | ) : RecyclerView.ViewHolder(itemView) {
13 |
14 | var playlistImage : ImageView = itemView.findViewById(R.id.playlistImage)
15 | var playlistTitle : MaterialTextView = itemView.findViewById(R.id.playlistTitle)
16 | var playlistChannelTitle : MaterialTextView = itemView.findViewById(R.id.playlistChannelTitle)
17 | var playlist : MaterialCardView = itemView.findViewById(R.id.playlist)
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewHolders/YoutubePlaylistsVideosViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewHolders
2 |
3 | import android.view.View
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.google.android.material.card.MaterialCardView
6 | import com.google.android.material.imageview.ShapeableImageView
7 | import com.google.android.material.textview.MaterialTextView
8 | import com.google.android.piyush.dopamine.R
9 |
10 | class YoutubePlaylistsVideosViewHolder(
11 | itemView: View
12 | ) : RecyclerView.ViewHolder(itemView) {
13 |
14 | val image : ShapeableImageView = itemView.findViewById(R.id.image)
15 | val text1 : MaterialTextView = itemView.findViewById(R.id.text1)
16 | val text2 : MaterialTextView = itemView.findViewById(R.id.text2)
17 | val video : MaterialCardView = itemView.findViewById(R.id.video)
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewModels/DopamineHomeViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewModels
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 |
6 | class DopamineHomeViewModel : ViewModel() {
7 |
8 | private val _selectedFragment : MutableLiveData = MutableLiveData()
9 | val selectedFragment : MutableLiveData = _selectedFragment
10 |
11 | fun setSelectedFragment(fragment : Int) {
12 | _selectedFragment.value = fragment
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewModels/SearchViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewModels
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import androidx.lifecycle.ViewModelProvider
6 | import androidx.lifecycle.viewModelScope
7 | import com.google.android.piyush.youtube.model.SearchTube
8 | import com.google.android.piyush.youtube.repository.YoutubeRepositoryImpl
9 | import com.google.android.piyush.youtube.utilities.YoutubeResource
10 | import kotlinx.coroutines.launch
11 |
12 | class SearchViewModel(
13 | private val youtubeRepositoryImpl: YoutubeRepositoryImpl
14 | ) : ViewModel() {
15 |
16 | private val _searchVideos : MutableLiveData> = MutableLiveData()
17 | val searchVideos : MutableLiveData> = _searchVideos
18 |
19 | private val _reGetSearchVideos : MutableLiveData> = MutableLiveData()
20 | val reGetSearchVideos : MutableLiveData> = _reGetSearchVideos
21 |
22 | fun searchVideos(query : String) {
23 | viewModelScope.launch {
24 | try {
25 | _searchVideos.postValue(YoutubeResource.Loading)
26 | val videos = youtubeRepositoryImpl.getSearchVideos(query)
27 | if(videos.items.isNullOrEmpty()){
28 | _searchVideos.postValue(
29 | YoutubeResource.Error(
30 | Exception(
31 | "The request cannot be completed because you have exceeded your quota."
32 | )
33 | )
34 | )
35 | } else {
36 | _searchVideos.postValue(YoutubeResource.Success(videos))
37 | }
38 | } catch (e : Exception) {
39 | _searchVideos.postValue(YoutubeResource.Error(e))
40 | }
41 | }
42 | }
43 |
44 | fun reSearchVideos(query : String) {
45 | viewModelScope.launch {
46 | try {
47 | _reGetSearchVideos.postValue(YoutubeResource.Loading)
48 | val videos = youtubeRepositoryImpl.reGetSearchVideos(query)
49 | if(videos.items.isNullOrEmpty()){
50 | _reGetSearchVideos.postValue(
51 | YoutubeResource.Error(
52 | Exception(
53 | "The request cannot be completed because you have exceeded your quota."
54 | )
55 | )
56 | )
57 | } else {
58 | _reGetSearchVideos.postValue(YoutubeResource.Success(videos))
59 | }
60 | } catch (e : Exception) {
61 | _reGetSearchVideos.postValue(YoutubeResource.Error(e))
62 | }
63 | }
64 | }
65 | }
66 |
67 |
68 | @Suppress("UNCHECKED_CAST")
69 | class SearchViewModelFactory(
70 | private val youtubeRepositoryImpl: YoutubeRepositoryImpl
71 | ) : ViewModelProvider.Factory {
72 | override fun create(modelClass: Class): T {
73 | if(modelClass.isAssignableFrom(SearchViewModel::class.java)) {
74 | return SearchViewModel(youtubeRepositoryImpl) as T
75 | } else {
76 | throw IllegalArgumentException("Unknown ViewModel class")
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewModels/SharedViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewModels
2 |
3 | import androidx.lifecycle.ViewModel
4 |
5 | class SharedViewModel : ViewModel()
--------------------------------------------------------------------------------
/app/src/main/java/com/google/android/piyush/dopamine/viewModels/YoutubeChannelPlaylistsVideosViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine.viewModels
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import androidx.lifecycle.ViewModelProvider
6 | import androidx.lifecycle.viewModelScope
7 | import com.google.android.piyush.youtube.model.Youtube
8 | import com.google.android.piyush.youtube.repository.YoutubeRepositoryImpl
9 | import com.google.android.piyush.youtube.utilities.YoutubeResource
10 | import kotlinx.coroutines.launch
11 |
12 | class YoutubeChannelPlaylistsVideosViewModel(
13 | private val youtubeRepositoryImpl: YoutubeRepositoryImpl
14 | ) : ViewModel() {
15 |
16 | private val _playlistsVideos : MutableLiveData> = MutableLiveData()
17 | val playlistsVideos : MutableLiveData> = _playlistsVideos
18 |
19 | fun getPlaylistsVideos(channelId: String) {
20 | viewModelScope.launch {
21 | try {
22 | _playlistsVideos.postValue(YoutubeResource.Loading)
23 | val response = youtubeRepositoryImpl.getPlaylistVideos(channelId)
24 | if(response.items.isNullOrEmpty()) {
25 | _playlistsVideos.postValue(
26 | YoutubeResource.Error(
27 | Exception(
28 | "The request cannot be completed because you have exceeded your quota."
29 | )
30 | )
31 | )
32 | } else {
33 | _playlistsVideos.postValue(
34 | YoutubeResource.Success(response)
35 | )
36 | }
37 | }catch (exception: Exception) {
38 | _playlistsVideos.postValue(
39 | YoutubeResource.Error(exception)
40 | )
41 | }
42 | }
43 | }
44 | }
45 |
46 | @Suppress("UNCHECKED_CAST")
47 | class YoutubeChannelPlaylistsViewModelFactory(
48 | private val youtubeRepositoryImpl: YoutubeRepositoryImpl
49 | ) : ViewModelProvider.Factory {
50 | override fun create(modelClass: Class): T {
51 | if(modelClass.isAssignableFrom(YoutubeChannelPlaylistsVideosViewModel::class.java)) {
52 | return YoutubeChannelPlaylistsVideosViewModel(youtubeRepositoryImpl) as T
53 | }
54 | throw IllegalArgumentException("Unknown ViewModel class")
55 | }
56 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/checked.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/clear.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/default_user.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/done.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/download_circle.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/facebook.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/get_data_problem.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/github.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/google_material_design_logo.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_alert.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_android.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_back.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_beta_app.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_copy_text.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_dialog_error.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_dopamine.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_download.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_facebook.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_favourite.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_favourite_videos_fill.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_favourite_videos_out.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_google.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_history.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_home_fill.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_home_out.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_info.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
11 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_library.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_library_fill.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_library_out.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_like_video.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_picture_in_picture.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_search.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_search_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_select.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_shorts.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_shorts_fill.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_shorts_out.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_sign_out.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_theme.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_update.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_view.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_voice_search.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/idcard.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/instagram.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/location.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/mail.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/mail_outline.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/memory.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/phone.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/round_add_24.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/round_download_24.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/round_local_phone_24.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/round_sd_storage_24.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/share.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/unchecked.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/video.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/website.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/whatsapp.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/wifi_off.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/font/circular_spotify.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/font/circular_spotify.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/circular_std.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/font/circular_std.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/gotham.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/font/gotham.ttf
--------------------------------------------------------------------------------
/app/src/main/res/font/proxima_nova.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/font/proxima_nova.otf
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_cvplaylist.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
25 |
26 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_dopamine_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
20 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_dopamine_video_watch_history.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
22 |
23 |
31 |
32 |
33 |
34 |
35 |
36 |
46 |
47 |
56 |
57 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_youtube_channel_playlists_videos.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
21 |
25 |
26 |
27 |
38 |
39 |
50 |
51 |
62 |
63 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_dopamine_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/bottom_sheet_add_playlist.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
22 |
23 |
24 |
32 |
33 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_shorts.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
15 |
16 |
17 |
18 |
19 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_activity_video_views_history.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
12 |
22 |
23 |
38 |
39 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_activity_youtube_channel_playlists.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
21 |
22 |
36 |
37 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_activity_youtube_playlists_videos.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
13 |
22 |
23 |
35 |
36 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_fragment_library.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
14 |
23 |
24 |
38 |
39 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_fragment_library_your_favourite_videos.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
12 |
22 |
23 |
38 |
39 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_fragment_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_fragment_shorts.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/shimmer_item_fragment_shorts.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/bottom_nav_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/search_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/user_profile_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
33 |
34 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - Reply
5 | - Reply to all
6 |
7 |
8 |
9 | - reply
10 | - reply_all
11 |
12 |
13 |
14 | - Follow System Dark Mode
15 | - Light Mode Selected
16 | - Dark Mode Selected
17 | - Auto Battery Dark Mode
18 |
19 |
20 |
21 | - 1
22 | - 2
23 | - 3
24 | - 4
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #000000
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
34 |
35 |
39 |
40 |
41 |
42 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/test/java/com/google/android/piyush/dopamine/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.google.android.piyush.dopamine
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 | }
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | alias(libs.plugins.android.application) apply false
4 | alias(libs.plugins.jetbrains.kotlin.android) apply false
5 | alias(libs.plugins.android.library) apply false
6 | alias(libs.plugins.google.gms.google.services) apply false
7 | kotlin("jvm") version "1.9.23"
8 | id("com.google.devtools.ksp") version "1.9.23-1.0.19" apply false
9 | }
--------------------------------------------------------------------------------
/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "11459978795",
4 | "project_id": "dopamine-rtx",
5 | "storage_bucket": "dopamine-rtx.firebasestorage.app"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:11459978795:android:f875a5d00554bbe3932c6e",
11 | "android_client_info": {
12 | "package_name": "com.google.android.piyush.dopamine"
13 | }
14 | },
15 | "oauth_client": [],
16 | "api_key": [
17 | {
18 | "current_key": "AIzaSyDHjTGfegLmCvNseHglpYhQoCFHH15MJ54"
19 | }
20 | ],
21 | "services": {
22 | "appinvite_service": {
23 | "other_platform_oauth_client": []
24 | }
25 | }
26 | }
27 | ],
28 | "configuration_version": "1"
29 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. For more details, visit
12 | # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kotlindevs/Dopamine/a4dd1e7b5f4a57215d6e4ec6e0482cb4fba31df2/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Mar 07 16:55:05 IST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google {
4 | content {
5 | includeGroupByRegex("com\\.android.*")
6 | includeGroupByRegex("com\\.google.*")
7 | includeGroupByRegex("androidx.*")
8 | }
9 | }
10 | mavenCentral()
11 | gradlePluginPortal()
12 | }
13 | }
14 | dependencyResolutionManagement {
15 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
16 | repositories {
17 | google()
18 | mavenCentral()
19 | maven(url = "https://jitpack.io")
20 | }
21 | }
22 |
23 | rootProject.name = "Dopamine"
24 | include(":app")
25 | include(":Youtube")
26 | include(":Database")
27 |
--------------------------------------------------------------------------------
/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "applicationId" : "com.google.android.piyush.dopamine",
3 | "minSdk" : 24,
4 | "targetsdk" : 34,
5 | "versionCode" : 1,
6 | "versionName" : "dopamine_20241503_04.phone.stable.dynamic",
7 | "jvmTarget" : 1.8,
8 | "url": "https://github.com/kotlindevs/Dopamine/releases/download/dopamine_20241503_04.phone.stable.dynamic/dopamine_20241503_04.phone.stable.dynamic-arm64-v8a-debug.apk",
9 | "inherit": true
10 | }
--------------------------------------------------------------------------------