├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── gradle.xml ├── jarRepositories.xml ├── misc.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── release │ └── output.json └── src │ └── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ └── aculix │ │ └── channelify │ │ └── app │ │ ├── Channelify.kt │ │ ├── activity │ │ ├── MainActivity.kt │ │ ├── SplashActivity.kt │ │ └── VideoPlayerActivity.kt │ │ ├── api │ │ ├── ChannelInfoService.kt │ │ ├── ChannelsService.kt │ │ ├── CommentRepliesService.kt │ │ ├── CommentService.kt │ │ ├── PlaylistItemsService.kt │ │ ├── PlaylistsService.kt │ │ ├── SearchVideoService.kt │ │ └── VideosService.kt │ │ ├── db │ │ ├── ChannelifyDatabase.kt │ │ └── FavoriteVideoDao.kt │ │ ├── di │ │ ├── aboutModule.kt │ │ ├── appModule.kt │ │ ├── commentRepliesModule.kt │ │ ├── commentsModule.kt │ │ ├── favoritesModule.kt │ │ ├── homeModule.kt │ │ ├── playlistVideosModule.kt │ │ ├── playlistsModule.kt │ │ ├── searchModule.kt │ │ ├── videoDetailsModule.kt │ │ └── videoPlayerModule.kt │ │ ├── fastadapteritems │ │ ├── CommentItem.kt │ │ ├── CommentReplyItem.kt │ │ ├── FavoriteItem.kt │ │ ├── HomeItem.kt │ │ ├── PlaylistItem.kt │ │ ├── PlaylistVideoItem.kt │ │ ├── ProgressIndicatorItem.kt │ │ └── SearchItem.kt │ │ ├── fragment │ │ ├── AboutFragment.kt │ │ ├── AppInfoFragment.kt │ │ ├── CommentRepliesFragment.kt │ │ ├── CommentsFragment.kt │ │ ├── FavoritesFragment.kt │ │ ├── HomeFragment.kt │ │ ├── PlaylistVideosFragment.kt │ │ ├── PlaylistsFragment.kt │ │ ├── SearchFragment.kt │ │ └── VideoDetailsFragment.kt │ │ ├── model │ │ ├── ChannelInfo.kt │ │ ├── ChannelUploadsPlaylistInfo.kt │ │ ├── Comment.kt │ │ ├── CommentReply.kt │ │ ├── FavoriteVideo.kt │ │ ├── Playlist.kt │ │ ├── PlaylistItemInfo.kt │ │ ├── SearchedVideo.kt │ │ └── Video.kt │ │ ├── paging │ │ ├── NetworkState.kt │ │ ├── datasource │ │ │ ├── CommentRepliesDataSource.kt │ │ │ ├── CommentsDataSource.kt │ │ │ ├── HomeDataSource.kt │ │ │ ├── PlaylistVideosDataSource.kt │ │ │ ├── PlaylistsDataSource.kt │ │ │ └── SearchDataSource.kt │ │ └── datasourcefactory │ │ │ ├── CommentRepliesDataSourceFactory.kt │ │ │ ├── CommentsDataSourceFactory.kt │ │ │ ├── HomeDataSourceFactory.kt │ │ │ ├── PlaylistVideosDataSourceFactory.kt │ │ │ ├── PlaylistsDataSourceFactory.kt │ │ │ └── SearchDataSourceFactory.kt │ │ ├── repository │ │ ├── AboutRepository.kt │ │ ├── CommentRepliesRepository.kt │ │ ├── CommentsRepository.kt │ │ ├── FavoritesRepository.kt │ │ ├── HomeRepository.kt │ │ ├── PlaylistVideosRepository.kt │ │ ├── PlaylistsRepository.kt │ │ ├── SearchRepository.kt │ │ ├── VideoDetailsRepository.kt │ │ └── VideoPlayerRepository.kt │ │ ├── sharedpref │ │ └── AppPref.kt │ │ ├── utils │ │ ├── ActivityExtensions.kt │ │ ├── Constants.kt │ │ ├── DateTimeUtils.kt │ │ ├── DividerItemDecorator.kt │ │ ├── FragmentActivityExtensions.kt │ │ └── FullScreenHelper.kt │ │ └── viewmodel │ │ ├── AboutViewModel.kt │ │ ├── CommentRepliesViewModel.kt │ │ ├── CommentsViewModel.kt │ │ ├── FavoritesViewModel.kt │ │ ├── HomeViewModel.kt │ │ ├── PlaylistVideosViewModel.kt │ │ ├── PlaylistsViewModel.kt │ │ ├── SearchViewModel.kt │ │ ├── VideoDetailsViewModel.kt │ │ └── VideoPlayerViewModel.kt │ └── res │ ├── anim │ ├── slide_in_bottom.xml │ └── slide_out_bottom.xml │ ├── drawable-hdpi │ └── ic_stat_notification.png │ ├── drawable-mdpi │ └── ic_stat_notification.png │ ├── drawable-night │ ├── ic_empty_comments.xml │ ├── ic_empty_favorites.xml │ ├── ic_empty_playlists.xml │ ├── ic_error.xml │ └── ic_error_video_details.xml │ ├── drawable-xhdpi │ └── ic_stat_notification.png │ ├── drawable-xxhdpi │ └── ic_stat_notification.png │ ├── drawable-xxxhdpi │ └── ic_stat_notification.png │ ├── drawable │ ├── bg_rounded_rect.xml │ ├── bg_splash.xml │ ├── ic_about.xml │ ├── ic_arrow_back.xml │ ├── ic_close.xml │ ├── ic_comment.xml │ ├── ic_dislike.xml │ ├── ic_email.xml │ ├── ic_empty_comments.xml │ ├── ic_empty_favorites.xml │ ├── ic_empty_playlists.xml │ ├── ic_error.xml │ ├── ic_error_about.xml │ ├── ic_error_video_details.xml │ ├── ic_favorite_border.xml │ ├── ic_favorite_filled.xml │ ├── ic_favorite_filled_border.xml │ ├── ic_forward.xml │ ├── ic_google_play.xml │ ├── ic_home.xml │ ├── ic_info.xml │ ├── ic_instagram.xml │ ├── ic_like.xml │ ├── ic_playlists.xml │ ├── ic_privacy_policy.xml │ ├── ic_retry.xml │ ├── ic_rewind.xml │ ├── ic_search.xml │ ├── ic_share.xml │ ├── ic_sort.xml │ ├── ic_star.xml │ ├── ic_store.xml │ ├── ic_theme_dark.xml │ ├── ic_theme_light.xml │ ├── ic_tos.xml │ ├── ic_unfold_more.xml │ ├── ic_view_count.xml │ ├── ic_website.xml │ ├── logo_splash.png │ └── view_divider_item_decorator.xml │ ├── font │ └── roboto.xml │ ├── layout │ ├── activity_main.xml │ ├── activity_video_player.xml │ ├── fragment_about.xml │ ├── fragment_app_info.xml │ ├── fragment_comment_replies.xml │ ├── fragment_comments.xml │ ├── fragment_favorites.xml │ ├── fragment_home.xml │ ├── fragment_playlist_details.xml │ ├── fragment_playlist_videos.xml │ ├── fragment_playlists.xml │ ├── fragment_search.xml │ ├── fragment_video_details.xml │ ├── item_comment.xml │ ├── item_comment_reply.xml │ ├── item_favorite.xml │ ├── item_home.xml │ ├── item_playlist.xml │ ├── item_playlist_video.xml │ ├── item_progress_indicator.xml │ ├── item_search.xml │ └── widget_toolbar.xml │ ├── menu │ ├── app_info_menu.xml │ ├── bab_menu_video_details.xml │ ├── bottom_navigation_menu.xml │ ├── comments_sort_menu_video_details.xml │ ├── main_menu.xml │ ├── toolbar_menu_about.xml │ └── toolbar_menu_playlist_videos.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── navigation │ ├── nav_graph.xml │ └── video_player_graph.xml │ ├── values-night │ ├── colors.xml │ ├── config.xml │ └── styles.xml │ └── values │ ├── colors.xml │ ├── config.xml │ ├── dimens.xml │ ├── font_certs.xml │ ├── ic_launcher_background.xml │ ├── ids.xml │ ├── preloaded_fonts.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── core ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── aculix │ │ └── core │ │ ├── base │ │ ├── BaseFragment.kt │ │ └── RoundedBottomSheetDialogFragment.kt │ │ ├── extensions │ │ ├── ButtonExtensions.kt │ │ ├── ChipExtensions.kt │ │ ├── ContextExtensions.kt │ │ ├── EditTextExtensions.kt │ │ ├── FragmentExtensions.kt │ │ ├── ImageViewExtensions.kt │ │ ├── IntExtensions.kt │ │ ├── LongExtensions.kt │ │ ├── StringExtensions.kt │ │ ├── ViewExtensions.kt │ │ └── ViewgroupExtensions.kt │ │ └── helper │ │ ├── BaseViewModelFactory.kt │ │ ├── ResultWrapper.kt │ │ └── SimpleDividerItemDecoration.kt │ └── res │ ├── drawable-v24 │ └── ic_launcher_background.xml │ ├── drawable │ ├── bg_bottom_sheet.xml │ ├── bg_line_divider.xml │ ├── ic_launcher_foreground.xml │ ├── ic_place_holder.xml │ └── ic_place_holder_wrapper.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Aculix Technologies LLP 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | -keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | ##-------------------------- Model classes -------------------------- 24 | -keep class aculix.channelify.app.model.** { *; } 25 | 26 | 27 | #-------------------------- Coroutines --------------------------# 28 | 29 | # ServiceLoader support 30 | -keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {} 31 | -keepnames class kotlinx.coroutines.CoroutineExceptionHandler {} 32 | -keepnames class kotlinx.coroutines.android.AndroidExceptionPreHandler {} 33 | -keepnames class kotlinx.coroutines.android.AndroidDispatcherFactory {} 34 | 35 | # Most of volatile fields are updated with AFU and should not be mangled 36 | -keepclassmembernames class kotlinx.** { 37 | volatile ; 38 | } 39 | 40 | 41 | #-------------------------- OkHttp --------------------------# 42 | 43 | # JSR 305 annotations are for embedding nullability information. 44 | -dontwarn javax.annotation.** 45 | 46 | # A resource is loaded with a relative path so the package of this class must be preserved. 47 | -keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase 48 | 49 | # Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. 50 | -dontwarn org.codehaus.mojo.animal_sniffer.* 51 | 52 | # OkHttp platform used only on JVM and when Conscrypt dependency is available. 53 | -dontwarn okhttp3.internal.platform.ConscryptPlatform 54 | 55 | # Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. 56 | -dontwarn org.codehaus.mojo.animal_sniffer.* 57 | -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":7,"versionName":"1.32","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release","dirName":""},"path":"app-release.apk","properties":{}}] -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 38 | 39 | 42 | 43 | 44 | 47 | 48 | 51 | 52 | 53 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aculix/Channelify/803ed24cc76dff0588e652f2d25298fb6f7109b6/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/Channelify.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app 2 | 3 | import aculix.channelify.app.di.* 4 | import aculix.channelify.app.sharedpref.AppPref 5 | import android.app.Application 6 | import androidx.appcompat.app.AppCompatDelegate 7 | import com.chibatching.kotpref.Kotpref 8 | import com.google.android.gms.ads.MobileAds 9 | import com.google.android.gms.ads.RequestConfiguration 10 | import org.koin.android.ext.koin.androidContext 11 | import org.koin.android.ext.koin.androidLogger 12 | import org.koin.core.context.startKoin 13 | import saschpe.android.customtabs.CustomTabsActivityLifecycleCallbacks 14 | import timber.log.Timber 15 | import java.util.* 16 | 17 | class Channelify : Application() { 18 | 19 | companion object { 20 | var isAdEnabled = true 21 | } 22 | 23 | override fun onCreate() { 24 | super.onCreate() 25 | isAdEnabled = resources.getBoolean(R.bool.enable_ads) 26 | 27 | initializeKotpref() 28 | setThemeMode() 29 | initializeTimber() 30 | initializeKoin() 31 | initializeCustomTabs() 32 | 33 | if (resources.getBoolean(R.bool.enable_ads)) initializeAdmob() 34 | } 35 | 36 | private fun setThemeMode() { 37 | if (AppPref.isLightThemeEnabled) { 38 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) 39 | } else { 40 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) 41 | } 42 | 43 | } 44 | 45 | private fun initializeTimber() { 46 | if (BuildConfig.DEBUG) { 47 | Timber.plant(Timber.DebugTree()) 48 | } 49 | } 50 | 51 | private fun initializeKotpref() { 52 | Kotpref.init(this) 53 | } 54 | 55 | private fun initializeKoin() { 56 | startKoin { 57 | androidLogger() 58 | androidContext(this@Channelify) 59 | modules( 60 | listOf( 61 | appModule, 62 | homeModule, 63 | videoPlayerModule, 64 | commentsModule, 65 | videoDetailsModule, 66 | commentRepliesModule, 67 | playlistsModule, 68 | playlistVideosModule, 69 | favoritesModule, 70 | searchModule, 71 | aboutModule 72 | ) 73 | ) 74 | } 75 | } 76 | 77 | private fun initializeAdmob() { 78 | MobileAds.initialize(this) { 79 | val testDeviceIds = listOf("7BD04413716C0B3DD5C73F814E02D21A") 80 | val configuration = 81 | RequestConfiguration.Builder().setTestDeviceIds(testDeviceIds).build() 82 | MobileAds.setRequestConfiguration(configuration) 83 | } 84 | } 85 | 86 | private fun initializeCustomTabs() { 87 | registerActivityLifecycleCallbacks(CustomTabsActivityLifecycleCallbacks()) 88 | } 89 | } -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/activity/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.activity 2 | 3 | import aculix.channelify.app.Channelify 4 | import aculix.channelify.app.R 5 | import aculix.channelify.app.utils.getAdaptiveBannerAdSize 6 | import aculix.core.extensions.makeGone 7 | import androidx.appcompat.app.AppCompatActivity 8 | import android.os.Bundle 9 | import android.util.DisplayMetrics 10 | import androidx.navigation.findNavController 11 | import androidx.navigation.ui.setupWithNavController 12 | import com.google.android.gms.ads.* 13 | import kotlinx.android.synthetic.main.activity_main.* 14 | import java.util.* 15 | 16 | class MainActivity : AppCompatActivity() { 17 | 18 | private lateinit var adView: AdView 19 | private var initialLayoutComplete = false 20 | 21 | override fun onCreate(savedInstanceState: Bundle?) { 22 | super.onCreate(savedInstanceState) 23 | setContentView(R.layout.activity_main) 24 | 25 | 26 | val navController = findNavController(R.id.navHostFragment) 27 | bottomNavView.setupWithNavController(navController) 28 | 29 | if (Channelify.isAdEnabled) setupAd() else adViewContainerMain.makeGone() 30 | 31 | } 32 | 33 | override fun onPause() { 34 | if (Channelify.isAdEnabled) adView.pause() 35 | super.onPause() 36 | } 37 | 38 | override fun onResume() { 39 | if (Channelify.isAdEnabled) adView.resume() 40 | super.onResume() 41 | } 42 | 43 | override fun onDestroy() { 44 | if (Channelify.isAdEnabled) adView.destroy() 45 | super.onDestroy() 46 | } 47 | 48 | private fun setupAd() { 49 | adView = AdView(this) 50 | adViewContainerMain.addView(adView) 51 | adViewContainerMain.viewTreeObserver.addOnGlobalLayoutListener { 52 | if (!initialLayoutComplete) { 53 | initialLayoutComplete = true 54 | 55 | adView.adUnitId = getString(R.string.main_banner_ad_id) 56 | adView.adSize = getAdaptiveBannerAdSize(adViewContainerMain) 57 | adView.loadAd(AdRequest.Builder().build()) 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/activity/SplashActivity.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.activity 2 | 3 | import android.content.Intent 4 | import androidx.appcompat.app.AppCompatActivity 5 | import android.os.Bundle 6 | 7 | class SplashActivity : AppCompatActivity() { 8 | 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | 12 | val intent = Intent(this, MainActivity::class.java) 13 | startActivity(intent) 14 | finish() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/api/ChannelInfoService.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.api 2 | 3 | import aculix.channelify.app.model.ChannelInfo 4 | import retrofit2.Response 5 | import retrofit2.http.GET 6 | import retrofit2.http.Query 7 | 8 | interface ChannelInfoService { 9 | 10 | @GET("channels") 11 | suspend fun getChannelInfo( 12 | @Query("id") channelId: String, 13 | @Query("part") part: String = "snippet, statistics, brandingSettings", 14 | @Query("fields") fields: String = "items(snippet(title, description, publishedAt, thumbnails), statistics(viewCount, subscriberCount, videoCount), brandingSettings(image(bannerMobileHdImageUrl, bannerMobileMediumHdImageUrl)))", 15 | @Query("maxResults") maxResults: Int = 1 16 | ): Response 17 | } -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/api/ChannelsService.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.api 2 | 3 | import aculix.channelify.app.model.ChannelUploadsPlaylistInfo 4 | import aculix.channelify.app.model.SearchedVideo 5 | import retrofit2.Response 6 | import retrofit2.http.GET 7 | import retrofit2.http.Query 8 | 9 | interface ChannelsService { 10 | 11 | @GET("channels") 12 | suspend fun getChannelUploadsPlaylistInfo( 13 | @Query("id") channelId: String, 14 | @Query("part") part: String = "contentDetails" 15 | ): Response 16 | } -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/api/CommentRepliesService.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.api 2 | 3 | import aculix.channelify.app.model.CommentReply 4 | import aculix.channelify.app.utils.Constants 5 | import retrofit2.Response 6 | import retrofit2.http.GET 7 | import retrofit2.http.Query 8 | 9 | interface CommentRepliesService { 10 | 11 | /** 12 | * Gets the list of replies for a particular comment 13 | */ 14 | @GET("comments") 15 | suspend fun getCommentReplies( 16 | @Query("parentId") commentId: String, 17 | @Query("pageToken") pageToken: String?, 18 | @Query("part") part: String = "snippet", 19 | @Query("fields") fields: String = "nextPageToken, items(snippet(authorDisplayName, authorProfileImageUrl, textOriginal, likeCount, publishedAt, updatedAt))", 20 | @Query("maxResults") maxResults: Int = Constants.YT_API_MAX_RESULTS 21 | ): Response 22 | } -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/api/CommentService.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.api 2 | 3 | import aculix.channelify.app.model.Comment 4 | import aculix.channelify.app.model.CommentReply 5 | import aculix.channelify.app.model.PlaylistItemInfo 6 | import aculix.channelify.app.utils.Constants 7 | import retrofit2.Response 8 | import retrofit2.http.GET 9 | import retrofit2.http.Query 10 | 11 | interface CommentService { 12 | 13 | /** 14 | * Gets the list of comments of a particular video 15 | */ 16 | @GET("commentThreads") 17 | suspend fun getVideoComments( 18 | @Query("videoId") videoId: String, 19 | @Query("pageToken") pageToken: String?, 20 | @Query("order") sortOrder: String, 21 | @Query("part") part: String = "snippet", 22 | @Query("fields") fields: String = "nextPageToken, items(snippet(topLevelComment(id, snippet(authorDisplayName, authorProfileImageUrl, textOriginal, likeCount, publishedAt, updatedAt)), totalReplyCount))", 23 | @Query("maxResults") maxResults: Int = Constants.YT_API_MAX_RESULTS 24 | ): Response 25 | } -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/api/PlaylistItemsService.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.api 2 | 3 | import aculix.channelify.app.model.ChannelUploadsPlaylistInfo 4 | import aculix.channelify.app.model.PlaylistItemInfo 5 | import aculix.channelify.app.utils.Constants 6 | import retrofit2.Response 7 | import retrofit2.http.GET 8 | import retrofit2.http.Query 9 | 10 | interface PlaylistItemsService { 11 | 12 | @GET("playlistItems") 13 | suspend fun getPlaylistVideos( 14 | @Query("playlistId") playlistId: String, 15 | @Query("pageToken") pageToken: String?, 16 | @Query("part") part: String = "snippet,contentDetails", 17 | @Query("fields") fields: String = "nextPageToken, prevPageToken, items(snippet(title, thumbnails), contentDetails(videoId, videoPublishedAt))", 18 | @Query("maxResults") maxResults: Int = Constants.YT_API_MAX_RESULTS 19 | ): Response 20 | } -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/api/PlaylistsService.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.api 2 | 3 | import aculix.channelify.app.model.Playlist 4 | import aculix.channelify.app.utils.Constants 5 | import retrofit2.Response 6 | import retrofit2.http.GET 7 | import retrofit2.http.Query 8 | 9 | interface PlaylistsService { 10 | 11 | @GET("playlists") 12 | suspend fun getPlaylists( 13 | @Query("channelId") channelId: String, 14 | @Query("pageToken") pageToken: String?, 15 | @Query("part") part: String = "snippet,contentDetails", 16 | @Query("fields") fields: String = "nextPageToken, items(id, snippet(publishedAt, title, description, thumbnails), contentDetails)", 17 | @Query("maxResults") maxResults: Int = Constants.YT_API_MAX_RESULTS 18 | ): Response 19 | } -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/api/SearchVideoService.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.api 2 | 3 | import aculix.channelify.app.model.SearchedVideo 4 | import aculix.channelify.app.utils.Constants 5 | import retrofit2.Response 6 | import retrofit2.http.GET 7 | import retrofit2.http.Query 8 | import retrofit2.http.QueryMap 9 | 10 | interface SearchVideoService { 11 | 12 | @GET("search") 13 | suspend fun searchVideos( 14 | @Query("q") searchQuery: String, 15 | @Query("channelId") channelId: String, 16 | @Query("pageToken") pageToken: String?, 17 | @QueryMap defaultQueryMap: HashMap, 18 | @Query("maxResults") maxResults: Int = Constants.YT_API_MAX_RESULTS 19 | ): Response 20 | } -------------------------------------------------------------------------------- /app/src/main/java/aculix/channelify/app/api/VideosService.kt: -------------------------------------------------------------------------------- 1 | package aculix.channelify.app.api 2 | 3 | import aculix.channelify.app.model.Video 4 | import retrofit2.Response 5 | import retrofit2.http.GET 6 | import retrofit2.http.Query 7 | 8 | interface VideosService { 9 | 10 | @GET("videos") 11 | suspend fun getVideoInfo( 12 | @Query("id") videoId: String, 13 | @Query("part") part: String = "snippet, statistics", 14 | @Query("fields") fields: String = "items(snippet(publishedAt, title, description, thumbnails), statistics)", 15 | @Query("maxResults") maxResults: Int = 1 16 | ): Response