diff --git a/.gradle/6.5/executionHistory/executionHistory.bin b/.gradle/6.5/executionHistory/executionHistory.bin deleted file mode 100644 index b6b7221..0000000 Binary files a/.gradle/6.5/executionHistory/executionHistory.bin and /dev/null differ diff --git a/.gradle/6.5/executionHistory/executionHistory.lock b/.gradle/6.5/executionHistory/executionHistory.lock deleted file mode 100644 index bff8f54..0000000 Binary files a/.gradle/6.5/executionHistory/executionHistory.lock and /dev/null differ diff --git a/.gradle/6.5/fileChanges/last-build.bin b/.gradle/6.5/fileChanges/last-build.bin deleted file mode 100644 index f76dd23..0000000 Binary files a/.gradle/6.5/fileChanges/last-build.bin and /dev/null differ diff --git a/.gradle/6.5/fileContent/fileContent.lock b/.gradle/6.5/fileContent/fileContent.lock deleted file mode 100644 index 6ba83b9..0000000 Binary files a/.gradle/6.5/fileContent/fileContent.lock and /dev/null differ diff --git a/.gradle/6.5/fileHashes/fileHashes.bin b/.gradle/6.5/fileHashes/fileHashes.bin deleted file mode 100644 index 78b61b7..0000000 Binary files a/.gradle/6.5/fileHashes/fileHashes.bin and /dev/null differ diff --git a/.gradle/6.5/fileHashes/fileHashes.lock b/.gradle/6.5/fileHashes/fileHashes.lock deleted file mode 100644 index 1e6647c..0000000 Binary files a/.gradle/6.5/fileHashes/fileHashes.lock and /dev/null differ diff --git a/.gradle/6.5/fileHashes/resourceHashesCache.bin b/.gradle/6.5/fileHashes/resourceHashesCache.bin deleted file mode 100644 index c641549..0000000 Binary files a/.gradle/6.5/fileHashes/resourceHashesCache.bin and /dev/null differ diff --git a/.gradle/6.5/javaCompile/classAnalysis.bin b/.gradle/6.5/javaCompile/classAnalysis.bin deleted file mode 100644 index 3d2ceb8..0000000 Binary files a/.gradle/6.5/javaCompile/classAnalysis.bin and /dev/null differ diff --git a/.gradle/6.5/javaCompile/jarAnalysis.bin b/.gradle/6.5/javaCompile/jarAnalysis.bin deleted file mode 100644 index f7625c3..0000000 Binary files a/.gradle/6.5/javaCompile/jarAnalysis.bin and /dev/null differ diff --git a/.gradle/6.5/javaCompile/javaCompile.lock b/.gradle/6.5/javaCompile/javaCompile.lock deleted file mode 100644 index 97548d8..0000000 Binary files a/.gradle/6.5/javaCompile/javaCompile.lock and /dev/null differ diff --git a/.gradle/6.5/javaCompile/taskHistory.bin b/.gradle/6.5/javaCompile/taskHistory.bin deleted file mode 100644 index 182abe2..0000000 Binary files a/.gradle/6.5/javaCompile/taskHistory.bin and /dev/null differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock deleted file mode 100644 index c9bbb9b..0000000 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and /dev/null differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index 5c3ca88..0000000 --- a/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Mon Nov 16 21:41:36 MSK 2020 -gradle.version=6.5 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin deleted file mode 100644 index e55a8af..0000000 Binary files a/.gradle/buildOutputCleanup/outputFiles.bin and /dev/null differ diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock deleted file mode 100644 index ac85cc8..0000000 Binary files a/.gradle/checksums/checksums.lock and /dev/null differ diff --git a/.gradle/checksums/md5-checksums.bin b/.gradle/checksums/md5-checksums.bin deleted file mode 100644 index 9452031..0000000 Binary files a/.gradle/checksums/md5-checksums.bin and /dev/null differ diff --git a/.gradle/checksums/sha1-checksums.bin b/.gradle/checksums/sha1-checksums.bin deleted file mode 100644 index 1d73c2c..0000000 Binary files a/.gradle/checksums/sha1-checksums.bin and /dev/null differ diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index fcb0c83..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -Spotifine \ No newline at end of file diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser deleted file mode 100644 index dd0cd3c..0000000 Binary files a/.idea/caches/build_file_checksums.ser and /dev/null differ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 45dce39..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,114 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 61a9130..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/dictionaries/firek.xml b/.idea/dictionaries/firek.xml deleted file mode 100644 index 70b8ccc..0000000 --- a/.idea/dictionaries/firek.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - archrahkshi - spotifine - сover - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index d00af75..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index e34606c..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_activity_activity_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_activity_activity_1_0_0_aar.xml deleted file mode 100644 index 3a857bf..0000000 --- a/.idea/libraries/Gradle__androidx_activity_activity_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_annotation_annotation_1_1_0.xml b/.idea/libraries/Gradle__androidx_annotation_annotation_1_1_0.xml deleted file mode 100644 index b2158ac..0000000 --- a/.idea/libraries/Gradle__androidx_annotation_annotation_1_1_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_annotation_annotation_experimental_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_annotation_annotation_experimental_1_0_0_aar.xml deleted file mode 100644 index 1481a9b..0000000 --- a/.idea/libraries/Gradle__androidx_annotation_annotation_experimental_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_2_0_aar.xml b/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_2_0_aar.xml deleted file mode 100644 index 604edce..0000000 --- a/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_2_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_2_0_aar.xml b/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_2_0_aar.xml deleted file mode 100644 index 411a908..0000000 --- a/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_2_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_arch_core_core_common_2_1_0.xml b/.idea/libraries/Gradle__androidx_arch_core_core_common_2_1_0.xml deleted file mode 100644 index 2208415..0000000 --- a/.idea/libraries/Gradle__androidx_arch_core_core_common_2_1_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_0_0_aar.xml b/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_0_0_aar.xml deleted file mode 100644 index 531f9e5..0000000 --- a/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_asynclayoutinflater_asynclayoutinflater_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_asynclayoutinflater_asynclayoutinflater_1_0_0_aar.xml deleted file mode 100644 index 103dedd..0000000 --- a/.idea/libraries/Gradle__androidx_asynclayoutinflater_asynclayoutinflater_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_browser_browser_1_2_0_aar.xml b/.idea/libraries/Gradle__androidx_browser_browser_1_2_0_aar.xml deleted file mode 100644 index e4e0ecc..0000000 --- a/.idea/libraries/Gradle__androidx_browser_browser_1_2_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_cardview_cardview_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_cardview_cardview_1_0_0_aar.xml deleted file mode 100644 index c8f2bf0..0000000 --- a/.idea/libraries/Gradle__androidx_cardview_cardview_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_collection_collection_1_1_0.xml b/.idea/libraries/Gradle__androidx_collection_collection_1_1_0.xml deleted file mode 100644 index eafc05e..0000000 --- a/.idea/libraries/Gradle__androidx_collection_collection_1_1_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_2_0_4_aar.xml b/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_2_0_4_aar.xml deleted file mode 100644 index 13caa91..0000000 --- a/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_2_0_4_aar.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_solver_2_0_4.xml b/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_solver_2_0_4.xml deleted file mode 100644 index cba1dae..0000000 --- a/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_solver_2_0_4.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_coordinatorlayout_coordinatorlayout_1_1_0_aar.xml b/.idea/libraries/Gradle__androidx_coordinatorlayout_coordinatorlayout_1_1_0_aar.xml deleted file mode 100644 index 0b7ee01..0000000 --- a/.idea/libraries/Gradle__androidx_coordinatorlayout_coordinatorlayout_1_1_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_core_core_1_3_2_aar.xml b/.idea/libraries/Gradle__androidx_core_core_1_3_2_aar.xml deleted file mode 100644 index 3cb0528..0000000 --- a/.idea/libraries/Gradle__androidx_core_core_1_3_2_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_core_core_ktx_1_3_2_aar.xml b/.idea/libraries/Gradle__androidx_core_core_ktx_1_3_2_aar.xml deleted file mode 100644 index 0e54eca..0000000 --- a/.idea/libraries/Gradle__androidx_core_core_ktx_1_3_2_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml deleted file mode 100644 index fa77552..0000000 --- a/.idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_customview_customview_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_customview_customview_1_0_0_aar.xml deleted file mode 100644 index 98bffd1..0000000 --- a/.idea/libraries/Gradle__androidx_customview_customview_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_documentfile_documentfile_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_documentfile_documentfile_1_0_0_aar.xml deleted file mode 100644 index d29d619..0000000 --- a/.idea/libraries/Gradle__androidx_documentfile_documentfile_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml deleted file mode 100644 index ed2385c..0000000 --- a/.idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_fragment_fragment_1_1_0_aar.xml b/.idea/libraries/Gradle__androidx_fragment_fragment_1_1_0_aar.xml deleted file mode 100644 index 0ede30d..0000000 --- a/.idea/libraries/Gradle__androidx_fragment_fragment_1_1_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml deleted file mode 100644 index b73e160..0000000 --- a/.idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_ui_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_ui_1_0_0_aar.xml deleted file mode 100644 index 6cb30d0..0000000 --- a/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_ui_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_utils_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_utils_1_0_0_aar.xml deleted file mode 100644 index e7e10b9..0000000 --- a/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_utils_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_legacy_legacy_support_v4_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_legacy_legacy_support_v4_1_0_0_aar.xml deleted file mode 100644 index 0c17860..0000000 --- a/.idea/libraries/Gradle__androidx_legacy_legacy_support_v4_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_1_0.xml b/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_1_0.xml deleted file mode 100644 index 9354d44..0000000 --- a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_1_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml b/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml deleted file mode 100644 index 2af1588..0000000 --- a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_0_0_aar.xml b/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_0_0_aar.xml deleted file mode 100644 index 04cf5ce..0000000 --- a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_1_0_aar.xml b/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_1_0_aar.xml deleted file mode 100644 index e5d0d92..0000000 --- a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_1_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_1_0_aar.xml b/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_1_0_aar.xml deleted file mode 100644 index 0c2ccfa..0000000 --- a/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_1_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml deleted file mode 100644 index e643dc3..0000000 --- a/.idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_localbroadcastmanager_localbroadcastmanager_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_localbroadcastmanager_localbroadcastmanager_1_0_0_aar.xml deleted file mode 100644 index 48de06f..0000000 --- a/.idea/libraries/Gradle__androidx_localbroadcastmanager_localbroadcastmanager_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_media_media_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_media_media_1_0_0_aar.xml deleted file mode 100644 index d3f2420..0000000 --- a/.idea/libraries/Gradle__androidx_media_media_1_0_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_print_print_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_print_print_1_0_0_aar.xml deleted file mode 100644 index e5b9374..0000000 --- a/.idea/libraries/Gradle__androidx_print_print_1_0_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_recyclerview_recyclerview_1_1_0_aar.xml b/.idea/libraries/Gradle__androidx_recyclerview_recyclerview_1_1_0_aar.xml deleted file mode 100644 index c70370a..0000000 --- a/.idea/libraries/Gradle__androidx_recyclerview_recyclerview_1_1_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_savedstate_savedstate_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_savedstate_savedstate_1_0_0_aar.xml deleted file mode 100644 index 3454df0..0000000 --- a/.idea/libraries/Gradle__androidx_savedstate_savedstate_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_slidingpanelayout_slidingpanelayout_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_slidingpanelayout_slidingpanelayout_1_0_0_aar.xml deleted file mode 100644 index bd59e32..0000000 --- a/.idea/libraries/Gradle__androidx_slidingpanelayout_slidingpanelayout_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_swiperefreshlayout_swiperefreshlayout_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_swiperefreshlayout_swiperefreshlayout_1_0_0_aar.xml deleted file mode 100644 index 2d1b83d..0000000 --- a/.idea/libraries/Gradle__androidx_swiperefreshlayout_swiperefreshlayout_1_0_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_test_core_1_3_0_aar.xml b/.idea/libraries/Gradle__androidx_test_core_1_3_0_aar.xml deleted file mode 100644 index 26f1dee..0000000 --- a/.idea/libraries/Gradle__androidx_test_core_1_3_0_aar.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_3_0_aar.xml b/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_3_0_aar.xml deleted file mode 100644 index f17ec78..0000000 --- a/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_3_0_aar.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_3_0_aar.xml b/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_3_0_aar.xml deleted file mode 100644 index dca2ca3..0000000 --- a/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_3_0_aar.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_test_ext_junit_1_1_2_aar.xml b/.idea/libraries/Gradle__androidx_test_ext_junit_1_1_2_aar.xml deleted file mode 100644 index 0d8ead7..0000000 --- a/.idea/libraries/Gradle__androidx_test_ext_junit_1_1_2_aar.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_test_monitor_1_3_0_aar.xml b/.idea/libraries/Gradle__androidx_test_monitor_1_3_0_aar.xml deleted file mode 100644 index 12baa42..0000000 --- a/.idea/libraries/Gradle__androidx_test_monitor_1_3_0_aar.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_test_runner_1_3_0_aar.xml b/.idea/libraries/Gradle__androidx_test_runner_1_3_0_aar.xml deleted file mode 100644 index b19218b..0000000 --- a/.idea/libraries/Gradle__androidx_test_runner_1_3_0_aar.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_transition_transition_1_2_0_aar.xml b/.idea/libraries/Gradle__androidx_transition_transition_1_2_0_aar.xml deleted file mode 100644 index c8b7fb8..0000000 --- a/.idea/libraries/Gradle__androidx_transition_transition_1_2_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml b/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml deleted file mode 100644 index 796dac5..0000000 --- a/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml b/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml deleted file mode 100644 index f031056..0000000 --- a/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_0_aar.xml b/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_0_aar.xml deleted file mode 100644 index 502e120..0000000 --- a/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_viewpager2_viewpager2_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_viewpager2_viewpager2_1_0_0_aar.xml deleted file mode 100644 index 3604d3c..0000000 --- a/.idea/libraries/Gradle__androidx_viewpager2_viewpager2_1_0_0_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml b/.idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml deleted file mode 100644 index be96889..0000000 --- a/.idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__artifacts_spotify_app_remote_unspecified.xml b/.idea/libraries/Gradle__artifacts_spotify_app_remote_unspecified.xml deleted file mode 100644 index fafa794..0000000 --- a/.idea/libraries/Gradle__artifacts_spotify_app_remote_unspecified.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__artifacts_spotify_auth_unspecified.xml b/.idea/libraries/Gradle__artifacts_spotify_auth_unspecified.xml deleted file mode 100644 index 41b4a18..0000000 --- a/.idea/libraries/Gradle__artifacts_spotify_auth_unspecified.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_android_material_material_1_2_1_aar.xml b/.idea/libraries/Gradle__com_google_android_material_material_1_2_1_aar.xml deleted file mode 100644 index 22e5fa0..0000000 --- a/.idea/libraries/Gradle__com_google_android_material_material_1_2_1_aar.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1.xml b/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1.xml deleted file mode 100644 index 2b834ea..0000000 --- a/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_code_gson_gson_2_8_5.xml b/.idea/libraries/Gradle__com_google_code_gson_gson_2_8_5.xml deleted file mode 100644 index c679021..0000000 --- a/.idea/libraries/Gradle__com_google_code_gson_gson_2_8_5.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_guava_listenablefuture_1_0.xml b/.idea/libraries/Gradle__com_google_guava_listenablefuture_1_0.xml deleted file mode 100644 index 09da23b..0000000 --- a/.idea/libraries/Gradle__com_google_guava_listenablefuture_1_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1.xml b/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1.xml deleted file mode 100644 index 662b001..0000000 --- a/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__javax_inject_javax_inject_1.xml b/.idea/libraries/Gradle__javax_inject_javax_inject_1.xml deleted file mode 100644 index 62012ea..0000000 --- a/.idea/libraries/Gradle__javax_inject_javax_inject_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__junit_junit_4_12.xml b/.idea/libraries/Gradle__junit_junit_4_12.xml deleted file mode 100644 index 6c078d6..0000000 --- a/.idea/libraries/Gradle__junit_junit_4_12.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__junit_junit_4_13_1.xml b/.idea/libraries/Gradle__junit_junit_4_13_1.xml deleted file mode 100644 index 4405e64..0000000 --- a/.idea/libraries/Gradle__junit_junit_4_13_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml deleted file mode 100644 index 09cf23d..0000000 --- a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3.xml deleted file mode 100644 index 1a77dd8..0000000 --- a/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3.xml deleted file mode 100644 index 3d45e8e..0000000 --- a/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jetbrains_annotations_13_0.xml b/.idea/libraries/Gradle__org_jetbrains_annotations_13_0.xml deleted file mode 100644 index 1fa0fa9..0000000 --- a/.idea/libraries/Gradle__org_jetbrains_annotations_13_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_android_extensions_runtime_1_4_10.xml b/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_android_extensions_runtime_1_4_10.xml deleted file mode 100644 index 46ee5fd..0000000 --- a/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_android_extensions_runtime_1_4_10.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_4_10.xml b/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_4_10.xml deleted file mode 100644 index aa9fdb1..0000000 --- a/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_4_10.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_10.xml b/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_10.xml deleted file mode 100644 index 7e57d94..0000000 --- a/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_10.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index d5d35ec..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 4c3d567..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/Spotifine.iml b/.idea/modules/Spotifine.iml deleted file mode 100644 index f2a5010..0000000 --- a/.idea/modules/Spotifine.iml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/app/Spotifine.app.iml b/.idea/modules/app/Spotifine.app.iml deleted file mode 100644 index e2b0844..0000000 --- a/.idea/modules/app/Spotifine.app.iml +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/spotify-app-remote/Spotifine.spotify-app-remote.iml b/.idea/modules/spotify-app-remote/Spotifine.spotify-app-remote.iml deleted file mode 100644 index ee39fac..0000000 --- a/.idea/modules/spotify-app-remote/Spotifine.spotify-app-remote.iml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/spotify-auth/Spotifine.spotify-auth.iml b/.idea/modules/spotify-auth/Spotifine.spotify-auth.iml deleted file mode 100644 index 5f972a3..0000000 --- a/.idea/modules/spotify-auth/Spotifine.spotify-auth.iml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/spotifine.iml b/.idea/spotifine.iml deleted file mode 100644 index d6ebd48..0000000 --- a/.idea/spotifine.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 24ba95a..376a671 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,6 +2,7 @@ plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-android-extensions' + id 'kotlin-kapt' } android { @@ -10,7 +11,7 @@ android { defaultConfig { applicationId "com.archrahkshi.spotifine" - minSdkVersion 21 + minSdkVersion 26 targetSdkVersion 29 versionCode 1 versionName "1.0" @@ -33,14 +34,15 @@ android { } } -dependencies { - +repositories { + google() + jcenter() +} +dependencies { // All other dependencies for your app should also be here: implementation 'androidx.browser:browser:1.2.0' implementation "androidx.appcompat:appcompat:1.2.0" - implementation project(':spotify-auth') - implementation project(':spotify-app-remote') implementation "com.google.code.gson:gson:2.8.5" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" @@ -53,4 +55,20 @@ dependencies { testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' + + implementation 'com.github.bumptech.glide:glide:4.11.0' + kapt 'com.github.bumptech.glide:compiler:4.11.0' + + implementation project(':spotify-auth') + implementation project(':spotify-app-remote') + + def room_version = "2.2.5" + implementation "androidx.room:room-runtime:$room_version" + kapt "androidx.room:room-compiler:$room_version" + + implementation("com.squareup.okhttp3:okhttp:4.9.0") + + implementation('com.ibm.watson:ibm-watson:8.6.3') } \ No newline at end of file diff --git a/app/src/androidTest/java/com/archrahkshi/spotifine/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/archrahkshi/spotifine/ExampleInstrumentedTest.kt index 8ef9f09..928003b 100644 --- a/app/src/androidTest/java/com/archrahkshi/spotifine/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/com/archrahkshi/spotifine/ExampleInstrumentedTest.kt @@ -19,4 +19,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.archrahkshi.spotifine", appContext.packageName) } -} \ No newline at end of file +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b5fe443..ef74e16 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,21 +1,22 @@ - + android:allowBackup="false" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:roundIcon="@mipmap/ic_launcher_round" + android:supportsRtl="true" + android:theme="@style/Theme.Spotifine" + tools:ignore="AllowBackup"> - + diff --git a/app/src/main/java/com/archrahkshi/spotifine/data/Constants.kt b/app/src/main/java/com/archrahkshi/spotifine/data/Constants.kt new file mode 100644 index 0000000..84bfac9 --- /dev/null +++ b/app/src/main/java/com/archrahkshi/spotifine/data/Constants.kt @@ -0,0 +1,20 @@ +package com.archrahkshi.spotifine.data + +const val ACCESS_TOKEN = "token" +const val ALBUM_FROM_PLAYLIST_DISTINCTION = 5 +const val ALBUMS = "albums" +const val ARTIST_FROM_ME_DISTINCTION = 2 +const val ARTISTS = "artists" +const val CLIENT_ID = "fbe0ec189f0247f99909e75530bac38e" +const val DURATION = "duration" +const val FROM_ARTIST = "from_artist" +const val FROM_ME = "from_me" +const val ID = "id" +const val IMAGE = "image" +const val LIST_TYPE = "list_type" +const val NAME = "name" +const val ONE_DIGIT = 9 +const val PLAYLISTS = "playlists" +const val REDIRECT_URI = "http://localhost:8888/callback/" +const val REQUEST_CODE = 1337 +const val URL = "url" diff --git a/app/src/main/java/com/archrahkshi/spotifine/data/Entities.kt b/app/src/main/java/com/archrahkshi/spotifine/data/Entities.kt new file mode 100644 index 0000000..f7335e3 --- /dev/null +++ b/app/src/main/java/com/archrahkshi/spotifine/data/Entities.kt @@ -0,0 +1,42 @@ +package com.archrahkshi.spotifine.data + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity +data class Playlist( + @PrimaryKey(autoGenerate = true) + var id: Int = 0, + val image: String, + val name: String, + val size: Int, + val url: String, +) + +@Entity +data class Artist( + @PrimaryKey(autoGenerate = true) + var id: Int = 0, + val image: String, + val name: String, + val url: String, +) + +@Entity +data class Album( + @PrimaryKey(autoGenerate = true) + var id: Int = 0, + val image: String, + val name: String, + val artists: String, + val url: String, +) + +@Entity +data class Track( + @PrimaryKey(autoGenerate = true) + var id: String, + val name: String, + val artist: String, + val duration: Long, +) diff --git a/app/src/main/java/com/archrahkshi/spotifine/data/LibraryListsAdapter.kt b/app/src/main/java/com/archrahkshi/spotifine/data/LibraryListsAdapter.kt new file mode 100644 index 0000000..9b258fb --- /dev/null +++ b/app/src/main/java/com/archrahkshi/spotifine/data/LibraryListsAdapter.kt @@ -0,0 +1,77 @@ +package com.archrahkshi.spotifine.data + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.archrahkshi.spotifine.R +import com.bumptech.glide.Glide +import kotlinx.android.synthetic.main.item_library_list.view.imageViewListPic +import kotlinx.android.synthetic.main.item_library_list.view.layoutLibraryList +import kotlinx.android.synthetic.main.item_library_list.view.textViewListInfo +import kotlinx.android.synthetic.main.item_library_list.view.textViewListName + +class LibraryListsAdapter( + private val libraryLists: List, + private val clickListener: (ListType) -> Unit +) : RecyclerView.Adapter>() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( + LayoutInflater + .from(parent.context) + .inflate(R.layout.item_library_list, parent, false) + ) + + override fun getItemCount() = libraryLists.size + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(libraryLists[position], clickListener) + } + + class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { + private val imageViewListPic = view.imageViewListPic + private val layoutItemList = view.layoutLibraryList + private val textViewListInfo = view.textViewListInfo + private val textViewListName = view.textViewListName + private val resources = view.context.resources + private val viewTest = view + + fun bind(listType: ListType, clickListener: (ListType) -> Unit) { + textViewListName.text = when (listType) { + is Playlist -> listType.name + is Artist -> listType.name + is Album -> listType.name + else -> null + } + textViewListInfo.text = when (listType) { + is Playlist -> { + val size = listType.size + "$size ${setWordTracks(size)}" + } + is Artist -> "" + is Album -> listType.artists + else -> null + } + Glide.with(viewTest).load( + when (listType) { + is Playlist -> listType.image + is Artist -> listType.image + is Album -> listType.image + else -> null + } + ).into(imageViewListPic) + layoutItemList.setOnClickListener { clickListener(listType) } + } + + private fun setWordTracks(size: Int) = resources.getString( + with(size.toString()) { + when { + endsWith('1') -> R.string.tracks_singular + endsWith('2') || endsWith('3') || endsWith('4') -> + R.string.tracks_paucal + else -> R.string.tracks_plural + } + } + ) + } +} diff --git a/app/src/main/java/com/archrahkshi/spotifine/data/LyricsAdapter.kt b/app/src/main/java/com/archrahkshi/spotifine/data/LyricsAdapter.kt new file mode 100644 index 0000000..e4a6e1c --- /dev/null +++ b/app/src/main/java/com/archrahkshi/spotifine/data/LyricsAdapter.kt @@ -0,0 +1,33 @@ +package com.archrahkshi.spotifine.data + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.archrahkshi.spotifine.R +import kotlinx.android.synthetic.main.item_lyrics_line.view.textViewLyricsLine + +class LyricsAdapter( + private val lines: List +) : RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( + LayoutInflater + .from(parent.context) + .inflate(R.layout.item_lyrics_line, parent, false) + ) + + override fun getItemCount() = lines.size + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(lines[position]) + } + + class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { + private val textViewLyricsLine = view.textViewLyricsLine + + fun bind(line: String) { + textViewLyricsLine.text = line + } + } +} diff --git a/app/src/main/java/com/archrahkshi/spotifine/data/TracksAdapter.kt b/app/src/main/java/com/archrahkshi/spotifine/data/TracksAdapter.kt new file mode 100644 index 0000000..a63d20f --- /dev/null +++ b/app/src/main/java/com/archrahkshi/spotifine/data/TracksAdapter.kt @@ -0,0 +1,51 @@ +package com.archrahkshi.spotifine.data + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.archrahkshi.spotifine.R +import kotlinx.android.synthetic.main.item_track.view.layoutItemList +import kotlinx.android.synthetic.main.item_track.view.textViewTrackArtist +import kotlinx.android.synthetic.main.item_track.view.textViewTrackDuration +import kotlinx.android.synthetic.main.item_track.view.textViewTrackName +import kotlin.time.ExperimentalTime +import kotlin.time.milliseconds + +@ExperimentalTime +class TracksAdapter( + private val tracks: List, + private val clickListener: (Track) -> Unit +) : RecyclerView.Adapter() { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( + LayoutInflater.from(parent.context).inflate(R.layout.item_track, parent, false) + ) + + override fun getItemCount() = tracks.size + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(tracks[position], clickListener) + } + + class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { + private val textViewTrackName = view.textViewTrackName + private val textViewTrackArtist = view.textViewTrackArtist + private val textViewTrackDuration = view.textViewTrackDuration + private val layoutItemList = view.layoutItemList + + fun bind(track: Track, clickListener: (Track) -> Unit) { + textViewTrackName.text = track.name + textViewTrackArtist.text = track.artist +// textViewTrackDuration.text = SimpleDateFormat("HH:mm:ss").format(track.duration) + textViewTrackDuration.text = track.duration.milliseconds.toComponents { HH, mm, ss, _ -> + var duration = "" + if (HH > 0) duration += "$HH:" + if (duration.isNotEmpty() && mm < ONE_DIGIT) duration += '0' + duration += "$mm:" + if (duration.isNotEmpty() && ss < ONE_DIGIT) duration += '0' + "$duration$ss" + } + layoutItemList.setOnClickListener { clickListener(track) } + } + } +} diff --git a/app/src/main/java/com/archrahkshi/spotifine/ui/LibraryActivity.kt b/app/src/main/java/com/archrahkshi/spotifine/ui/LibraryActivity.kt new file mode 100644 index 0000000..802b880 --- /dev/null +++ b/app/src/main/java/com/archrahkshi/spotifine/ui/LibraryActivity.kt @@ -0,0 +1,47 @@ +package com.archrahkshi.spotifine.ui + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.archrahkshi.spotifine.R +import com.archrahkshi.spotifine.data.ACCESS_TOKEN +import com.archrahkshi.spotifine.data.ALBUMS +import com.archrahkshi.spotifine.data.ARTISTS +import com.archrahkshi.spotifine.data.LIST_TYPE +import com.archrahkshi.spotifine.data.PLAYLISTS +import kotlinx.android.synthetic.main.activity_library.buttonAlbums +import kotlinx.android.synthetic.main.activity_library.buttonArtists +import kotlinx.android.synthetic.main.activity_library.buttonPlaylists + +class LibraryActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_library) + + replaceFragmentWith(PLAYLISTS) + + buttonPlaylists.setOnClickListener { + replaceFragmentWith(PLAYLISTS) + } + + buttonArtists.setOnClickListener { + replaceFragmentWith(ARTISTS) + } + + buttonAlbums.setOnClickListener { + replaceFragmentWith(ALBUMS) + } + } + + private fun replaceFragmentWith(listType: String) { + supportFragmentManager.beginTransaction().replace( + R.id.frameLayoutLibrary, + LibraryListsFragment().apply { + arguments = Bundle().apply { + putString(LIST_TYPE, listType) + putString(ACCESS_TOKEN, intent.getStringExtra(ACCESS_TOKEN)) + } + } + ).commit() + } +} diff --git a/app/src/main/java/com/archrahkshi/spotifine/ui/LibraryListsFragment.kt b/app/src/main/java/com/archrahkshi/spotifine/ui/LibraryListsFragment.kt new file mode 100644 index 0000000..d7c9d19 --- /dev/null +++ b/app/src/main/java/com/archrahkshi/spotifine/ui/LibraryListsFragment.kt @@ -0,0 +1,193 @@ +package com.archrahkshi.spotifine.ui + +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.archrahkshi.spotifine.R +import com.archrahkshi.spotifine.data.ACCESS_TOKEN +import com.archrahkshi.spotifine.data.ALBUMS +import com.archrahkshi.spotifine.data.ARTISTS +import com.archrahkshi.spotifine.data.ARTIST_FROM_ME_DISTINCTION +import com.archrahkshi.spotifine.data.Album +import com.archrahkshi.spotifine.data.Artist +import com.archrahkshi.spotifine.data.FROM_ARTIST +import com.archrahkshi.spotifine.data.FROM_ME +import com.archrahkshi.spotifine.data.IMAGE +import com.archrahkshi.spotifine.data.LIST_TYPE +import com.archrahkshi.spotifine.data.LibraryListsAdapter +import com.archrahkshi.spotifine.data.NAME +import com.archrahkshi.spotifine.data.PLAYLISTS +import com.archrahkshi.spotifine.data.Playlist +import com.archrahkshi.spotifine.data.URL +import com.google.gson.JsonObject +import com.google.gson.JsonParser +import kotlinx.android.synthetic.main.fragment_library_lists.recyclerViewLists +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.Request +import java.io.IOException +import kotlin.coroutines.CoroutineContext + +class LibraryListsFragment( + override val coroutineContext: CoroutineContext = Dispatchers.Main.immediate +) : Fragment(), CoroutineScope { + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? = inflater.inflate(R.layout.fragment_library_lists, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val accessToken = arguments?.getString(ACCESS_TOKEN) + + launch { + recyclerViewLists.adapter = LibraryListsAdapter( + createLibraryLists(accessToken)!! + ) { + Log.i("Item clicked", it.toString()) + fragmentManager?.beginTransaction()?.replace( + R.id.frameLayoutLibrary, + when (it) { + is Playlist -> TracksFragment().apply { + arguments = Bundle().apply { + putString(URL, it.url) + putString(IMAGE, it.image) + putString(NAME, it.name) + putString(ACCESS_TOKEN, accessToken) + } + } + is Artist -> LibraryListsFragment().apply { + arguments = Bundle().apply { + putString(LIST_TYPE, ALBUMS) + putString(URL, it.url) + putString(IMAGE, it.image) + putString(ACCESS_TOKEN, accessToken) + } + } + is Album -> TracksFragment().apply { + arguments = Bundle().apply { + putString(URL, it.url) + putString(IMAGE, it.image) + putString(NAME, it.name) + putString(ACCESS_TOKEN, accessToken) + } + } + else -> null + }!! + )?.addToBackStack(null)?.commit() + } + } + } + + private suspend fun createLibraryLists( + accessToken: String? + ) = withContext(Dispatchers.IO) { + when (arguments?.getString(LIST_TYPE)) { + PLAYLISTS -> { + val libraryLists = mutableListOf() + getJsonFromApi( + "me/playlists", + accessToken + )["items"].asJsonArray.forEach { + libraryLists.add(createPlaylist(it.asJsonObject)) + } + libraryLists + } + ARTISTS -> { + val libraryLists = mutableListOf() + getJsonFromApi( + "me/following?type=artist", + accessToken + )["artists"].asJsonObject["items"].asJsonArray.forEach { + libraryLists.add(createArtist(it.asJsonObject)) + } + libraryLists + } + ALBUMS -> { + val libraryLists = mutableListOf() + val json = getJsonFromApi( + "${arguments?.getString(URL) ?: "me"}/albums", + accessToken + ) + val items = json["items"].asJsonArray + when ( + json["href"] + .asString + .removePrefix("https://api.spotify.com/v1/") + .take(ARTIST_FROM_ME_DISTINCTION) + ) { + "ar" -> { + items.forEach { + libraryLists.add(createAlbum(it.asJsonObject, FROM_ARTIST)) + } + libraryLists + } + "me" -> { + items.forEach { + libraryLists.add( + createAlbum(it.asJsonObject["album"].asJsonObject, FROM_ME) + ) + } + libraryLists + } + else -> libraryLists + } + } + else -> null + } + } + + private fun createPlaylist(item: JsonObject): Playlist { + val tracks = item["tracks"].asJsonObject + return Playlist( + image = item["images"].asJsonArray.first().asJsonObject["url"].asString, + name = item["name"].asString, + size = tracks["total"].asInt, + url = tracks["href"].asString + ) + } + + private fun createArtist(item: JsonObject) = Artist( + image = item["images"].asJsonArray[1].asJsonObject["url"].asString, + name = item["name"].asString, + url = "artists/${item["id"].asString}" + ) + + private fun createAlbum(item: JsonObject, type: String) = Album( + image = item["images"].asJsonArray[1].asJsonObject["url"].asString, + name = item["name"].asString, + artists = item["artists"].asJsonArray + .joinToString { it.asJsonObject["name"].asString }, + url = if (type == FROM_ARTIST) + "${item["href"].asString}/tracks" + else + item["tracks"].asJsonObject["href"].asString + ) + + private fun getJsonFromApi(requestPostfix: String, accessToken: String?) = JsonParser().parse( + try { + OkHttpClient().newCall( + Request.Builder() + .url("https://api.spotify.com/v1/$requestPostfix") + .header("Authorization", "Bearer $accessToken") + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .build() + ).execute().body?.string().also { + Log.i("JSON string", it ?: "no JSON string") + } + } catch (e: IOException) { + Log.wtf("getJsonFromApi", e) + null + } + ).asJsonObject +} diff --git a/app/src/main/java/com/archrahkshi/spotifine/ui/LyricsFragment.kt b/app/src/main/java/com/archrahkshi/spotifine/ui/LyricsFragment.kt index 9c423fa..a2b6681 100644 --- a/app/src/main/java/com/archrahkshi/spotifine/ui/LyricsFragment.kt +++ b/app/src/main/java/com/archrahkshi/spotifine/ui/LyricsFragment.kt @@ -6,21 +6,52 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import com.archrahkshi.spotifine.R -import kotlinx.android.synthetic.main.fragment_lyrics.* - +import com.archrahkshi.spotifine.data.LyricsAdapter +import kotlinx.android.synthetic.main.fragment_lyrics.buttonTranslate +import kotlinx.android.synthetic.main.fragment_lyrics.recyclerViewLyrics class LyricsFragment(private var isLyricsTranslated: Boolean) : Fragment() { override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View? = inflater.inflate(R.layout.fragment_lyrics, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val toRussian = "... > РУССКИЙ" - buttonTranslate.text = if (isLyricsTranslated) toRussian else R.string.translate.toString() + val lyricsOriginal = listOf( + "Hoort u mij toe", + "Als ik u verhaal", + "Van oude sagen", + "Van reuzentijd", + "", + "Vertel ons de sagen", + "Van oeroude machten", + "In 't Gelderse land", + "Wat weet u nog meer?", + ) + val lyricsTranslated = listOf( + "Послушай меня", + "Если я скажу тебе", + "Из старых саг", + "Из гигантских времен", + "", + "Расскажи нам саги", + "Древних сил", + "В стране Гелдерланд", + "Что еще ты знаешь?", + ) + val lyrics = if (isLyricsTranslated) lyricsTranslated else lyricsOriginal + + val detectedLanguage = "..." // TODO + val toRussian = "$detectedLanguage > ${resources.getString(R.string.russian)}" + buttonTranslate.text = + if (isLyricsTranslated) + toRussian + else + resources.getString(R.string.translate) buttonTranslate.setOnClickListener { isLyricsTranslated = !isLyricsTranslated @@ -29,5 +60,7 @@ class LyricsFragment(private var isLyricsTranslated: Boolean) : Fragment() { LyricsFragment(isLyricsTranslated) )?.commit() } + + recyclerViewLyrics.adapter = LyricsAdapter(lyrics) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/archrahkshi/spotifine/ui/MainActivity.kt b/app/src/main/java/com/archrahkshi/spotifine/ui/MainActivity.kt index fb8be31..30edcfc 100644 --- a/app/src/main/java/com/archrahkshi/spotifine/ui/MainActivity.kt +++ b/app/src/main/java/com/archrahkshi/spotifine/ui/MainActivity.kt @@ -5,104 +5,62 @@ import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import com.archrahkshi.spotifine.R -import com.spotify.android.appremote.api.SpotifyAppRemote +import com.archrahkshi.spotifine.data.ACCESS_TOKEN +import com.archrahkshi.spotifine.data.CLIENT_ID +import com.archrahkshi.spotifine.data.REDIRECT_URI +import com.archrahkshi.spotifine.data.REQUEST_CODE import com.spotify.sdk.android.auth.AuthorizationClient import com.spotify.sdk.android.auth.AuthorizationRequest import com.spotify.sdk.android.auth.AuthorizationResponse -import kotlinx.android.synthetic.main.activity_main.* - class MainActivity : AppCompatActivity() { - private val CLIENT_ID = "fbe0ec189f0247f99909e75530bac38e" - private val REDIRECT_URI = "http://localhost:8888/callback/" - private val REQUEST_CODE = 1337 - private var mSpotifyAppRemote: SpotifyAppRemote? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - // TODO: Login Activity - buttonProceed.setOnClickListener { - - // Set the connection parameters - /* val connectionParams = ConnectionParams.Builder(CLIENT_ID) - .setRedirectUri(REDIRECT_URI) - .showAuthView(true) - .build() - SpotifyAppRemote.connect(this, connectionParams, - object : Connector.ConnectionListener { - override fun onConnected(spotifyAppRemote: SpotifyAppRemote) { - mSpotifyAppRemote = spotifyAppRemote - Log.d("MainActivity", "Connected! Yay!") - - // Now you can start interacting with App Remote - - connected() - } - - override fun onFailure(throwable: Throwable) { - Log.e("MainActivity", throwable.message, throwable) + AuthorizationClient.openLoginActivity( + this, + REQUEST_CODE, + AuthorizationRequest.Builder( + CLIENT_ID, + AuthorizationResponse.Type.TOKEN, + REDIRECT_URI + ).apply { + setScopes(arrayOf("streaming", "user-library-read", "user-follow-read")) + }.build() + ) + } - // Something went wrong when attempting to connect! Handle errors here + override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { + super.onActivityResult(requestCode, resultCode, intent) + + if (requestCode == REQUEST_CODE) { + val response: AuthorizationResponse? = + AuthorizationClient.getResponse(resultCode, intent) + when (response?.type) { + AuthorizationResponse.Type.TOKEN -> { + Log.i("Token", "OK") + startActivity( + Intent(this, LibraryActivity::class.java).apply { + putExtra( + ACCESS_TOKEN, + response.accessToken.also { + Log.i("Access token", it) + } + ) } - })*/ - - - val builder = AuthorizationRequest.Builder(CLIENT_ID, AuthorizationResponse.Type.TOKEN, REDIRECT_URI) - - builder.setScopes(arrayOf("streaming")) - val request:AuthorizationRequest = builder.build() - - AuthorizationClient.openLoginActivity(this, REQUEST_CODE, request) - - - - - + ) + finish() + } + AuthorizationResponse.Type.ERROR -> Log.wtf("Token", response.error) + else -> Log.wtf("Token", "bullshit") + } } } - - /* private fun connected() { - // Play a playlist - mSpotifyAppRemote!!.playerApi.play("spotify:playlist:37i9dQZF1DX2sUQwD7tbmL") - // information about track - mSpotifyAppRemote!!.playerApi - .subscribeToPlayerState() - .setEventCallback { playerState: PlayerState -> - val track: Track? = playerState.track - if (track != null) { - Log.d("MainActivity", track.name.toString() + " by " + track.artist.name) - } - } - - - }*/ - override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { - super.onActivityResult(requestCode, resultCode, intent) - - // Check if result comes from the correct activity - if (requestCode == REQUEST_CODE) { - val response: AuthorizationResponse? = AuthorizationClient.getResponse(resultCode, intent) - Log.d("aaaaaaaaaaaaaaaa", response?.accessToken.toString()) - when (response?.type) { - AuthorizationResponse.Type.TOKEN -> { - Log.d("aaaaa2222222", response.state?: "null") - startActivity(Intent(this, MusicLibraryActivity::class.java)) - } - AuthorizationResponse.Type.ERROR -> { - Log.d("aaaaa2222222", response.error?: "nullError") - } - else -> { - Log.d("aaaaaelse", response?.state?: "nullElse") - } - } - } - } - override fun onStop() { super.onStop() AuthorizationClient.clearCookies(this) - //SpotifyAppRemote.disconnect(mSpotifyAppRemote) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/archrahkshi/spotifine/ui/MusicLibraryActivity.kt b/app/src/main/java/com/archrahkshi/spotifine/ui/MusicLibraryActivity.kt deleted file mode 100644 index e0308ed..0000000 --- a/app/src/main/java/com/archrahkshi/spotifine/ui/MusicLibraryActivity.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.archrahkshi.spotifine.ui - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.archrahkshi.spotifine.R -import kotlinx.android.synthetic.main.activity_music_library.* - - -enum class ListTypes {PLAYLISTS, ARTISTS, ALBUMS} - -class MusicLibraryActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_music_library) - - supportFragmentManager.beginTransaction().replace( - R.id.frameLayoutLibrary, - PlaylistsFragment(ListTypes.PLAYLISTS) - ).commit() - - buttonPlaylists.setOnClickListener { - supportFragmentManager.beginTransaction().replace( - R.id.frameLayoutLibrary, - PlaylistsFragment(ListTypes.PLAYLISTS) - ) - } - - buttonArtists.setOnClickListener { - supportFragmentManager.beginTransaction().replace( - R.id.frameLayoutLibrary, - PlaylistsFragment(ListTypes.ARTISTS) - ) - } - - buttonAlbums.setOnClickListener { - supportFragmentManager.beginTransaction().replace( - R.id.frameLayoutLibrary, - PlaylistsFragment(ListTypes.ALBUMS) - ) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/archrahkshi/spotifine/ui/PlayerActivity.kt b/app/src/main/java/com/archrahkshi/spotifine/ui/PlayerActivity.kt index c862d46..3673f3e 100644 --- a/app/src/main/java/com/archrahkshi/spotifine/ui/PlayerActivity.kt +++ b/app/src/main/java/com/archrahkshi/spotifine/ui/PlayerActivity.kt @@ -1,10 +1,24 @@ package com.archrahkshi.spotifine.ui +import android.annotation.SuppressLint import android.os.Bundle +import android.util.Log +import android.widget.SeekBar +import android.widget.SeekBar.OnSeekBarChangeListener import androidx.appcompat.app.AppCompatActivity import com.archrahkshi.spotifine.R +import com.archrahkshi.spotifine.data.CLIENT_ID +import com.archrahkshi.spotifine.data.DURATION +import com.archrahkshi.spotifine.data.ID +import com.archrahkshi.spotifine.data.REDIRECT_URI +import com.spotify.android.appremote.api.ConnectionParams +import com.spotify.android.appremote.api.Connector +import com.spotify.android.appremote.api.SpotifyAppRemote +import kotlinx.android.synthetic.main.activity_player.* class PlayerActivity : AppCompatActivity() { + private var pSpotifyAppRemote: SpotifyAppRemote? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_player) @@ -14,4 +28,86 @@ class PlayerActivity : AppCompatActivity() { LyricsFragment(false) ).commit() } -} \ No newline at end of file + + override fun onStart() { + super.onStart() + val id = intent.getStringExtra(ID) + val duration = intent.getLongExtra(DURATION, 0) + Log.wtf("id", id?.toString()) + Log.wtf("duration", duration.toString()) + val connectionParams = ConnectionParams.Builder(CLIENT_ID) + .setRedirectUri(REDIRECT_URI) + .showAuthView(true) + .build() + SpotifyAppRemote.connect( + this, + connectionParams, + object : Connector.ConnectionListener { + @SuppressLint("SetTextI18n") + override fun onConnected(spotifyAppRemote: SpotifyAppRemote) { + this@PlayerActivity.pSpotifyAppRemote = spotifyAppRemote + val appRemote = this@PlayerActivity.pSpotifyAppRemote!! + Log.d("MainActivity", "Connected! Yay!") + + val seekBar = findViewById(R.id.seekBar) + seekBar.max = duration.toInt() + var flag = 0 + buttonPlay.text = "PLAY" + seekBar.setOnSeekBarChangeListener( + object : OnSeekBarChangeListener { + override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) { + if (flag == 0) { + seekBar.progress = 0 + } else { + appRemote.playerApi.seekTo(seekBar.progress.toLong()) + } + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + if (flag == 1) { + appRemote.playerApi.pause() + } + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + if (flag == 1) { + appRemote.playerApi.resume() + } + } + } + ) + buttonPlay.setOnClickListener { + when (flag) { + 0 -> { + appRemote.playerApi.play("spotify:track:$id") + flag = 1 + buttonPlay.text = "PAUSE" + } + 1 -> { + appRemote.playerApi.pause() + flag = 2 + buttonPlay.text = "PLAY" + } + 2 -> { + appRemote.playerApi.resume() + flag = 1 + buttonPlay.text = "PAUSE" + } + } + } + } + + override fun onFailure(throwable: Throwable) { + Log.e("MyActivity", throwable.message, throwable) + + // Something went wrong when attempting to connect! Handle errors here + } + } + ) + } + + override fun onStop() { + super.onStop() + SpotifyAppRemote.disconnect(pSpotifyAppRemote) + } +} diff --git a/app/src/main/java/com/archrahkshi/spotifine/ui/PlaylistFragment.kt b/app/src/main/java/com/archrahkshi/spotifine/ui/PlaylistFragment.kt deleted file mode 100644 index 69bda8c..0000000 --- a/app/src/main/java/com/archrahkshi/spotifine/ui/PlaylistFragment.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.archrahkshi.spotifine.ui - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.Fragment -import com.archrahkshi.spotifine.R - - -class PlaylistFragment : Fragment() { - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? = inflater.inflate(R.layout.fragment_playlist, container, false) - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - // TODO - } -} \ No newline at end of file diff --git a/app/src/main/java/com/archrahkshi/spotifine/ui/PlaylistsFragment.kt b/app/src/main/java/com/archrahkshi/spotifine/ui/PlaylistsFragment.kt deleted file mode 100644 index dff8805..0000000 --- a/app/src/main/java/com/archrahkshi/spotifine/ui/PlaylistsFragment.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.archrahkshi.spotifine.ui - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.Fragment -import com.archrahkshi.spotifine.R - - -class PlaylistsFragment(private val listType: ListTypes) : Fragment() { - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? = inflater.inflate(R.layout.fragment_playlists, container, false) - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - // TODO - } -} \ No newline at end of file diff --git a/app/src/main/java/com/archrahkshi/spotifine/ui/TracksFragment.kt b/app/src/main/java/com/archrahkshi/spotifine/ui/TracksFragment.kt new file mode 100644 index 0000000..2db5661 --- /dev/null +++ b/app/src/main/java/com/archrahkshi/spotifine/ui/TracksFragment.kt @@ -0,0 +1,134 @@ +package com.archrahkshi.spotifine.ui + +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.archrahkshi.spotifine.R +import com.archrahkshi.spotifine.data.ACCESS_TOKEN +import com.archrahkshi.spotifine.data.ALBUM_FROM_PLAYLIST_DISTINCTION +import com.archrahkshi.spotifine.data.DURATION +import com.archrahkshi.spotifine.data.ID +import com.archrahkshi.spotifine.data.IMAGE +import com.archrahkshi.spotifine.data.NAME +import com.archrahkshi.spotifine.data.Track +import com.archrahkshi.spotifine.data.TracksAdapter +import com.archrahkshi.spotifine.data.URL +import com.bumptech.glide.Glide +import com.google.gson.JsonParser +import kotlinx.android.synthetic.main.fragment_tracks.imageViewHeader +import kotlinx.android.synthetic.main.fragment_tracks.recyclerViewTracks +import kotlinx.android.synthetic.main.fragment_tracks.textViewHeaderLine1 +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.Request +import java.io.IOException +import kotlin.coroutines.CoroutineContext +import kotlin.time.ExperimentalTime + +class TracksFragment( + override val coroutineContext: CoroutineContext = Dispatchers.Main.immediate +) : Fragment(), CoroutineScope { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? = inflater.inflate(R.layout.fragment_tracks, container, false) + + @ExperimentalTime + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val args = this.arguments + textViewHeaderLine1.text = args?.getString(NAME) + + Glide + .with(this) + .load(args?.getString(IMAGE)) + .into(imageViewHeader) + + launch { + recyclerViewTracks.adapter = TracksAdapter( + createTrackLists(args?.getString(URL), args?.getString(ACCESS_TOKEN)) + ) { + Log.i("Track", it.toString()) + startActivity( + Intent(activity, PlayerActivity::class.java).apply { + putExtra(ID, it.id) + putExtra(DURATION, it.duration) + } + ) + } + } + } + + private fun getJsonFromApi(url: String?, accessToken: String?) = JsonParser().parse( + try { + OkHttpClient().newCall( + Request.Builder() + .url(url!!) + .header("Authorization", "Bearer $accessToken") + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .build() + ).execute().body?.string().also { + Log.i("JSON string", it ?: "no JSON string") + } + } catch (e: IOException) { + Log.wtf("getJsonFromApi", e) + null + } + ).asJsonObject + + private suspend fun createTrackLists( + url: String?, + accessToken: String? + ) = withContext(Dispatchers.IO) { + val tracks = mutableListOf() + val json = getJsonFromApi(url, accessToken) + when ( + json["href"] + .asString + .removePrefix("https://api.spotify.com/v1/") + .take(ALBUM_FROM_PLAYLIST_DISTINCTION) + ) { + "album" -> { + json["items"].asJsonArray.forEach { element -> + val item = element.asJsonObject + tracks.add( + Track( + name = item["name"].asString, + artist = item["artists"].asJsonArray + .joinToString { it.asJsonObject["name"].asString }, + duration = item["duration_ms"].asLong, + id = item["id"].asString + ) + ) + } + tracks + } + "playl" -> { + json["items"].asJsonArray.forEach { element -> + val item = element.asJsonObject["track"].asJsonObject + tracks.add( + Track( + name = item["name"].asString, + artist = item["artists"].asJsonArray + .joinToString { it.asJsonObject["name"].asString }, + duration = item["duration_ms"].asLong, + id = item["id"].asString + ) + ) + } + tracks + } + else -> tracks + } + } +} diff --git a/app/src/main/res/layout/activity_library.xml b/app/src/main/res/layout/activity_library.xml new file mode 100644 index 0000000..103c1e3 --- /dev/null +++ b/app/src/main/res/layout/activity_library.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 0fe989b..11eefe4 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,14 +1,17 @@ - + -