commit 058e46bae8a5a041771c8e9a665156aa56147b67
Author: raoqian <506411586@qq.com>
Date: Wed Sep 17 18:35:26 2025 +0800
初次代码上传
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
new file mode 100644
index 0000000..da6ad36
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,109 @@
+import java.text.SimpleDateFormat
+import java.util.Date
+
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+// id("com.google.gms.google-services")
+// id("com.google.firebase.firebase-perf")
+}
+
+android {
+ namespace = "com.jia.er.nebuluxe.app"
+ compileSdk = 35
+
+ defaultConfig {
+ applicationId = "com.jia.er.nebuluxe.app"
+ minSdk = 24
+ targetSdk = 35
+ versionCode = 1
+ versionName = "1.0.0"
+ }
+
+ buildTypes {
+ debug {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+// signingConfig = signingConfigs.getByName("debug")
+ }
+ release {
+ isMinifyEnabled = true
+ isShrinkResources = true
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+ buildFeatures {
+ buildConfig = true
+ viewBinding = true
+ }
+ android.applicationVariants.all {
+ val buildType = this.buildType.name
+ val date = SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(Date())
+ outputs.all {
+ if (this is com.android.build.gradle
+ .internal.api.ApkVariantOutputImpl
+ ) {
+ this.outputFileName = "Nebuluxe" +
+ "_${android.defaultConfig.versionName}_${android.defaultConfig.versionCode}_${date}_${buildType}.apk"
+ }
+ }
+ }
+
+}
+
+dependencies {
+ implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.androidx.lifecycle.viewmodel.ktx)
+ implementation(libs.material)
+ implementation(libs.com.github.wuao.flycotablayout2)
+ implementation(libs.io.github.youth5201314.banner)
+ implementation(libs.io.github.cymchad.baserecyclerviewadapterhelper4)
+ implementation(libs.com.github.bumptech.glide.glide2)
+ implementation(libs.org.greenrobot.eventbus3)
+ implementation(libs.androidx.media3.media3.exoplayer2)
+ implementation(libs.androidx.media3.media3.exoplayer.dash2)
+ implementation(libs.androidx.media3.media3.ui2)
+ implementation(libs.androidx.media3.media3.exoplayer.hls2)
+ implementation(libs.androidx.media3.media3.exoplayer.rtsp2)
+ implementation(libs.squareup.okhttp)
+ implementation(libs.squareup.logging.interceptor)
+ implementation(libs.squareup.retrofit)
+ implementation(libs.squareup.converter.gson)
+ implementation(libs.com.tencent.mmkv)
+ implementation(libs.androidx.lifecycle.lifecycle.livedata.ktx3)
+ implementation(libs.androidx.lifecycle.lifecycle.extensions4)
+ implementation(libs.scwang90.refresh.layout.kernel)
+ implementation(libs.scwang90.refresh.header.material)
+ implementation(libs.scwang90.refresh.footer.classics)
+ implementation(libs.com.getkeepsafe.relinker.relinker)
+ implementation(libs.utilcodex)
+ implementation(libs.shapeblurview)
+ implementation(libs.com.google.android.flexbox.flexbox)
+ implementation(libs.play.services.ads.identifier)
+ implementation("com.github.getActivity:ShapeView:9.8")
+// implementation(libs.android.billing)
+// implementation(platform(libs.google.firebase.bom))
+// implementation(libs.google.firebase.messaging.ktx)
+// implementation(libs.google.firebase.analytics.ktx)
+// implementation(libs.firebase.perf)
+// implementation(libs.adjust.android)
+// implementation(libs.adjust.android.webbridge)
+// implementation(libs.com.android.installreferrer.installreferrer)
+// implementation("com.facebook.android:facebook-android-sdk:17.0.2")
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..7ebc1bb
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseActivity.kt
new file mode 100644
index 0000000..aad71ec
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseActivity.kt
@@ -0,0 +1,141 @@
+package com.jia.er.nebuluxe.app.basics
+
+import android.app.Dialog
+import android.content.Context
+import android.content.pm.ActivityInfo
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.os.Build
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.view.inputmethod.InputMethodManager
+import android.widget.EditText
+import android.widget.FrameLayout
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.core.content.ContextCompat
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+import androidx.viewbinding.ViewBinding
+import com.blankj.utilcode.util.BarUtils
+import com.jia.er.nebuluxe.app.R
+
+abstract class BaseActivity : AppCompatActivity() {
+ lateinit var binding: BV
+ private var networkErrorView: View? = null
+ private var noDramaView: View? = null
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = getViewBinding()
+ val container = FrameLayout(this).apply {
+ layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ addView(
+ binding.root,
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ }
+ setContentView(container)
+ networkErrorView =
+ layoutInflater.inflate(R.layout.layout_network_error, container, false).apply {
+ layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ visibility = View.INVISIBLE
+ findViewById(R.id.tv_example_retry)?.setOnClickListener {
+ onRetry()
+ }
+ }
+ container.addView(networkErrorView)
+ noDramaView =
+ layoutInflater.inflate(R.layout.layout_no_drama, container, false).apply {
+ layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ visibility = View.INVISIBLE
+ findViewById(R.id.tv_example_retry)?.setOnClickListener {
+ onReturn()
+ }
+ }
+ container.addView(noDramaView)
+ BarUtils.transparentStatusBar(this)
+ BarUtils.setStatusBarLightMode(this, false)
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+ top()
+ center()
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
+ ViewCompat.setOnApplyWindowInsetsListener(container) { v, insets ->
+ val systemInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
+ v.setPadding(0, 0, 0, systemInsets.bottom)
+ window.navigationBarColor = ContextCompat.getColor(this, R.color.black)
+ insets
+ }
+ }
+ }
+
+ protected abstract fun top()
+ protected abstract fun center()
+ protected abstract fun getViewBinding(): BV
+
+ protected open fun onRetry() {
+ }
+
+ protected open fun onReturn() {
+ }
+
+ fun showNetError() {
+ networkErrorView?.visibility = View.VISIBLE
+ }
+
+ fun hideNetError() {
+ networkErrorView?.visibility = View.INVISIBLE
+ }
+
+ fun showNoDrama(){
+ noDramaView?.visibility = View.VISIBLE
+ }
+
+ private var loadingDialog: Dialog? = null
+
+ protected open fun showLoading(
+ message: String = "Loading..."
+ ) {
+ if (loadingDialog?.isShowing == true) return
+
+ loadingDialog = Dialog(this, R.style.FullScreenLoadingDialog).apply {
+ setContentView(R.layout.dialog_loading)
+ window?.apply {
+ setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
+ setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ decorView.setBackgroundColor(Color.argb(150, 0, 0, 0))
+ }
+ setCancelable(true)
+ findViewById(R.id.tv_loading_text)?.text = message
+ }
+ loadingDialog?.show()
+ }
+
+ protected open fun hideLoading() {
+ loadingDialog?.takeIf { it.isShowing }?.dismiss()
+ loadingDialog = null
+ }
+
+ fun showKeyBord(mEditText: EditText, mContext: Context) {
+ val imm = mContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.showSoftInput(mEditText, InputMethodManager.RESULT_SHOWN)
+ imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
+ }
+
+ fun hideKeyBord(mEditText: EditText, mContext: Context) {
+ val imm = mContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(mEditText.windowToken, 0)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseFragment.kt b/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseFragment.kt
new file mode 100644
index 0000000..c687b90
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseFragment.kt
@@ -0,0 +1,99 @@
+package com.jia.er.nebuluxe.app.basics
+
+import android.app.Dialog
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.TextView
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.fragment.app.Fragment
+import androidx.viewbinding.ViewBinding
+import com.jia.er.nebuluxe.app.R
+
+abstract class BaseFragment : Fragment() {
+ lateinit var binding: VB
+ var networkErrorView: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = getViewBinding()
+ val layout = FrameLayout(requireContext()).apply {
+ layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ addView(
+ binding.root,
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ }
+ networkErrorView =
+ layoutInflater.inflate(R.layout.layout_network_error, layout, false).apply {
+ layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ visibility = View.INVISIBLE
+ findViewById(R.id.tv_example_retry)?.setOnClickListener {
+ onRetry()
+ }
+ }
+ layout.addView(networkErrorView)
+ return layout
+ }
+
+ protected open fun onRetry() {
+ }
+
+ fun showNetError() {
+ networkErrorView?.visibility = View.VISIBLE
+ }
+
+ fun hideNetError() {
+ networkErrorView?.visibility = View.INVISIBLE
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ top()
+ center()
+ }
+
+ protected abstract fun top()
+ protected abstract fun center()
+ protected abstract fun getViewBinding(): VB
+
+ private var loadingDialog: Dialog? = null
+
+ protected open fun showLoading(
+ message: String = "Loading..."
+ ) {
+ if (loadingDialog?.isShowing == true) return
+
+ loadingDialog = Dialog(requireContext(), R.style.FullScreenLoadingDialog).apply {
+ setContentView(R.layout.dialog_loading)
+ window?.apply {
+ setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
+ setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ decorView.setBackgroundColor(Color.argb(150, 0, 0, 0))
+ }
+ setCancelable(true)
+
+ findViewById(R.id.tv_loading_text)?.text = message
+ }
+ loadingDialog?.show()
+ }
+
+ protected open fun hideLoading() {
+ loadingDialog?.takeIf { it.isShowing }?.dismiss()
+ loadingDialog = null
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/basics/Constants.kt b/app/src/main/java/com/jia/er/nebuluxe/app/basics/Constants.kt
new file mode 100644
index 0000000..1e1425b
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/basics/Constants.kt
@@ -0,0 +1,60 @@
+package com.jia.er.nebuluxe.app.basics
+
+
+object Constants {
+ var isUat = false
+ const val Constants_BASE_URL_RES = "https://api-nebuluxetv.nebuluxetv.com/xe/"
+ const val CONSTANTS_AuthorizationExample = "Authorization"
+ const val CONSTANTS_device_id = "device-id"
+ const val CONSTANTS_device_gaid = "device-gaid"
+ const val CONSTANTS_app_name = "app-name"
+ const val CONSTANTS_app_version = "app-version"
+ const val CONSTANTS_system_type = "system-type"
+ const val CONSTANTS_lang_key = "lang-key"
+ const val CONSTANTS_time_zone = "time-zone"
+ const val CONSTANTS_model = "model"
+ const val CONSTANTS_brand = "brand"
+ const val CONSTANTS_edit = "CONSTANTS_edit"
+ const val CONSTANTS_system_version = "system-version"
+ const val CONSTANTS_auth_refresh = "CONSTANTS_auth_refresh"
+ const val CONSTANTS_User_STRING = "CONSTANTS_User_STRING"
+ const val CONSTANTS_SEARCH_STRINGExample = "searchString"
+ const val CONSTANTS_main_stop = "CONSTANTS_main_stop"
+ const val CONSTANTS_short_play_id = "CONSTANTS_short_play_id"
+ const val Constants_Episodes_Series_Data_currentPositionExample =
+ "Constants_Episodes_Series_Data_currentPositionExample"
+ const val Constants_Episodes_Series_Data_ListExample =
+ "Constants_Episodes_Series_Data_ListExample"
+ const val Constants_Episodes_Series_DataExample = "Constants_Episodes_Series_DataExample"
+ const val CONSTANTS_activity_id = "activity_id"
+ const val CONSTANTS_refresh_me = "CONSTANTS_refresh_me"
+ const val Constants_DDL_Url = "Constants_DDL_Url"
+ const val CONSTANTS_leaveApp = "CONSTANTS_leaveApp"
+ const val CONSTANTS_enterTheApp = "CONSTANTS_enterTheApp"
+ const val CONSTANTS_onLine = "CONSTANTS_onLine"
+ const val CONSTANTS_examplePayReq = "CONSTANTS_examplePayReq"
+ const val CONSTANTS_Episode = "CONSTANTS_Episode"
+ const val CONSTANTS_pay_refresh = "CONSTANTS_pay_refresh"
+ const val CONSTANTS_collect_refresh = "CONSTANTS_collect_refresh"
+ const val Constants_onTokenRefresh = "onTokenRefresh"
+ const val Constants_getClip = "Constants_getClip"
+ const val CONSTANTS_web_Login = "CONSTANTS_web_Login"
+ const val CONSTANTS_PREF_LAST_POPUP_TIME_Notification =
+ "CONSTANTS_PREF_LAST_POPUP_TIME_Notification"
+ const val ONE_DAY_IN_MILLIS = 24 * 60 * 60 * 1000L
+ var CanNotification: Boolean = false
+ const val CONSTANTS_Detail_id = "CONSTANTS_Detail_id"
+ const val Constants_requestPermissions_photo = "Constants_requestPermissions_photo"
+ const val Constants_requestPermissions_photo_detail =
+ "Constants_requestPermissions_photo_detail"
+ const val Constants_openFeedbackDetail = "Constants_openFeedbackDetail"
+ const val Constants_openFeedback = "Constants_openFeedback"
+ const val CONSTANTS_web_notification = "CONSTANTS_web_notification"
+ const val feedback_URL_res: String = "https://campaign.nebuluxetv.com/pages/leave/index"
+ const val feedback_list_URL_res: String = "https://campaign.nebuluxetv.com/pages/leave/list"
+ const val feedback_detail_URL_res: String = "https://campaign.nebuluxetv.com/pages/leave/detail"
+ const val Constants_Main_Video_status = "Constants_Main_Video_status"
+ const val Constants_Main_Video_info = "Constants_Main_Video_info"
+ var WebRefresh: Boolean = false
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/basics/MyApplication.kt b/app/src/main/java/com/jia/er/nebuluxe/app/basics/MyApplication.kt
new file mode 100644
index 0000000..d32cc1d
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/basics/MyApplication.kt
@@ -0,0 +1,136 @@
+package com.jia.er.nebuluxe.app.basics
+
+import android.app.Activity
+import android.app.Application
+import android.content.Context
+import android.os.Bundle
+import android.util.Log
+import com.jia.er.nebuluxe.app.BuildConfig.DEBUG
+//import com.adjust.sdk.Adjust
+//import com.adjust.sdk.AdjustConfig
+//import com.adjust.sdk.LogLevel
+//import com.adjust.sdk.OnEventTrackingFailedListener
+//import com.adjust.sdk.OnEventTrackingSucceededListener
+//import com.facebook.FacebookSdk
+//import com.facebook.LoggingBehavior
+//import com.facebook.appevents.AppEventsLogger
+//import com.facebook.applinks.AppLinkData
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import org.greenrobot.eventbus.EventBus
+
+
+class MyApplication : Application() {
+ private val LOG_TAG: String = "MyApplication"
+
+ companion object {
+ lateinit var context: Context
+ var isAppInBackground = true
+ var countActivity = 0
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ context = this
+// initAdjust()
+ if (DEBUG) {
+ registerActivityLifecycleCallbacks(AdjustLifecycleCallbacks())
+ }
+// registerActivityLifecycleCallbacks({
+// fun onActivityResumed(activity: Activity) {
+// Log.d("onResume", activity.javaClass.simpleName)
+// }
+//
+// } as ActivityLifecycleCallbacks?)
+// GlobalScope.launch(Dispatchers.Main) {
+// initFacebookSdk()
+// }
+
+ }
+
+ // private fun initAdjust() {
+// val appToken = "dmq04yk7ftvk"
+// val environment = AdjustConfig.ENVIRONMENT_PRODUCTION
+// val config = AdjustConfig(context, appToken, environment)
+// config.setLogLevel(LogLevel.VERBOSE)
+// config.onEventTrackingSucceededListener =
+// OnEventTrackingSucceededListener { adjustEventSuccess ->
+// Log.d(LOG_TAG, "Event recorded at " + adjustEventSuccess.timestamp)
+// }
+// config.onEventTrackingFailedListener =
+// OnEventTrackingFailedListener { adjustEventFailure ->
+// Log.v(
+// LOG_TAG,
+// "Event recording failed. Response: " + adjustEventFailure.message
+// )
+// }
+// config.setOnDeferredDeeplinkResponseListener { deeplink ->
+// Log.d(LOG_TAG, "Deferred deep link callback called!")
+// Log.d(LOG_TAG, "Deep link URL: $deeplink")
+// Memory.getMMKV()
+// .putString(Constants.Constants_DDL_Url, deeplink.toString())
+// EventBus.getDefault().post(Constants.Constants_DDL_Url)
+// true
+// }
+// Adjust.initSdk(config)
+// }
+//
+ inner class AdjustLifecycleCallbacks : ActivityLifecycleCallbacks {
+ override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
+ override fun onActivityStarted(activity: Activity) {
+// countActivity++
+// if (countActivity == 1 && isAppInBackground) {
+// isAppInBackground = false
+// Log.d("Lifecycle", "onActivityStarted")
+// EventBus.getDefault().post(Constants.CONSTANTS_enterTheApp)
+// }
+ }
+
+ override fun onActivityResumed(activity: Activity) {
+// Adjust.onResume()
+ Log.d("onResume", "=========" + activity.javaClass.simpleName + "=========")
+ }
+
+ override fun onActivityPaused(activity: Activity) {
+// Adjust.onPause()
+ }
+
+ override fun onActivityStopped(activity: Activity) {
+// countActivity--
+// if (countActivity <= 0 && !isAppInBackground) {
+// isAppInBackground = true
+// Log.d("Lifecycle", "onActivityStopped")
+// EventBus.getDefault().post(Constants.CONSTANTS_leaveApp)
+// }
+ }
+
+ override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
+ override fun onActivityDestroyed(activity: Activity) {}
+ }
+//
+// private fun initFacebookSdk() {
+// FacebookSdk.setAutoInitEnabled(true)
+// FacebookSdk.fullyInitialize()
+// if (Constants.isUat) {
+// FacebookSdk.setIsDebugEnabled(true)
+// FacebookSdk.addLoggingBehavior(LoggingBehavior.APP_EVENTS)
+// }
+// AppEventsLogger.activateApp(this)
+// AppLinkData.fetchDeferredAppLinkData(
+// this
+// ) {
+// // Process app link data
+// if (null != it) {
+// Memory.getMMKV()
+// .putString(Constants.Constants_DDL_Url, it.targetUri.toString())
+// Log.d(
+// "initFacebookSdk",
+// "fetchDeferredAppLinkData callback called!====${it.targetUri}"
+// )
+// EventBus.getDefault().post(Constants.Constants_DDL_Url)
+// }
+// Log.d("initFacebookSdk", "fetchDeferredAppLinkData callback called!")
+// }
+// }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/basics/MyContentProvider.kt b/app/src/main/java/com/jia/er/nebuluxe/app/basics/MyContentProvider.kt
new file mode 100644
index 0000000..86b4d54
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/basics/MyContentProvider.kt
@@ -0,0 +1,65 @@
+package com.jia.er.nebuluxe.app.basics
+
+import android.content.ContentProvider
+import android.content.ContentValues
+import android.database.Cursor
+import android.net.Uri
+import com.getkeepsafe.relinker.ReLinker
+import com.tencent.mmkv.MMKV
+
+class MyContentProvider : ContentProvider() {
+ override fun onCreate(): Boolean {
+ initMMKV()
+ return true
+ }
+
+ private fun initMMKV() {
+ try {
+ context?.let { MMKV.initialize(it) }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ try {
+ val dir: String = context?.filesDir?.absolutePath + "/mmkv"
+ MMKV.initialize(context, dir) { libName -> ReLinker.loadLibrary(
+ context, libName) }
+ } catch (e2: Exception) {
+ e2.printStackTrace()
+ }
+ }
+ }
+
+
+
+
+
+ override fun query(
+ uri: Uri,
+ projection: Array?,
+ selection: String?,
+ selectionArgs: Array?,
+ sortOrder: String?
+ ): Cursor? {
+ return null
+ }
+
+ override fun getType(uri: Uri): String? {
+ return null
+ }
+
+ override fun insert(uri: Uri, values: ContentValues?): Uri? {
+ return null
+ }
+
+ override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int {
+ return 0
+ }
+
+ override fun update(
+ uri: Uri,
+ values: ContentValues?,
+ selection: String?,
+ selectionArgs: Array?
+ ): Int {
+ return 0
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/AndroidBridge.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/AndroidBridge.kt
new file mode 100644
index 0000000..e085da7
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/AndroidBridge.kt
@@ -0,0 +1,130 @@
+package com.jia.er.nebuluxe.app.data
+
+import android.Manifest
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build
+import android.webkit.JavascriptInterface
+import androidx.core.content.ContextCompat
+import com.jia.er.nebuluxe.app.net.Retrofit.getCurrentTimeZone
+import com.jia.er.nebuluxe.app.utils.Memory
+import com.jia.er.nebuluxe.app.utils.singleClick
+import com.google.gson.Gson
+import com.google.gson.JsonObject
+import com.google.gson.JsonParser
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.video.PlayerDetailActivity
+import org.greenrobot.eventbus.EventBus
+
+class AndroidBridge(private val context: Context) {
+ @JavascriptInterface
+ fun getUserInfo(): String {
+ val jsInfo = ReelCrushJsInfo(
+ Memory.getMMKV()
+ .getString(Constants.CONSTANTS_AuthorizationExample, "")
+ .toString(),
+ getCurrentTimeZone(),
+ Memory.getMMKV().getString(Constants.CONSTANTS_lang_key, "en")
+ .toString(),
+ "android",
+ Memory.getMMKV().getString(Constants.CONSTANTS_Detail_id, "")
+ .toString(),"theme_1"
+ )
+ return Gson().toJson(jsInfo)
+ }
+
+ @JavascriptInterface
+ fun js2app(string: String) {
+ val parser = JsonParser()
+ val rootJson = parser.parse(string) as JsonObject
+ when (rootJson.get("type").asString) {
+
+ "open_notify" -> {
+ singleClick {
+ EventBus.getDefault().post(Constants.CONSTANTS_web_notification)
+ }
+ }
+
+ "watch_video" -> {
+ singleClick {
+ val fromJson = Gson().fromJson(string, JsonInfo::class.java)
+ context.startActivity(
+ Intent(
+ context,
+ PlayerDetailActivity::class.java
+ ).apply {
+ putExtra(
+ Constants.CONSTANTS_short_play_id,
+ fromJson.data?.short_play_id
+ )
+ putExtra(
+ Constants.CONSTANTS_activity_id,
+ fromJson.data?.activity_id
+ )
+ })
+ }
+ }
+
+ }
+ }
+
+ @JavascriptInterface
+ fun openFeedbackDetail(id: String) {
+ EventBus.getDefault()
+ .post(BaseEventBus(Constants.Constants_openFeedbackDetail, id))
+ }
+
+ @JavascriptInterface
+ fun openFeedbackList() {
+ EventBus.getDefault()
+ .post(Constants.Constants_openFeedback)
+ }
+
+ @JavascriptInterface
+ fun openPhotoPicker() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (ContextCompat.checkSelfPermission(
+ context,
+ Manifest.permission.READ_MEDIA_IMAGES
+ ) == PackageManager.PERMISSION_GRANTED
+ ) {
+ openFilePicker()
+ } else {
+ EventBus.getDefault().post(Constants.Constants_requestPermissions_photo)
+ }
+ } else {
+ if ((ContextCompat.checkSelfPermission(
+ context,
+ Manifest.permission.READ_EXTERNAL_STORAGE
+ ) == PackageManager.PERMISSION_GRANTED &&
+ ContextCompat.checkSelfPermission(
+ context,
+ Manifest.permission.READ_EXTERNAL_STORAGE
+ ) == PackageManager.PERMISSION_GRANTED &&
+ ContextCompat.checkSelfPermission(
+ context,
+ Manifest.permission.CAMERA
+ ) == PackageManager.PERMISSION_GRANTED)
+ ) {
+ openFilePicker()
+ } else {
+ EventBus.getDefault().post(Constants.Constants_requestPermissions_photo)
+ }
+ }
+
+ }
+
+
+ private val REQUEST_PICK_FILE: Int = 1002
+
+ private fun openFilePicker() {
+ val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
+ addCategory(Intent.CATEGORY_OPENABLE)
+ type = "image/*"
+ }
+ (context as? Activity)?.startActivityForResult(intent, REQUEST_PICK_FILE)
+ }
+
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/AndroidBridgeDetail.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/AndroidBridgeDetail.kt
new file mode 100644
index 0000000..a18c80c
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/AndroidBridgeDetail.kt
@@ -0,0 +1,79 @@
+package com.jia.er.nebuluxe.app.data
+
+import android.Manifest
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build
+import android.webkit.JavascriptInterface
+import androidx.core.content.ContextCompat
+import com.jia.er.nebuluxe.app.utils.Memory
+import com.google.gson.Gson
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.net.Retrofit.getCurrentTimeZone
+import org.greenrobot.eventbus.EventBus
+
+class AndroidBridgeDetail(private val context: Context) {
+ @JavascriptInterface
+ fun getUserInfo(): String {
+ val moviaJsInfo = ReelCrushJsInfo(
+ Memory.getMMKV()
+ .getString(Constants.CONSTANTS_AuthorizationExample, "")
+ .toString(),
+ getCurrentTimeZone(),
+ Memory.getMMKV().getString(Constants.CONSTANTS_lang_key, "en")
+ .toString(),
+ "android",
+ Memory.getMMKV().getString(Constants.CONSTANTS_Detail_id, "")
+ .toString(),"theme_1"
+ )
+ return Gson().toJson(moviaJsInfo)
+ }
+
+
+ @JavascriptInterface
+ fun openPhotoPicker() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (ContextCompat.checkSelfPermission(
+ context,
+ Manifest.permission.READ_MEDIA_IMAGES
+ ) == PackageManager.PERMISSION_GRANTED
+ ) {
+ openFilePicker()
+ } else {
+ EventBus.getDefault().post(Constants.Constants_requestPermissions_photo_detail)
+ }
+ } else {
+ if ((ContextCompat.checkSelfPermission(
+ context,
+ Manifest.permission.READ_EXTERNAL_STORAGE
+ ) == PackageManager.PERMISSION_GRANTED &&
+ ContextCompat.checkSelfPermission(
+ context,
+ Manifest.permission.READ_EXTERNAL_STORAGE
+ ) == PackageManager.PERMISSION_GRANTED &&
+ ContextCompat.checkSelfPermission(
+ context,
+ Manifest.permission.CAMERA
+ ) == PackageManager.PERMISSION_GRANTED)
+ ) {
+ openFilePicker()
+ } else {
+ EventBus.getDefault().post(Constants.Constants_requestPermissions_photo_detail)
+ }
+ }
+
+ }
+
+
+ private val REQUEST_PICK_FILE: Int = 1003
+
+ private fun openFilePicker() {
+ val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
+ addCategory(Intent.CATEGORY_OPENABLE)
+ type = "image/*"
+ }
+ (context as? Activity)?.startActivityForResult(intent, REQUEST_PICK_FILE)
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/BaseEventBus.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/BaseEventBus.kt
new file mode 100644
index 0000000..e64593d
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/BaseEventBus.kt
@@ -0,0 +1,3 @@
+package com.jia.er.nebuluxe.app.data
+
+data class BaseEventBus(val code: String, val data: T)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/BaseRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/BaseRes.kt
new file mode 100644
index 0000000..b6133d1
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/BaseRes.kt
@@ -0,0 +1,6 @@
+package com.jia.er.nebuluxe.app.data
+
+data class BaseRes(
+ val code: Int,
+ val msg: String,
+ val data: T?)
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/BuyVideoRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/BuyVideoRes.kt
new file mode 100644
index 0000000..258177c
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/BuyVideoRes.kt
@@ -0,0 +1,7 @@
+package com.jia.er.nebuluxe.app.data
+
+data class BuyVideoRes(
+ val status: String,
+ val coin_left_total: Int,
+ val send_coin_left_total: Int
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/CategoriesDataRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/CategoriesDataRes.kt
new file mode 100644
index 0000000..c17f9a6
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/CategoriesDataRes.kt
@@ -0,0 +1,11 @@
+package com.jia.er.nebuluxe.app.data
+
+class CategoriesDataRes(
+ val list: ArrayList
+) {
+
+ data class Item8(
+ val id: Int,
+ val name: String
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/CollectionRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/CollectionRes.kt
new file mode 100644
index 0000000..07eaf6d
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/CollectionRes.kt
@@ -0,0 +1,24 @@
+package com.jia.er.nebuluxe.app.data
+
+data class CollectionRes(
+ val list: List,
+ val pagination: Pagination
+) {
+
+ data class CollectionData(
+ val description: String,
+ val episode_total: Int,
+ val image_url: String,
+ val name: String,
+ val short_play_id: Int,
+ val current_episode: Int,
+ val short_play_video_id: Int
+ )
+
+ data class Pagination(
+ val current_page: Int,
+ val page_size: Int,
+ val page_total: Int,
+ val total_size: Int
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/CreateOrderReq.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/CreateOrderReq.kt
new file mode 100644
index 0000000..d9a4043
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/CreateOrderReq.kt
@@ -0,0 +1,8 @@
+package com.jia.er.nebuluxe.app.data
+
+data class CreateOrderReq(
+ val pay_setting_id: String,
+ val payment_channel: String,
+ val short_play_id: Int,
+ val video_id: Int
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/CreateOrderRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/CreateOrderRes.kt
new file mode 100644
index 0000000..b01373b
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/CreateOrderRes.kt
@@ -0,0 +1,5 @@
+package com.jia.er.nebuluxe.app.data
+
+data class CreateOrderRes(
+ val order_code: String
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/CustomerBuyRecordsRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/CustomerBuyRecordsRes.kt
new file mode 100644
index 0000000..ceb3463
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/CustomerBuyRecordsRes.kt
@@ -0,0 +1,18 @@
+package com.jia.er.nebuluxe.app.data
+
+class CustomerBuyRecordsRes(
+ val list: List
+) {
+
+ data class Data(
+ val coin_type: Int,
+ val coins: Int,
+ val created_at: String,
+ val episode: Int,
+ val image_url: String,
+ val is_grounding: Int,
+ val name: String,
+ val short_play_id: Int,
+ val short_play_video_id: Int
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/CustomerOrderRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/CustomerOrderRes.kt
new file mode 100644
index 0000000..c732cc3
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/CustomerOrderRes.kt
@@ -0,0 +1,20 @@
+package com.jia.er.nebuluxe.app.data
+
+data class CustomerOrderRes(
+ val list: List,
+ val pagination: Pagination
+) {
+
+ data class Item0(
+ val created_at: String,
+ val type: String,
+ val value: String
+ )
+
+ data class Pagination(
+ val current_page: Int,
+ val page_size: Int,
+ val page_total: Int,
+ val total_size: Int
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/DetailsRecommendRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/DetailsRecommendRes.kt
new file mode 100644
index 0000000..f0e28b4
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/DetailsRecommendRes.kt
@@ -0,0 +1,28 @@
+package com.jia.er.nebuluxe.app.data
+
+data class DetailsRecommendRes(
+ val brief: String,
+ val description: String,
+ val list: List- ,
+ val tag: String,
+ val title: String
+) {
+
+ data class Item(
+ val all_coins: Int,
+ val buy_type: Int,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val video_url: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val short_id: Int,
+ val short_play_id: Int?,
+ val tag_type: String,
+ val watch_total: Int
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/ExampleKeywordDataRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/ExampleKeywordDataRes.kt
new file mode 100644
index 0000000..28100e2
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/ExampleKeywordDataRes.kt
@@ -0,0 +1,30 @@
+package com.jia.er.nebuluxe.app.data
+
+class ExampleKeywordDataRes(
+ val list: List,
+) {
+
+ data class KeywordData(
+ val all_coins: Int,
+ val buy_type: Int,
+ val categoryList: List,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Long,
+ val search_click_total: Int,
+ )
+
+ data class Category(
+ val id: Int,
+ val name: String
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/FbNotificationReq.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/FbNotificationReq.kt
new file mode 100644
index 0000000..ea9a8ba
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/FbNotificationReq.kt
@@ -0,0 +1,3 @@
+package com.jia.er.nebuluxe.app.data
+
+data class FbNotificationReq(val is_open_notice: String)
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/FreeSeriesMoreRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/FreeSeriesMoreRes.kt
new file mode 100644
index 0000000..8c22d69
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/FreeSeriesMoreRes.kt
@@ -0,0 +1,24 @@
+package com.jia.er.nebuluxe.app.data
+
+data class FreeSeriesMoreRes(
+ val list: List
+) {
+
+ data class Item9(
+ val all_coins: Int,
+ val buy_type: Int,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Int
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HistoryDataRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HistoryDataRes.kt
new file mode 100644
index 0000000..32d1aab
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HistoryDataRes.kt
@@ -0,0 +1,26 @@
+package com.jia.er.nebuluxe.app.data
+
+class HistoryDataRes(
+ val list: List,
+ val pagination: Pagination
+) {
+
+ data class Data(
+ val description: String,
+ val episode_total: Int,
+ val category: List,
+ val image_url: String,
+ val name: String,
+ val short_play_id: Int,
+ var is_collect: Int,
+ val current_episode: Int,
+ val short_play_video_id: Int
+ )
+
+ data class Pagination(
+ val current_page: Int,
+ val page_size: Int,
+ val page_total: Int,
+ val total_size: Int
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeBannerAndNineSquarepRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeBannerAndNineSquarepRes.kt
new file mode 100644
index 0000000..29cd9bd
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeBannerAndNineSquarepRes.kt
@@ -0,0 +1,30 @@
+package com.jia.er.nebuluxe.app.data
+
+data class HomeBannerAndNineSquarepRes(
+ val arrangement: String,
+ val list: List,
+ val title: String
+) {
+
+ data class Item0(
+ val all_coins: Int,
+ val buy_type: Int,
+ val category: List,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val ffmpeg_id: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val jump_ffmpeg_id: Int,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val video_url: String,
+ val watch_total: Int
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeBannerBean.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeBannerBean.kt
new file mode 100644
index 0000000..98ea271
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeBannerBean.kt
@@ -0,0 +1,21 @@
+package com.jia.er.nebuluxe.app.data
+
+data class HomeBannerBean(
+ val all_coins: Any,
+ val buy_type: Int,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val video_url: String,
+ val watch_total: Int,
+ val category: List
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeBestSellersData.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeBestSellersData.kt
new file mode 100644
index 0000000..f68d8e9
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeBestSellersData.kt
@@ -0,0 +1,28 @@
+package com.jia.er.nebuluxe.app.data
+
+
+class HomeBestSellersData : ArrayList() {
+ data class HomeBestSellersDataItem(
+ val all_coins: String,
+ val buy_type: Int,
+ val categoryList: List,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Int
+ )
+
+ data class Category(
+ val id: Int,
+ val name: String
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeModuleBean.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeModuleBean.kt
new file mode 100644
index 0000000..be9c517
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeModuleBean.kt
@@ -0,0 +1,13 @@
+package com.jia.er.nebuluxe.app.data
+
+import com.google.gson.JsonElement
+
+
+class HomeModuleBean(
+ val list: List,
+) {
+ data class RecommandDataBean(
+ val module_key :String,
+ val data: JsonElement
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeNewShortPlayNoPaginateRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeNewShortPlayNoPaginateRes.kt
new file mode 100644
index 0000000..ac60f5d
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeNewShortPlayNoPaginateRes.kt
@@ -0,0 +1,25 @@
+package com.jia.er.nebuluxe.app.data
+
+class HomeNewShortPlayNoPaginateRes(
+ val list: List
+) {
+
+ data class Item8(
+ val all_coins: Int,
+ val buy_type: Int,
+ val category: List,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Int
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeNewShortPlayRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeNewShortPlayRes.kt
new file mode 100644
index 0000000..d8c093d
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeNewShortPlayRes.kt
@@ -0,0 +1,61 @@
+package com.jia.er.nebuluxe.app.data
+
+class HomeNewShortPlayRes(
+ val category_list: List,
+ val pagination: Pagination,
+ val ranking_list: List,
+ val short_play_list: MutableList
+) {
+
+ data class Category(
+ val category_id: Int,
+ val category_name: String
+ )
+
+ data class Pagination(
+ val current_page: Int,
+ val page_size: Int,
+ val page_total: Int,
+ val total_size: Int
+ )
+
+ data class Ranking(
+ val all_coins: Int,
+ val buy_type: Int,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Int
+ )
+
+ data class ShortPlay(
+ val all_coins: Int,
+ val buy_type: Int,
+ val category: List,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ var view_type: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Int,
+ var ranking_list: List,
+ var category_list: List
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeRankingRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeRankingRes.kt
new file mode 100644
index 0000000..359d273
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeRankingRes.kt
@@ -0,0 +1,25 @@
+package com.jia.er.nebuluxe.app.data
+
+class HomeRankingRes(
+ val list: List
+) {
+
+ data class Item7(
+ val all_coins: Int,
+ val buy_type: Int,
+ val category: List,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Long
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeTopRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeTopRes.kt
new file mode 100644
index 0000000..d50cc23
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeTopRes.kt
@@ -0,0 +1,30 @@
+package com.jia.er.nebuluxe.app.data
+
+data class HomeTopRes(
+ val category: List,
+ val hotData: List
+) {
+
+ data class Category(
+ val category_id: Int,
+ val category_name: String
+ )
+
+ data class HotData(
+ val all_coins: Int,
+ val buy_type: Int,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Int
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeTopWeekRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeTopWeekRes.kt
new file mode 100644
index 0000000..e4b1c32
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/HomeTopWeekRes.kt
@@ -0,0 +1,25 @@
+package com.jia.er.nebuluxe.app.data
+
+data class HomeTopWeekRes(
+ val list: List
+){
+
+data class Item8(
+ val all_coins: String,
+ val buy_type: Int,
+ val category: List,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val search_click_total: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val video_url: String,
+ val watch_total: Int
+)}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/JsonInfo.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/JsonInfo.kt
new file mode 100644
index 0000000..d2188bc
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/JsonInfo.kt
@@ -0,0 +1,14 @@
+package com.jia.er.nebuluxe.app.data
+
+class JsonInfo(
+ val `data`: Data?,
+ val is_complete: Boolean,
+ val is_show: Int,
+ val type: String
+) {
+
+ data class Data(
+ val activity_id: Int,
+ val short_play_id: Int?
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/LoginReq.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/LoginReq.kt
new file mode 100644
index 0000000..e3f84b5
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/LoginReq.kt
@@ -0,0 +1,10 @@
+package com.jia.er.nebuluxe.app.data
+
+data class LoginReq(
+ val avator: String,
+ val email: String,
+ val family_name: String,
+ val giving_name: String,
+ val platform: String,
+ val third_id: String
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/LoginRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/LoginRes.kt
new file mode 100644
index 0000000..8b70619
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/LoginRes.kt
@@ -0,0 +1,6 @@
+package com.jia.er.nebuluxe.app.data
+
+data class LoginRes(
+ val customer_id: String,
+ val token: String
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/MainDataHis.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/MainDataHis.kt
new file mode 100644
index 0000000..1d9dbf4
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/MainDataHis.kt
@@ -0,0 +1,8 @@
+package com.jia.er.nebuluxe.app.data
+
+data class MainDataHis(
+ val episode_total: String,
+ val video_id: Int,
+ val video_last: String,
+ val video_img: String
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/NoticeNumRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/NoticeNumRes.kt
new file mode 100644
index 0000000..cb8983d
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/NoticeNumRes.kt
@@ -0,0 +1,5 @@
+package com.jia.er.nebuluxe.app.data
+
+data class NoticeNumRes(
+ val feedback_notice_num: Int
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/PayReq.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/PayReq.kt
new file mode 100644
index 0000000..cfd9d8e
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/PayReq.kt
@@ -0,0 +1,11 @@
+package com.jia.er.nebuluxe.app.data
+
+data class PayReq(
+ val order_code: String,
+ val pay_setting_id: String,//id
+ val pkg_name: String,
+ val product_id: String,//template id
+ val purchases_token: String,
+ val transaction_id: String,
+ val show_money: String,
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/PayRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/PayRes.kt
new file mode 100644
index 0000000..3e97d50
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/PayRes.kt
@@ -0,0 +1,8 @@
+package com.jia.er.nebuluxe.app.data
+
+data class PayRes(
+ val is_backhaul: Int,
+ val money: String,
+ val order_code: String,
+ val status: String
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/PaySettingRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/PaySettingRes.kt
new file mode 100644
index 0000000..c1f64c6
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/PaySettingRes.kt
@@ -0,0 +1,68 @@
+package com.jia.er.nebuluxe.app.data
+
+class PaySettingRes(
+ val list_coins: List,
+ val sort: List,
+ val list_sub_vip: List,
+) {
+
+ data class Coins(
+ val android_template_id: String,
+ val backhaul_price: String,
+ val brief: String,
+ val buy_type: String,
+ val coins: Int,
+ val created_at: String,
+ val currency: String,
+ var currency_goolge: String?,
+ val description: String,
+ val id: Int,
+ val ios_template_id: String,
+ val corner_marker: String,
+ val lang_id: Int,
+ val origin_price: String,
+ val platform: String,
+ val price: String,
+ var price_google: String?,
+ val send_coins: Int,
+ val sort: Int,
+ val status: String,
+ val title: String,
+ val size: String,
+ val translate_key: String,
+ val updated_at: String,
+ val vip_type: String
+ )
+
+ data class Vip(
+ val android_template_id: String,
+ val backhaul_price: String,
+ val brief: String,
+ val short_type: String,
+ val buy_type: String,
+ val coins: Int,
+ val corner_marker: String,
+ val created_at: String,
+ val currency: String,
+ var currency_goolge: String?,
+ val description: String,
+ val id: Int,
+ val ios_template_id: String,
+ val lang_id: Int,
+ val origin_price: String,
+ val platform: String,
+ val price: String,
+ var price_google: String?,
+ val send_coins: Int,
+ val send_coin_ttl: Int,
+ val sort: Int,
+ var show: Int,
+ val status: String,
+ val title: String,
+ val translate_key: String,
+ val updated_at: String,
+ val auto_sub: String,
+ var vip_type: String,
+ var vip_type_key: String,
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/PlayerDetailDataRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/PlayerDetailDataRes.kt
new file mode 100644
index 0000000..4cc98fd
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/PlayerDetailDataRes.kt
@@ -0,0 +1,160 @@
+package com.jia.er.nebuluxe.app.data
+
+import android.os.Parcel
+import android.os.Parcelable
+
+data class PlayerDetailDataRes(
+ val episodeList: List,
+ val is_collect: Boolean,
+ val show_share_coin: Boolean,
+ val share_coin: Int,
+ val install_coins: Int,
+ val unlock_video_ad_count: Int,
+ val revolution: Int,
+ val discount: Int,
+ var jump_type: Int,
+ var jump_short_play_id: Int,
+ var business_model: String,
+ val shortPlayInfo: ShortPlayInfo,
+ val video_info: VideoInfo
+) {
+
+ data class Episode(
+ val coins: Int,
+ val episode: Int,
+ val id: Int,
+ var is_lock: Boolean,
+ val is_vip: Int,
+ val short_play_id: Int,
+ val short_play_video_id: Int,
+ val video_url: String,
+ val vip_coins: Int,
+ var play_seconds: String?,
+ var shortPlayInfo: ShortPlayInfo?,
+ var promise_view_ad: Int,
+ ): Parcelable {
+ constructor(parcel: Parcel) : this(
+ parcel.readInt(),
+ parcel.readInt(),
+ parcel.readInt(),
+ parcel.readByte() != 0.toByte(),
+ parcel.readInt(),
+ parcel.readInt(),
+ parcel.readInt(),
+ parcel.readString().toString(),
+ parcel.readInt(),
+ parcel.readString(),
+ parcel.readParcelable(ShortPlayInfo::class.java.classLoader),
+ parcel.readInt()
+ ) {
+ }
+
+ override fun writeToParcel(parcel: Parcel, flags: Int) {
+ parcel.writeInt(coins)
+ parcel.writeInt(episode)
+ parcel.writeInt(id)
+ parcel.writeByte(if (is_lock) 1 else 0)
+ parcel.writeInt(is_vip)
+ parcel.writeInt(short_play_id)
+ parcel.writeInt(short_play_video_id)
+ parcel.writeString(video_url)
+ parcel.writeInt(vip_coins)
+ parcel.writeString(play_seconds)
+ parcel.writeParcelable(shortPlayInfo, flags)
+ parcel.writeInt(promise_view_ad)
+ }
+
+ override fun describeContents(): Int {
+ return 0
+ }
+
+ companion object CREATOR : Parcelable.Creator {
+ override fun createFromParcel(parcel: Parcel): Episode {
+ return Episode(parcel)
+ }
+
+ override fun newArray(size: Int): Array {
+ return arrayOfNulls(size)
+ }
+ }
+
+
+ }
+
+ data class ShortPlayInfo(
+ val all_coins: Int,
+ val buy_type: Int,
+ var collect_total: Int,
+ val description: String,
+ val category: ArrayList?,
+ val episode_total: Int,
+ val id: Int,
+ val image_url: String,
+ var is_collect: Boolean,
+ val name: String,
+ val process: Int,
+ val short_id: Int,
+ val watch_total: Int
+ ): Parcelable {
+ constructor(parcel: Parcel) : this(
+ parcel.readInt(),
+ parcel.readInt(),
+ parcel.readInt(),
+ parcel.readString().toString(),
+ parcel.createStringArrayList(),
+ parcel.readInt(),
+ parcel.readInt(),
+ parcel.readString().toString(),
+ parcel.readByte() != 0.toByte(),
+ parcel.readString().toString(),
+ parcel.readInt(),
+ parcel.readInt(),
+ parcel.readInt()
+ ) {
+ }
+
+ override fun writeToParcel(parcel: Parcel, flags: Int) {
+ parcel.writeInt(all_coins)
+ parcel.writeInt(buy_type)
+ parcel.writeInt(collect_total)
+ parcel.writeString(description)
+ parcel.writeStringList(category)
+ parcel.writeInt(episode_total)
+ parcel.writeInt(id)
+ parcel.writeString(image_url)
+ parcel.writeByte(if (is_collect) 1 else 0)
+ parcel.writeString(name)
+ parcel.writeInt(process)
+ parcel.writeInt(short_id)
+ parcel.writeInt(watch_total)
+ }
+
+ override fun describeContents(): Int {
+ return 0
+ }
+
+ companion object CREATOR : Parcelable.Creator {
+ override fun createFromParcel(parcel: Parcel): ShortPlayInfo {
+ return ShortPlayInfo(parcel)
+ }
+
+ override fun newArray(size: Int): Array {
+ return arrayOfNulls(size)
+ }
+ }
+
+ }
+
+ data class VideoInfo(
+ val coins: Int,
+ val episode: Int,
+ val id: Int,
+ val is_vip: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val short_play_video_id: Int,
+ val promise_view_ad: Int,
+ val video_url: String,
+ val vip_coins: Int
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/RecommendDataRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/RecommendDataRes.kt
new file mode 100644
index 0000000..8462415
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/RecommendDataRes.kt
@@ -0,0 +1,39 @@
+package com.jia.er.nebuluxe.app.data
+
+data class RecommendDataRes(
+ val list: List,
+ val pagination: Pagination
+) {
+
+ data class Data(
+ val all_price_total: Int,
+ val buy_type: Int,
+ var collect_total: Int?,
+ val description: String,
+ val episode_total: Int,
+ val id: Int,
+ val image_url: String,
+ var is_collect: Boolean,
+ val name: String,
+ val process: Int,
+ val video_info: VideoInfo?,
+ val watch_total: Int
+ )
+
+ data class Pagination(
+ val current_page: Int,
+ val page_size: Int,
+ val page_total: Int,
+ val total_size: Int
+ )
+
+ data class VideoInfo(
+ val episode: Int,
+ val id: Int,
+ val is_vip: Int,
+ val short_play_id: Int,
+ val short_play_video_id: Int,
+ val video_url: String,
+ val image_url: String
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/ReelCrushJsInfo.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/ReelCrushJsInfo.kt
new file mode 100644
index 0000000..a065c7b
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/ReelCrushJsInfo.kt
@@ -0,0 +1,10 @@
+package com.jia.er.nebuluxe.app.data
+
+data class ReelCrushJsInfo(
+ val token: String,
+ val time_zone: String,
+ val lang: String,
+ val type: String,
+ val id: String,
+ val theme: String
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/RewardCoinsRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/RewardCoinsRes.kt
new file mode 100644
index 0000000..0252e1e
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/RewardCoinsRes.kt
@@ -0,0 +1,14 @@
+package com.jia.er.nebuluxe.app.data
+
+class RewardCoinsRes(val list: List) {
+ data class ExampleRewardCoinsResItem(
+ val coins: Int,
+ val created_at: String,
+ val diff_datetime: String,
+ val expired_time: Int,
+ val id: Int,
+ val is_effective: Int,
+ val left_coins: String,
+ val type: String
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/ShortListCategoryDataInfo.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/ShortListCategoryDataInfo.kt
new file mode 100644
index 0000000..fa843b4
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/ShortListCategoryDataInfo.kt
@@ -0,0 +1,32 @@
+package com.jia.er.nebuluxe.app.data
+
+
+class ShortListCategoryDataInfo(
+ val list: List,
+) {
+
+ data class CategoryListData(
+
+ val id: Int,
+ val category_name: String,
+ val short_play_list: List
+
+ )
+
+ data class ShortPlayListData(
+ val all_coins: Int,
+ val buy_type: Int,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Long
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/TabEntity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/TabEntity.kt
new file mode 100644
index 0000000..8e3a05d
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/TabEntity.kt
@@ -0,0 +1,20 @@
+package com.jia.er.nebuluxe.app.data
+
+import com.flyco.tablayout.listener.CustomTabEntity
+
+class TabEntity(var s1: String, var i1: Int, var i2: Int) :
+ CustomTabEntity {
+
+ override fun getTabTitle(): String {
+ return s1
+ }
+
+ override fun getTabSelectedIcon(): Int {
+ return i1
+ }
+
+ override fun getTabUnselectedIcon(): Int {
+ return i2
+ }
+
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/UploadHistoryReq.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/UploadHistoryReq.kt
new file mode 100644
index 0000000..9950b0e
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/UploadHistoryReq.kt
@@ -0,0 +1,7 @@
+package com.jia.er.nebuluxe.app.data
+
+data class UploadHistoryReq(
+ val play_seconds: Long?,
+ val short_play_id: Int,
+ val video_id: Int?
+)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/UserInfoRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/UserInfoRes.kt
new file mode 100644
index 0000000..0f2e83c
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/UserInfoRes.kt
@@ -0,0 +1,30 @@
+package com.jia.er.nebuluxe.app.data
+
+data class UserInfoRes(
+ val avator: String = "",
+ val coin_left_total: Int = 0,
+ val country: String = "",
+ val country_code: String = "",
+ val customer_id: String = "",
+ val email: String = "",
+ val family_name: String = "",
+ val fn: String = "",
+ val giving_name: String = "",
+ val id: String = "",
+ val ip_address: String = "0.0.0.0",
+ val is_guide_vip: Boolean = false,
+ val is_tourist: Boolean = true,
+ val is_vip: Boolean = false,
+ val ln: String = "",
+ val registered_days: Int = 0,
+ val send_coin_left_total: Int = 0,
+ val third_access_platform: String = "",
+ val vip_end_time: Int = 0,
+ val vip_type: String = ""
+) {
+ companion object {
+ fun createWithDefaults(): UserInfoRes {
+ return UserInfoRes()
+ }
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/UserRegisterRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/UserRegisterRes.kt
new file mode 100644
index 0000000..53e90b3
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/UserRegisterRes.kt
@@ -0,0 +1,4 @@
+package com.jia.er.nebuluxe.app.data
+
+data class UserRegisterRes(val customer_id: String,
+ val token: String)
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/data/VideoListDataRes.kt b/app/src/main/java/com/jia/er/nebuluxe/app/data/VideoListDataRes.kt
new file mode 100644
index 0000000..8fc6f92
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/data/VideoListDataRes.kt
@@ -0,0 +1,29 @@
+package com.jia.er.nebuluxe.app.data
+
+class VideoListDataRes(
+ val list: List,
+) {
+
+ data class VideoListData(
+ val all_coins: Int,
+ val buy_type: Int,
+ val categoryList: List,
+ val collect_total: Int,
+ val description: String,
+ val episode_total: Int,
+ val horizontally_img: String,
+ val id: Int,
+ val image_url: String,
+ val name: String,
+ val process: Int,
+ val short_id: Int,
+ val short_play_id: Int,
+ val tag_type: String,
+ val watch_total: Long
+ )
+
+ data class Category(
+ val id: Int,
+ val name: String
+ )
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/FreshActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/FreshActivity.kt
new file mode 100644
index 0000000..85de714
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/FreshActivity.kt
@@ -0,0 +1,84 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Intent
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.blankj.utilcode.util.NetworkUtils
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseActivity
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.data.HomeRankingRes
+import com.jia.er.nebuluxe.app.databinding.ActivityFreshBinding
+import com.jia.er.nebuluxe.app.databinding.ActivityRankingsBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.singleClick
+import com.jia.er.nebuluxe.app.utils.toast
+import com.jia.er.nebuluxe.app.video.PlayerDetailActivity
+
+
+class FreshActivity : BaseActivity() {
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+ private var type = "new_releases"
+
+ override fun top() {
+ binding?.exampleIvBack?.setOnClickListener { finish() }
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.homeRanking(type)
+ } else {
+ showNetError()
+ }
+ binding.srRank.setOnRefreshListener {
+ mViewModel.homeRanking(type)
+ }
+ }
+
+ override fun center() {
+ mViewModel.homeRankingData.observe(this) {
+ if (it != null) {
+ if (it.data?.list?.isNotEmpty() == true) {
+ val homeRankTrendingAdapter = FreshAdapter()
+ val manager1 = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
+ binding?.rvRanks?.layoutManager = manager1
+ binding?.rvRanks?.adapter = homeRankTrendingAdapter
+ homeRankTrendingAdapter?.submitList(it.data.list)
+ homeRankTrendingAdapter?.isStateViewEnable = true
+ homeRankTrendingAdapter?.setStateViewLayout(this, R.layout.layout_emptyview)
+ homeRankTrendingAdapter?.setOnItemClickListener { adapter, view, position ->
+ val data = adapter.getItem(position) as HomeRankingRes.Item7
+ startActivity(Intent(
+ this, PlayerDetailActivity::class.java
+ ).apply {
+ putExtra(
+ Constants.CONSTANTS_short_play_id, data.short_play_id
+ )
+ })
+ }
+ }
+ binding.srRank.finishRefresh()
+ hideNetError()
+ hideLoading()
+ } else {
+ showNetError()
+ toast(getString(R.string.network_error))
+ hideLoading()
+ }
+ }
+ }
+
+ override fun getViewBinding(): ActivityFreshBinding {
+ return ActivityFreshBinding.inflate(layoutInflater)
+ }
+
+ override fun onRetry() {
+ super.onRetry()
+ singleClick {
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.homeRanking(type)
+ } else {
+ toast(getString(R.string.example_no_network))
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/FreshAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/FreshAdapter.kt
new file mode 100644
index 0000000..7dff62a
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/FreshAdapter.kt
@@ -0,0 +1,57 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.appcompat.widget.AppCompatImageView
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.resource.bitmap.CenterCrop
+import com.chad.library.adapter4.BaseQuickAdapter
+import com.chad.library.adapter4.fullspan.FullSpanAdapterType
+import com.chad.library.adapter4.viewholder.QuickViewHolder
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.data.HomeRankingRes
+import com.jia.er.nebuluxe.app.ui.CustomRoundedCorners
+import com.jia.er.nebuluxe.app.utils.dpToPxByFloat
+
+
+class FreshAdapter :
+ BaseQuickAdapter(),
+ FullSpanAdapterType {
+ override fun onBindViewHolder(
+ holder: QuickViewHolder,
+ position: Int,
+ item: HomeRankingRes.Item7?
+ ) {
+ Glide.with(context).load(item?.image_url).placeholder(R.drawable.iv_placeholder_v)
+ .into(holder.getView(R.id.iv_cover))
+ holder.setText(R.id.tv_rank_name, item?.name)
+ if (item?.category?.isNotEmpty() == true) {
+ val string = item.category[0]
+ holder.setText(R.id.tv_rank_tag, string)
+ holder.setVisible(R.id.tv_rank_tag, true)
+ } else {
+ holder.setVisible(R.id.tv_rank_tag, false)
+ }
+ val view = holder.getView(R.id.example_iv_icon_ceo)
+ Glide.with(context)
+ .load(item?.image_url).placeholder(R.drawable.iv_placeholder_v)
+ .transform(
+ CenterCrop(),
+ CustomRoundedCorners(
+ dpToPxByFloat(20, context),
+ 0f,
+ dpToPxByFloat(20, context),
+ dpToPxByFloat(20, context)
+ )
+ )
+ .into(view)
+ }
+
+ override fun onCreateViewHolder(
+ context: Context,
+ parent: ViewGroup,
+ viewType: Int
+ ): QuickViewHolder {
+ return QuickViewHolder(R.layout.item_fresh, parent)
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/GenresActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/GenresActivity.kt
new file mode 100644
index 0000000..98fa4bb
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/GenresActivity.kt
@@ -0,0 +1,101 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Intent
+import android.graphics.Rect
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.blankj.utilcode.util.NetworkUtils
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseActivity
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.data.HomeRankingRes
+import com.jia.er.nebuluxe.app.data.ShortListCategoryDataInfo
+import com.jia.er.nebuluxe.app.databinding.ActivityFreshBinding
+import com.jia.er.nebuluxe.app.databinding.ActivityRankingsBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.singleClick
+import com.jia.er.nebuluxe.app.utils.toast
+import com.jia.er.nebuluxe.app.video.PlayerDetailActivity
+
+
+class GenresActivity : BaseActivity() {
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+
+ override fun top() {
+ binding?.exampleIvBack?.setOnClickListener { finish() }
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.userCenterRecommend()
+ } else {
+ showNetError()
+ }
+ binding.srRank.setOnRefreshListener {
+ mViewModel.userCenterRecommend()
+ }
+ }
+
+ override fun center() {
+ mViewModel.userCenterRecommendData.observe(this) {
+ if (it != null) {
+ if (it.data?.list?.isNotEmpty() == true) {
+ val homeRankTrendingAdapter = GenresAdapter()
+ val manager1 = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
+ binding?.rvRanks?.layoutManager = manager1
+ binding?.rvRanks?.adapter = homeRankTrendingAdapter
+ homeRankTrendingAdapter?.submitList(it.data.list)
+ binding?.rvRanks?.addItemDecoration(object : RecyclerView.ItemDecoration() {
+ override fun getItemOffsets(
+ outRect: Rect,
+ view: View,
+ parent: RecyclerView,
+ state: RecyclerView.State
+ ) {
+ super.getItemOffsets(outRect, view, parent, state)
+ if (parent.getChildPosition(view) != (it.data.list.size - 1)) {
+ outRect.bottom = -100
+ }
+ }
+ })
+ homeRankTrendingAdapter?.isStateViewEnable = true
+ homeRankTrendingAdapter?.setStateViewLayout(this, R.layout.layout_emptyview)
+ homeRankTrendingAdapter?.setOnItemClickListener { adapter, view, position ->
+ val data =
+ adapter.getItem(position) as ShortListCategoryDataInfo.CategoryListData
+// startActivity(Intent(
+// this, PlayerDetailActivity::class.java
+// ).apply {
+// putExtra(
+// Constants.CONSTANTS_short_play_id, data.short_play_id
+// )
+// })
+ }
+ }
+ binding.srRank.finishRefresh()
+ hideNetError()
+ hideLoading()
+ } else {
+ showNetError()
+ toast(getString(R.string.network_error))
+ hideLoading()
+ }
+ }
+ }
+
+ override fun getViewBinding(): ActivityFreshBinding {
+ return ActivityFreshBinding.inflate(layoutInflater)
+ }
+
+ override fun onRetry() {
+ super.onRetry()
+ singleClick {
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.userCenterRecommend()
+ } else {
+ toast(getString(R.string.example_no_network))
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/GenresAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/GenresAdapter.kt
new file mode 100644
index 0000000..4d4bba3
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/GenresAdapter.kt
@@ -0,0 +1,67 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.Color
+import android.graphics.Rect
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.chad.library.adapter4.BaseQuickAdapter
+import com.chad.library.adapter4.fullspan.FullSpanAdapterType
+import com.chad.library.adapter4.viewholder.QuickViewHolder
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.data.ShortListCategoryDataInfo
+
+
+class GenresAdapter :
+ BaseQuickAdapter(),
+ FullSpanAdapterType {
+ override fun onBindViewHolder(
+ holder: QuickViewHolder,
+ position: Int,
+ item: ShortListCategoryDataInfo.CategoryListData?
+ ) {
+ when (position) {
+ 0 -> {
+ holder.setBackgroundResource(R.id.rl, R.drawable.iv_genres_1)
+ holder.setBackgroundResource(R.id.line, R.color.E3D4FF)
+ }
+
+ 1 -> {
+ holder.setBackgroundResource(R.id.rl, R.drawable.iv_genres_2)
+ holder.setBackgroundResource(R.id.line, R.color.BDF5E2)
+ }
+
+ 2 -> {
+ holder.setBackgroundResource(R.id.rl, R.drawable.iv_genres_3)
+ holder.setBackgroundResource(R.id.line, R.color.FFFA80)
+ }
+
+ else -> {
+ holder.setBackgroundResource(R.id.rl, R.drawable.iv_genres_4)
+ holder.setBackgroundResource(R.id.line, R.color.F0C2E1)
+ }
+ }
+ val view = holder.getView(R.id.rv_genres_item)
+ holder.setText(R.id.tv_type, item?.category_name)
+ holder.setText(
+ R.id.tv_num,
+ item?.short_play_list?.size.toString().plus("\n").plus("Dramas")
+ )
+ val homeRankTrendingAdapter = GenresItemAdapter()
+ val manager1 = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
+ view?.layoutManager = manager1
+ view?.adapter = homeRankTrendingAdapter
+ homeRankTrendingAdapter?.submitList(item?.short_play_list)
+ }
+
+ override fun onCreateViewHolder(
+ context: Context,
+ parent: ViewGroup,
+ viewType: Int
+ ): QuickViewHolder {
+ return QuickViewHolder(R.layout.item_genres, parent)
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/GenresItemAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/GenresItemAdapter.kt
new file mode 100644
index 0000000..7f68113
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/GenresItemAdapter.kt
@@ -0,0 +1,32 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Context
+import android.view.ViewGroup
+import com.bumptech.glide.Glide
+import com.chad.library.adapter4.BaseQuickAdapter
+import com.chad.library.adapter4.fullspan.FullSpanAdapterType
+import com.chad.library.adapter4.viewholder.QuickViewHolder
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.data.ShortListCategoryDataInfo
+
+
+class GenresItemAdapter :
+ BaseQuickAdapter(),
+ FullSpanAdapterType {
+ override fun onBindViewHolder(
+ holder: QuickViewHolder,
+ position: Int,
+ item: ShortListCategoryDataInfo.ShortPlayListData?
+ ) {
+ Glide.with(context).load(item?.image_url).placeholder(R.drawable.iv_placeholder_v)
+ .into(holder.getView(R.id.iv_cover))
+ }
+
+ override fun onCreateViewHolder(
+ context: Context,
+ parent: ViewGroup,
+ viewType: Int
+ ): QuickViewHolder {
+ return QuickViewHolder(R.layout.item_genres_img, parent)
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeBannerAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeBannerAdapter.kt
new file mode 100644
index 0000000..f0eb733
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeBannerAdapter.kt
@@ -0,0 +1,57 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.widget.AppCompatImageView
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.data.HomeBannerAndNineSquarepRes
+import com.youth.banner.adapter.BannerAdapter
+
+class HomeBannerAdapter(items: List?) :
+ BannerAdapter(
+ items
+ ) {
+ override fun onCreateHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
+ val view: View = LayoutInflater.from(parent.context)
+ .inflate(R.layout.custom_banner_view, parent, false)
+ view.layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ return BannerViewHolder(view)
+ }
+
+
+ override fun onBindView(
+ holder: BannerViewHolder?,
+ data: HomeBannerAndNineSquarepRes.Item0?,
+ position: Int,
+ size: Int
+ ) {
+ val findViewById =
+ holder?.view?.findViewById(R.id.iv_icon_banner)
+ val tv_name = holder?.view?.findViewById(R.id.tv_name)
+ val tv_tag = holder?.view?.findViewById(R.id.tv_tag)
+ if (findViewById != null) {
+ Glide.with(holder.itemView.context)
+ .load(data?.image_url).placeholder(R.drawable.iv_placeholder_v)
+ .into(findViewById)
+ }
+ tv_name?.text = data?.name
+ if (data?.category?.isNotEmpty() == true) {
+ tv_tag?.visibility = View.VISIBLE
+ tv_tag?.text = data?.category[0]
+ } else {
+ tv_tag?.visibility = View.INVISIBLE
+ }
+ }
+
+ inner class BannerViewHolder(var view: View) : RecyclerView.ViewHolder(
+ view
+ )
+
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeBannerBottomAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeBannerBottomAdapter.kt
new file mode 100644
index 0000000..fb0ab61
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeBannerBottomAdapter.kt
@@ -0,0 +1,60 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.widget.AppCompatImageView
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.data.HomeBannerAndNineSquarepRes
+import com.jia.er.nebuluxe.app.data.HomeTopWeekRes
+import com.youth.banner.adapter.BannerAdapter
+
+class HomeBannerBottomAdapter(items: List?) :
+ BannerAdapter(
+ items
+ ) {
+ override fun onCreateHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
+ val view: View = LayoutInflater.from(parent.context)
+ .inflate(R.layout.custom_banner_view_bottom, parent, false)
+ view.layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ return BannerViewHolder(view)
+ }
+
+
+ override fun onBindView(
+ holder: BannerViewHolder?,
+ data: HomeTopWeekRes.Item8?,
+ position: Int,
+ size: Int
+ ) {
+ val findViewById =
+ holder?.view?.findViewById(R.id.iv_icon_banner)
+ val tv_name = holder?.view?.findViewById(R.id.tv_name)
+ val tv_tag = holder?.view?.findViewById(R.id.tv_tag)
+ val tv_des = holder?.view?.findViewById(R.id.tv_des)
+ if (findViewById != null) {
+ Glide.with(holder.itemView.context)
+ .load(data?.image_url).placeholder(R.drawable.iv_placeholder_v)
+ .into(findViewById)
+ }
+ tv_name?.text = data?.name
+ tv_des?.text = data?.description
+ if (data?.category?.isNotEmpty() == true) {
+ tv_tag?.visibility = View.VISIBLE
+ tv_tag?.text = data?.category[0]
+ } else {
+ tv_tag?.visibility = View.INVISIBLE
+ }
+ }
+
+ inner class BannerViewHolder(var view: View) : RecyclerView.ViewHolder(
+ view
+ )
+
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeForYouAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeForYouAdapter.kt
new file mode 100644
index 0000000..4652915
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeForYouAdapter.kt
@@ -0,0 +1,29 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Context
+import android.view.ViewGroup
+import com.bumptech.glide.Glide
+import com.chad.library.adapter4.BaseQuickAdapter
+import com.chad.library.adapter4.viewholder.QuickViewHolder
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.data.RecommendDataRes
+
+class HomeForYouAdapter :
+ BaseQuickAdapter() {
+ override fun onBindViewHolder(
+ holder: QuickViewHolder,
+ position: Int,
+ item: RecommendDataRes.Data?
+ ) {
+ Glide.with(context).load(item?.image_url)
+ .into(holder.getView(R.id.iv_icon))
+ }
+
+ override fun onCreateViewHolder(
+ context: Context,
+ parent: ViewGroup,
+ viewType: Int
+ ): QuickViewHolder {
+ return QuickViewHolder(R.layout.item_home_for_you, parent)
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeFragment.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeFragment.kt
new file mode 100644
index 0000000..bb2b6ed
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeFragment.kt
@@ -0,0 +1,265 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Intent
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.blankj.utilcode.util.NetworkUtils
+import com.bumptech.glide.Glide
+import com.google.gson.Gson
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseFragment
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.data.HomeBannerAndNineSquarepRes
+import com.jia.er.nebuluxe.app.data.HomeBannerBean
+import com.jia.er.nebuluxe.app.data.HomeTopWeekRes
+import com.jia.er.nebuluxe.app.databinding.FragmentHomeBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.ui.RotateDownPageTransformer
+import com.jia.er.nebuluxe.app.utils.singleClick
+import com.jia.er.nebuluxe.app.utils.toast
+import com.jia.er.nebuluxe.app.video.PlayerDetailActivity
+import org.greenrobot.eventbus.EventBus
+
+
+class HomeFragment : BaseFragment() {
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+ private var page: Int = 1
+ private val gson = Gson()
+ override fun top() {
+ if (NetworkUtils.isConnected()) {
+ mViewModel.allModules()
+ } else {
+ EventBus.getDefault().post(Constants.CONSTANTS_main_stop)
+ showNetError()
+ }
+ binding?.srHome?.setOnRefreshListener {
+ page = 1
+ mViewModel.allModules()
+ }
+ binding.tvHot.setOnClickListener {
+ singleClick {
+ startActivity(
+ Intent(
+ context,
+ HotActivity::class.java
+ ))
+ }
+ }
+ binding.tvTop.setOnClickListener {
+ singleClick {
+ startActivity(
+ Intent(
+ context,
+ RankActivity::class.java
+ ))
+ }
+ }
+ binding.tvFresh.setOnClickListener {
+ singleClick {
+ startActivity(
+ Intent(
+ context,
+ FreshActivity::class.java
+ ))
+ }
+ }
+ binding.tvFresh.setOnClickListener {
+ singleClick {
+ startActivity(
+ Intent(
+ context,
+ GenresActivity::class.java
+ ))
+ }
+ }
+ }
+
+ private var dataList: MutableList = mutableListOf()
+
+ override fun center() {
+ mViewModel.allModulesData.observe(this) {
+ if (it != null) {
+ if (it?.data?.list?.isNotEmpty() == true) {
+ for (item in it.data.list) {
+ when (item.module_key) {
+ "marquee" -> {
+ binding.root.postDelayed({
+ dataList.clear()
+ val marqueeList =
+ gson.fromJson(item.data, Array::class.java)
+ .toList()
+ marqueeList?.forEach { it1 ->
+ dataList.add(it1.name)
+ }
+ if (dataList.isNotEmpty()) {
+ binding?.tvText?.setData(dataList)
+ }
+ }, 1000)
+ }
+
+ "home_banner" -> {
+ val bannerList =
+ gson.fromJson(item.data, Array::class.java)
+ .toList()
+ if (bannerList?.isNotEmpty() == true) {
+ binding?.clFs?.visibility = View.VISIBLE
+ val exampleDominantCeoAdapter = HomeMostAdapter()
+ val layoutManager =
+ LinearLayoutManager(
+ context,
+ LinearLayoutManager.HORIZONTAL,
+ false
+ )
+ binding?.rvFs?.layoutManager = layoutManager
+ binding?.rvFs?.adapter = exampleDominantCeoAdapter
+ binding?.rvFs?.isNestedScrollingEnabled = false
+ exampleDominantCeoAdapter.submitList(bannerList)
+ val video = bannerList[0]
+ Glide.with(requireContext()).load(video?.horizontally_img)
+ .placeholder(R.drawable.iv_placeholder_h)
+ .into(binding.ivFs)
+ binding.tvName.text = video.name
+ if (video.category.isNotEmpty()) {
+ binding.tvTag.visibility = View.VISIBLE
+ binding.tvTag.text = video.category[0]
+ } else {
+ binding.tvTag.visibility = View.INVISIBLE
+ }
+ binding.ivFs.setOnClickListener {
+ startActivity(
+ Intent(
+ context,
+ PlayerDetailActivity::class.java
+ ).apply {
+ putExtra(
+ Constants.CONSTANTS_short_play_id,
+ video.short_play_id
+ )
+ })
+ }
+ exampleDominantCeoAdapter.setOnItemClickListener { adapter, view, position ->
+ exampleDominantCeoAdapter.currentPosition = position
+ val video =
+ adapter.getItem(position) as HomeBannerBean
+ Glide.with(requireContext()).load(video?.horizontally_img)
+ .placeholder(R.drawable.iv_placeholder_h)
+ .into(binding.ivFs)
+ binding.tvName.text = video.name
+ if (video.category.isNotEmpty()) {
+ binding.tvTag.visibility = View.VISIBLE
+ binding.tvTag.text = video.category[0]
+ } else {
+ binding.tvTag.visibility = View.INVISIBLE
+ }
+ binding.ivFs.setOnClickListener {
+ startActivity(
+ Intent(
+ context,
+ PlayerDetailActivity::class.java
+ ).apply {
+ putExtra(
+ Constants.CONSTANTS_short_play_id,
+ video.short_play_id
+ )
+ })
+ }
+ exampleDominantCeoAdapter.notifyDataSetChanged()
+ }
+
+ } else {
+ binding?.clFs?.visibility = View.GONE
+ }
+ }
+
+ "home_v3_recommand" -> {
+ val homeBannerAndNineSquarepRes =
+ gson.fromJson(
+ item.data,
+ HomeBannerAndNineSquarepRes::class.java
+ )
+ if (homeBannerAndNineSquarepRes?.list?.isNotEmpty() == true) {
+ binding?.clBanner?.visibility = View.VISIBLE
+ val exampleHomeBannerAdapter =
+ HomeBannerAdapter(homeBannerAndNineSquarepRes?.list)
+ binding?.bannerHome?.apply {
+ setAdapter(exampleHomeBannerAdapter)
+ setBannerGalleryEffect(65, 10, 1f)
+ setPageTransformer(RotateDownPageTransformer(10.5f))
+ }
+ exampleHomeBannerAdapter.setOnBannerListener { data, position ->
+ startActivity(
+ Intent(
+ context,
+ PlayerDetailActivity::class.java
+ ).apply {
+ putExtra(
+ Constants.CONSTANTS_short_play_id,
+ data?.short_play_id
+ )
+ })
+ }
+ } else {
+ binding?.clBanner?.visibility = View.GONE
+ }
+ }
+
+ "new_recommand" -> {
+ val cagetoryBean =
+ gson.fromJson(item.data, HomeTopWeekRes::class.java)
+ if (cagetoryBean.list.isNotEmpty()) {
+ binding?.clBannerB?.visibility = View.VISIBLE
+ val exampleHomeBannerAdapter =
+ HomeBannerBottomAdapter(cagetoryBean.list)
+ binding?.bannerHomeB?.setBannerGalleryEffect(24, 10, 1f)
+ binding?.bannerHomeB?.setAdapter(
+ exampleHomeBannerAdapter
+ )?.addBannerLifecycleObserver(this)
+ ?.setIndicator(binding.indicatorHome, false)
+ exampleHomeBannerAdapter.setOnBannerListener { data, position ->
+ startActivity(
+ Intent(
+ context,
+ PlayerDetailActivity::class.java
+ ).apply {
+ putExtra(
+ Constants.CONSTANTS_short_play_id,
+ data?.short_play_id
+ )
+ })
+ }
+ } else {
+ binding?.clBannerB?.visibility = View.GONE
+ }
+ }
+ }
+ }
+ hideLoading()
+ hideNetError()
+ binding?.srHome?.finishRefresh()
+ EventBus.getDefault().post(Constants.CONSTANTS_main_stop)
+ }
+ } else {
+ toast(getString(R.string.network_error))
+ hideLoading()
+ binding?.srHome?.finishRefresh()
+ EventBus.getDefault().post(Constants.CONSTANTS_main_stop)
+ }
+ }
+ }
+
+ override fun getViewBinding(): FragmentHomeBinding {
+ return FragmentHomeBinding.inflate(layoutInflater)
+ }
+
+ override fun onRetry() {
+ super.onRetry()
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.allModules()
+ } else {
+ toast(getString(R.string.example_no_network))
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeMostAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeMostAdapter.kt
new file mode 100644
index 0000000..a3ea2fb
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/HomeMostAdapter.kt
@@ -0,0 +1,58 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Context
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.graphics.Outline
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewOutlineProvider
+import android.widget.ImageView
+import com.bumptech.glide.Glide
+import com.chad.library.adapter4.BaseQuickAdapter
+import com.chad.library.adapter4.viewholder.QuickViewHolder
+import com.google.android.material.imageview.ShapeableImageView
+import com.google.android.material.shape.RelativeCornerSize
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.data.HomeBannerBean
+
+class HomeMostAdapter :
+ BaseQuickAdapter() {
+ var currentPosition = 0
+ override fun onBindViewHolder(
+ holder: QuickViewHolder,
+ position: Int,
+ item: HomeBannerBean?
+ ) {
+ val view = holder.getView(R.id.example_iv_icon_ceo)
+ Glide.with(context).load(item?.image_url).placeholder(R.drawable.iv_placeholder_v)
+ .into(view)
+ view.scaleType = ImageView.ScaleType.CENTER_CROP
+ view.shapeAppearanceModel = view.shapeAppearanceModel
+ .toBuilder()
+ .setAllCornerSizes(RelativeCornerSize(0.5f))
+ .build()
+ view.elevation = 0f
+ view.clipToOutline = true
+ view.outlineProvider = object : ViewOutlineProvider() {
+ override fun getOutline(view: View, outline: Outline) {
+ val size = minOf(view.width, view.height)
+ outline.setOval(0, 0, size, size)
+ }
+ }
+
+ if (currentPosition == position) {
+ holder.setVisible(R.id.view, false)
+ } else {
+ holder.setVisible(R.id.view, true)
+ }
+ }
+
+ override fun onCreateViewHolder(
+ context: Context,
+ parent: ViewGroup,
+ viewType: Int
+ ): QuickViewHolder {
+ return QuickViewHolder(R.layout.item_dominant_ceo, parent)
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/HotActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/HotActivity.kt
new file mode 100644
index 0000000..482371d
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/HotActivity.kt
@@ -0,0 +1,91 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Intent
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.StaggeredGridLayoutManager
+import com.blankj.utilcode.util.NetworkUtils
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseActivity
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.data.VideoListDataRes
+import com.jia.er.nebuluxe.app.databinding.FragmentHotBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.singleClick
+import com.jia.er.nebuluxe.app.utils.toast
+import com.jia.er.nebuluxe.app.video.PlayerDetailActivity
+
+class HotActivity : BaseActivity() {
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+
+ private var hotAdapter: HotAdapter? = null
+ private var isLoad = false
+ override fun top() {
+ binding?.exampleIvBack?.setOnClickListener { finish() }
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.homeHot(1, 10)
+ } else {
+ showNetError()
+ }
+ binding?.srFree?.setOnRefreshListener {
+ mViewModel.homeHot(1, 10)
+ }
+ }
+
+
+ override fun center() {
+ mViewModel.homeHotData.observe(this) {
+ if (it != null) {
+ hotAdapter = HotAdapter()
+ val layoutManager =
+ StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
+ binding?.rvDataFree?.layoutManager = layoutManager
+ binding?.rvDataFree?.adapter = hotAdapter
+ binding?.rvDataFree?.isNestedScrollingEnabled = false
+ hotAdapter?.submitList(it.data?.list)
+ hotAdapter?.isStateViewEnable = true
+ hotAdapter?.setStateViewLayout(
+ this,
+ R.layout.layout_emptyview
+ )
+ hotAdapter?.setOnItemClickListener { adapter, _, position ->
+ val videoListData =
+ adapter.getItem(position) as VideoListDataRes.VideoListData
+ startActivity(
+ Intent(
+ this,
+ PlayerDetailActivity::class.java
+ ).apply {
+ putExtra(
+ Constants.CONSTANTS_short_play_id,
+ videoListData.id
+ )
+ })
+ }
+ } else {
+ toast(getString(R.string.network_error))
+ }
+ binding?.srFree?.finishRefresh()
+ hideLoading()
+ hideNetError()
+ isLoad = true
+ }
+ }
+
+ override fun getViewBinding(): FragmentHotBinding {
+ return FragmentHotBinding.inflate(layoutInflater)
+ }
+
+ override fun onRetry() {
+ super.onRetry()
+ singleClick {
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.freeMoreVideo()
+ } else {
+ toast(getString(R.string.example_no_network))
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/HotAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/HotAdapter.kt
new file mode 100644
index 0000000..8df86d9
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/HotAdapter.kt
@@ -0,0 +1,62 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.widget.AppCompatTextView
+import com.bumptech.glide.Glide
+import com.chad.library.adapter4.BaseQuickAdapter
+import com.chad.library.adapter4.viewholder.QuickViewHolder
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.data.VideoListDataRes
+import com.jia.er.nebuluxe.app.ui.PosterStyleImageView
+
+class HotAdapter :
+ BaseQuickAdapter() {
+ override fun onBindViewHolder(
+ holder: QuickViewHolder,
+ position: Int,
+ item: VideoListDataRes.VideoListData?
+ ) {
+ val posterView = holder.getView(R.id.iv_hot)
+ posterView.loadImage(
+ url = item?.image_url.toString(),
+ placeholderRes = R.drawable.iv_placeholder_v,
+ errorRes = R.drawable.iv_placeholder_v
+ )
+ if (0 == position) {
+ holder.setGone(R.id.iv_top, false)
+ posterView.apply {
+ // 顶部倾斜程度(左侧更低)
+ setTopSlantOffsetDp(25f)
+
+ // 左上小圆角,其他正常
+ setTopLeftShortStyle(topLeftDp = 12f, otherDp = 18f)
+
+ // 如果还需更贴合
+ setCornerRadiiDp(12f, 18f, 18f, 18f)
+ }
+ } else {
+ holder.setGone(R.id.iv_top, true)
+ posterView.apply {
+ // 顶部倾斜程度(左侧更低)
+ setTopSlantOffsetDp(0f)
+
+ // 左上小圆角,其他正常
+ setTopLeftShortStyle(topLeftDp = 18f, otherDp = 18f)
+ // 如果还需更贴合
+ setCornerRadiiDp(18f, 18f, 18f, 18f)
+ }
+ }
+
+
+ }
+
+ override fun onCreateViewHolder(
+ context: Context,
+ parent: ViewGroup,
+ viewType: Int
+ ): QuickViewHolder {
+ return QuickViewHolder(R.layout.item_hot, parent)
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/RankActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/RankActivity.kt
new file mode 100644
index 0000000..3437f24
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/RankActivity.kt
@@ -0,0 +1,83 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Intent
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.blankj.utilcode.util.NetworkUtils
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseActivity
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.data.HomeRankingRes
+import com.jia.er.nebuluxe.app.databinding.ActivityRankingsBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.singleClick
+import com.jia.er.nebuluxe.app.utils.toast
+import com.jia.er.nebuluxe.app.video.PlayerDetailActivity
+
+
+class RankActivity : BaseActivity() {
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+ private var type = "most_trending"
+
+ override fun top() {
+ binding?.exampleIvBack?.setOnClickListener { finish() }
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.homeRanking(type)
+ } else {
+ showNetError()
+ }
+ binding.srRank.setOnRefreshListener {
+ mViewModel.homeRanking(type)
+ }
+ }
+
+ override fun center() {
+ mViewModel.homeRankingData.observe(this) {
+ if (it != null) {
+ if (it.data?.list?.isNotEmpty() == true) {
+ val homeRankTrendingAdapter = RankAdapter()
+ val manager1 = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
+ binding?.rvRanks?.layoutManager = manager1
+ binding?.rvRanks?.adapter = homeRankTrendingAdapter
+ homeRankTrendingAdapter?.submitList(it.data.list)
+ homeRankTrendingAdapter?.isStateViewEnable = true
+ homeRankTrendingAdapter?.setStateViewLayout(this, R.layout.layout_emptyview)
+ homeRankTrendingAdapter?.setOnItemClickListener { adapter, view, position ->
+ val data = adapter.getItem(position) as HomeRankingRes.Item7
+ startActivity(Intent(
+ this, PlayerDetailActivity::class.java
+ ).apply {
+ putExtra(
+ Constants.CONSTANTS_short_play_id, data.short_play_id
+ )
+ })
+ }
+ }
+ binding.srRank.finishRefresh()
+ hideNetError()
+ hideLoading()
+ } else {
+ showNetError()
+ toast(getString(R.string.network_error))
+ hideLoading()
+ }
+ }
+ }
+
+ override fun getViewBinding(): ActivityRankingsBinding {
+ return ActivityRankingsBinding.inflate(layoutInflater)
+ }
+
+ override fun onRetry() {
+ super.onRetry()
+ singleClick {
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.homeRanking(type)
+ } else {
+ toast(getString(R.string.example_no_network))
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/RankAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/RankAdapter.kt
new file mode 100644
index 0000000..23549a0
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/RankAdapter.kt
@@ -0,0 +1,95 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Context
+import android.graphics.Color
+import android.view.ViewGroup
+import androidx.appcompat.widget.AppCompatTextView
+import com.bumptech.glide.Glide
+import com.chad.library.adapter4.BaseQuickAdapter
+import com.chad.library.adapter4.fullspan.FullSpanAdapterType
+import com.chad.library.adapter4.viewholder.QuickViewHolder
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.data.HomeRankingRes
+import com.jia.er.nebuluxe.app.utils.formatNumberByLong
+
+class RankAdapter :
+ BaseQuickAdapter(),
+ FullSpanAdapterType {
+ override fun onBindViewHolder(
+ holder: QuickViewHolder,
+ position: Int,
+ item: HomeRankingRes.Item7?
+ ) {
+ Glide.with(context).load(item?.image_url).placeholder(R.drawable.iv_placeholder_v)
+ .into(holder.getView(R.id.iv_cover))
+ holder.setText(R.id.tv_rank_name, item?.name)
+ holder.setText(R.id.tv_des, item?.description)
+ if (item?.category?.isNotEmpty() == true) {
+ val string = item.category[0]
+ holder.setText(R.id.tv_rank_tag, string)
+ holder.setVisible(R.id.tv_rank_tag, true)
+ } else {
+ holder.setVisible(R.id.tv_rank_tag, false)
+ }
+ val view = holder.getView(R.id.tv_rank_watch)
+ holder.setText(R.id.tv_num, (position + 1).toString())
+ when (position) {
+ 0 -> {
+ holder.setBackgroundResource(R.id.tv_num, R.drawable.bg_rank_1)
+ holder.setTextColor(R.id.tv_num,Color.parseColor("#4F2500"))
+ holder.setTextColor(R.id.tv_rank_tag,Color.parseColor("#FFE8C4"))
+ view?.setCompoundDrawablesWithIntrinsicBounds(
+ context?.getDrawable(R.drawable.iv_item_rank_heat),
+ null,
+ null,
+ null
+ )
+ }
+
+ 1 -> {
+ holder.setBackgroundResource(R.id.tv_num, R.drawable.bg_rank_2)
+ holder.setTextColor(R.id.tv_num,Color.parseColor("#424242"))
+ holder.setTextColor(R.id.tv_rank_tag,Color.parseColor("#FFE8C4"))
+ view?.setCompoundDrawablesWithIntrinsicBounds(
+ context?.getDrawable(R.drawable.iv_item_rank_heat),
+ null,
+ null,
+ null
+ )
+ }
+
+ 2 -> {
+ holder.setBackgroundResource(R.id.tv_num, R.drawable.bg_rank_3)
+ holder.setTextColor(R.id.tv_num,Color.parseColor("#79471B"))
+ holder.setTextColor(R.id.tv_rank_tag,Color.parseColor("#FFE8C4"))
+ view?.setCompoundDrawablesWithIntrinsicBounds(
+ context?.getDrawable(R.drawable.iv_item_rank_heat),
+ null,
+ null,
+ null
+ )
+ }
+
+ else -> {
+ holder.setBackgroundResource(R.id.tv_num, R.drawable.bg_rank_other)
+ holder.setTextColor(R.id.tv_num,Color.parseColor("#0F0F0F"))
+ holder.setTextColor(R.id.tv_rank_tag,Color.parseColor("#F0C2E1"))
+ view?.setCompoundDrawablesWithIntrinsicBounds(
+ context?.getDrawable(R.drawable.iv_item_rank_heat_1),
+ null,
+ null,
+ null
+ )
+ }
+ }
+ holder.setText(R.id.tv_rank_watch, item?.watch_total?.let { formatNumberByLong(it) })
+ }
+
+ override fun onCreateViewHolder(
+ context: Context,
+ parent: ViewGroup,
+ viewType: Int
+ ): QuickViewHolder {
+ return QuickViewHolder(R.layout.item_ranks, parent)
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/ReelsFragment.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/ReelsFragment.kt
new file mode 100644
index 0000000..8837a21
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/ReelsFragment.kt
@@ -0,0 +1,464 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.annotation.SuppressLint
+import android.graphics.Color
+import android.net.Uri
+import android.text.SpannableStringBuilder
+import android.view.View
+import android.view.WindowManager
+import android.widget.FrameLayout
+import android.widget.SeekBar
+import androidx.appcompat.widget.AppCompatImageView
+import androidx.appcompat.widget.AppCompatSeekBar
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import androidx.media3.common.MediaItem
+import androidx.media3.common.PlaybackException
+import androidx.media3.common.Player
+import androidx.media3.datasource.DataSource
+import androidx.media3.datasource.DefaultDataSourceFactory
+import androidx.media3.exoplayer.DefaultRenderersFactory
+import androidx.media3.exoplayer.ExoPlayer
+import androidx.media3.exoplayer.hls.HlsMediaSource
+import androidx.media3.exoplayer.source.MediaSource
+import androidx.media3.exoplayer.source.ProgressiveMediaSource
+import androidx.media3.ui.PlayerView
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.PagerSnapHelper
+import androidx.recyclerview.widget.RecyclerView
+import com.jia.er.nebuluxe.app.data.RecommendDataRes
+import com.jia.er.nebuluxe.app.ui.FfmpegRenderersFactory
+import com.jia.er.nebuluxe.app.ui.LoadingLine
+import com.jia.er.nebuluxe.app.ui.OnSnapHelperCurrentListener
+import com.jia.er.nebuluxe.app.ui.RecyclerViewScrollerDetection
+import com.blankj.utilcode.util.NetworkUtils
+import com.blankj.utilcode.util.ViewUtils
+import com.bumptech.glide.Glide
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseFragment
+import com.jia.er.nebuluxe.app.databinding.FragmentReelsBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.appendWithStyle
+import com.jia.er.nebuluxe.app.utils.formatTimestamp
+import com.jia.er.nebuluxe.app.utils.singleClick
+import com.jia.er.nebuluxe.app.utils.toast
+import com.jia.er.nebuluxe.app.utils.DialogUtils
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+@SuppressLint("UnsafeOptInUsageError")
+class ReelsFragment : BaseFragment(),
+ OnSnapHelperCurrentListener {
+ private var builder: ExoPlayer.Builder? = null
+ private var player: ExoPlayer? = null
+ private val pagerSnapHelper = PagerSnapHelper()
+ private val recyclerViewScrollerDetection = RecyclerViewScrollerDetection()
+ private var homeForYouAdapter: HomeForYouAdapter? = null
+ private var playerView: PlayerView? = null
+ private var currentView: View? = null
+ private var loadingLine: LoadingLine? = null
+ private var tvName: AppCompatTextView? = null
+ private var tvTime: AppCompatTextView? = null
+ private var play: AppCompatImageView? = null
+ private var collection: AppCompatImageView? = null
+ private var ivIconPlayer: AppCompatImageView? = null
+ private var ivCover: AppCompatImageView? = null
+ private var exampleSeekbarPlayerController: AppCompatSeekBar? = null
+ private var exampleProgressJob: Job? = null
+ private var isDragging = false
+ private var isPlaying = false
+ private var currentPage = 1
+ private val currentSize = 10
+ private var dataRes: RecommendDataRes.Data? = null
+ private var currentPosition = 0
+ private var tvEpTotal: AppCompatTextView? = null
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+ private var isCanPlay = false
+
+ override fun top() {
+ activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+ builder = ExoPlayer.Builder(requireContext(), FfmpegRenderersFactory(requireContext()))
+ .setRenderersFactory(
+ DefaultRenderersFactory(requireContext()).setEnableDecoderFallback(
+ true
+ )
+ )
+ player = builder?.build()
+ playerView = ViewUtils.layoutId2View(R.layout.include_player_view) as PlayerView
+ playerView?.player = player
+ loadingLine = playerView?.findViewById(R.id.load_line)
+ tvName = playerView?.findViewById(R.id.example_tv_title_player_controller)
+ tvTime = playerView?.findViewById(R.id.tv_player_seek_time)
+ tvEpTotal = playerView?.findViewById(R.id.tv_ep_total)
+ play = playerView?.findViewById(R.id.example_iv_play_player_controller)
+ collection = playerView?.findViewById(R.id.example_iv_collection_controller)
+ ivIconPlayer = playerView?.findViewById(R.id.iv_icon_player)
+ exampleSeekbarPlayerController =
+ playerView?.findViewById(R.id.example_seekBar_player_controller)
+ play?.setOnClickListener {
+ singleClick {
+ if (isPlaying) {
+ pause()
+ } else {
+ play()
+ }
+ }
+ }
+ player?.addListener(object : Player.Listener {
+ override fun onPlaybackStateChanged(playbackState: Int) {
+ super.onPlaybackStateChanged(playbackState)
+ when (playbackState) {
+ Player.STATE_BUFFERING -> {
+ if (!isHidden) {
+ ivIconPlayer?.visibility = View.VISIBLE
+ loadingLine?.visibility = View.VISIBLE
+ loadingLine?.postDelayed({ loadingLine?.startAnimation() }, 200)
+ }
+ }
+
+ Player.STATE_READY -> {
+ if (isCanPlay) {
+ canPlay()
+ }
+ }
+
+ Player.STATE_ENDED -> {
+ val plus = currentPosition.plus(1)
+ binding.rvRecommend.smoothScrollToPosition(plus)
+ }
+
+ Player.STATE_IDLE -> {
+ }
+ }
+ }
+
+ override fun onPlayerError(error: PlaybackException) {
+ super.onPlayerError(error)
+
+ }
+ })
+ collection?.setOnClickListener {
+ singleClick {
+ if (dataRes?.is_collect == true) {
+ dataRes?.video_info?.short_play_id?.let { it1 ->
+ dataRes?.video_info?.short_play_video_id?.let { it2 ->
+ DialogUtils.unFavoriteDialog(
+ requireContext(),
+ it1, it2, mViewModel
+ )
+ }
+ }
+ } else {
+ dataRes?.video_info?.short_play_id?.let {
+ dataRes?.video_info?.short_play_video_id.let { it1 ->
+ if (it1 != null) {
+ mViewModel.doCollect(
+ it, it1
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+ binding.srFy.apply {
+ setOnRefreshListener {
+ recyclerViewScrollerDetection.isFirstAttached = false
+ player?.stop()
+ mViewModel.getRecommands(currentPage, currentSize, "")
+ }
+ }
+ binding.rvRecommend.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+
+ var isSlidingUp = false
+
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+
+ isSlidingUp = dy > 0
+ }
+
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ super.onScrollStateChanged(recyclerView, newState)
+
+ val layoutManager = recyclerView.layoutManager as LinearLayoutManager
+ val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
+ val totalItemCount = layoutManager.itemCount
+
+ if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+ if (isSlidingUp &&
+ lastVisibleItemPosition == totalItemCount - 1
+ ) {
+ currentPage++
+ mViewModel.getRecommands(currentPage, currentSize, "")
+ }
+ }
+ }
+ })
+ exampleSeekbarPlayerController?.setOnSeekBarChangeListener(object :
+ SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(
+ seekBar: SeekBar?,
+ progress: Int,
+ fromUser: Boolean
+ ) {
+ if (fromUser) {
+ seekTo(progress)
+ }
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {
+ tvTime?.visibility = FrameLayout.VISIBLE
+ isDragging = true
+ }
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {
+ isDragging = false
+ tvTime?.visibility = FrameLayout.INVISIBLE
+ }
+ })
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.getRecommands(currentPage, currentSize, "")
+ } else {
+ showNetError()
+ }
+ }
+
+ private fun setProgress() {
+ exampleProgressJob?.cancel()
+ val duration = player!!.duration
+ exampleSeekbarPlayerController?.max = duration.toInt()
+ exampleSeekbarPlayerController?.progress = player!!.currentPosition.toInt()
+ exampleProgressJob = lifecycleScope.launch {
+ while (isActive) {
+ if (!isDragging) {
+ withContext(Dispatchers.Main) {
+ exampleSeekbarPlayerController?.progress =
+ player!!.currentPosition.toInt()
+ }
+ }
+ delay(1000)
+ }
+ }
+ }
+
+ fun play() {
+ player?.play()
+ play?.setImageResource(R.drawable.iv_example_stop)
+ isPlaying = true
+ isDragging = false
+ }
+
+ fun pause() {
+ player?.pause()
+ play?.setImageResource(R.drawable.iv_example_play)
+ isPlaying = false
+ isDragging = true
+ }
+
+ private fun seekTo(progress: Int) {
+ player?.seekTo(progress.toLong())
+ seekTime()
+ }
+
+ private fun seekTime() {
+ val currentPosition = player!!.currentPosition
+ val currentTime = formatTimestamp(currentPosition / 1000)
+ val totalDuration = player!!.duration
+ val totalTime = formatTimestamp(totalDuration / 1000)
+ tvTime?.text = "$currentTime/$totalTime"
+ }
+
+ override fun center() {
+ mViewModel.recommendData.observe(this) {
+ if (it != null) {
+ if (it.data?.list?.isNotEmpty() == true) {
+ if (currentPage == 1) {
+ homeForYouAdapter = HomeForYouAdapter()
+ val layoutManager =
+ LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
+ binding?.rvRecommend?.layoutManager = layoutManager
+ binding?.rvRecommend?.adapter = homeForYouAdapter
+ binding?.rvRecommend?.isNestedScrollingEnabled = false
+ pagerSnapHelper.attachToRecyclerView(binding?.rvRecommend)
+ recyclerViewScrollerDetection.setCurrentListener(this)
+ recyclerViewScrollerDetection.attachToSnapHelper(pagerSnapHelper)
+ binding?.rvRecommend?.let { it1 ->
+ recyclerViewScrollerDetection.addOnScrollListener(
+ it1
+ )
+ }
+ it.data?.list?.forEach { item ->
+ Glide.with(requireContext()).load(item.image_url).preload()
+ }
+ homeForYouAdapter?.submitList(it.data.list)
+ } else {
+ homeForYouAdapter?.addAll(it.data.list)
+ }
+ hideLoading()
+ } else {
+ toast(getString(R.string.no_more_data))
+ }
+ hideNetError()
+ } else {
+ toast(getString(R.string.network_error))
+ hideLoading()
+ }
+ binding.srFy.finishRefresh()
+ }
+
+ mViewModel.collectData.observe(this) {
+ if (it != null) {
+ collection?.setImageResource(R.drawable.iv_example_collection_h)
+ dataRes?.collect_total = dataRes?.collect_total?.plus(1)
+ homeForYouAdapter?.getItem(currentPosition)?.is_collect = true
+ homeForYouAdapter?.getItem(currentPosition)?.collect_total =
+ dataRes?.collect_total
+ toast(getString(R.string.success))
+ } else {
+ toast(getString(R.string.network_error))
+ }
+ }
+ mViewModel.cancelCollectData.observe(this) {
+ if (it != null) {
+ collection?.setImageResource(R.drawable.iv_example_collection_n)
+ dataRes?.collect_total = dataRes?.collect_total?.minus(1)
+ homeForYouAdapter?.getItem(currentPosition)?.is_collect = false
+ homeForYouAdapter?.getItem(currentPosition)?.collect_total =
+ dataRes?.collect_total
+ toast(getString(R.string.success))
+ } else {
+ toast(getString(R.string.network_error))
+ }
+ }
+ }
+
+ private fun buildMediaSource(videoPath: String): MediaSource {
+ val dataSourceFactory: DataSource.Factory =
+ DefaultDataSourceFactory(requireContext(), "loopdrama")
+
+ return if (videoPath.endsWith(".m3u8")) {
+ HlsMediaSource.Factory(dataSourceFactory)
+ .createMediaSource(MediaItem.fromUri(Uri.parse(videoPath)))
+ } else {
+ ProgressiveMediaSource.Factory(dataSourceFactory)
+ .createMediaSource(MediaItem.fromUri(Uri.parse(videoPath)))
+ }
+ }
+
+ override fun getViewBinding(): FragmentReelsBinding {
+ return FragmentReelsBinding.inflate(layoutInflater)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ isCanPlay = false
+ binding.root.postDelayed({ pause() }, 300)
+ }
+
+
+ override fun onResume() {
+ super.onResume()
+ if (isVisible) {
+ isCanPlay = true
+ canPlay()
+ }
+ }
+
+ @SuppressLint("UnsafeOptInUsageError")
+ override fun setActive(
+ currentView: View?, position: Int, previousView: View?, previousPosition: Int
+ ) {
+ isCanPlay = true
+ currentPosition = position
+ this.currentView = currentView
+ val frameLayout = currentView?.findViewById(R.id.video)
+ (playerView?.parent as FrameLayout?)?.removeView(playerView)
+ frameLayout?.removeAllViews()
+ frameLayout?.addView(playerView)
+ playerView?.showController()
+ dataRes = homeForYouAdapter?.getItem(position)
+ dataRes?.video_info?.video_url?.let { buildMediaSource(it) }
+ ?.let { player?.setMediaSource(it) }
+ player?.prepare()
+ setUI()
+ }
+
+ private fun setUI() {
+ ivIconPlayer?.let { it1 ->
+ Glide.with(this).load(dataRes?.image_url).into(it1)
+ }
+ tvName?.text = dataRes?.name
+ val builder = SpannableStringBuilder()
+ builder.appendWithStyle(
+ "Ep.".plus(dataRes?.video_info?.episode),
+ Color.parseColor("#50FFFFFF"),
+ isBold = true
+ )
+ .appendWithStyle(
+ "/Ep.".plus(dataRes?.episode_total),
+ Color.parseColor("#50FFFFFF"),
+ isBold = false
+ )
+ tvEpTotal?.text = builder
+ collection?.setImageResource(if (dataRes?.is_collect == true) R.drawable.iv_example_collection_h else R.drawable.iv_example_collection_n)
+ }
+
+ override fun disActive(detachedView: View?, detachedPosition: Int) {
+ if (null == detachedView) return
+ ivCover = detachedView.findViewById(R.id.iv_icon)
+ ivCover?.visibility = View.VISIBLE
+ if (player?.isPlaying == true) {
+ pause()
+ }
+ }
+
+ override fun onHiddenChanged(hidden: Boolean) {
+ super.onHiddenChanged(hidden)
+ if (hidden) {
+ isCanPlay = false
+ binding.root.postDelayed({ pause() }, 200)
+ activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+ } else {
+ isCanPlay = true
+ canPlay()
+ activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+ }
+ }
+
+ private fun canPlay() {
+ loadingLine?.endAnimation()
+ loadingLine?.visibility = View.INVISIBLE
+ ivCover = currentView?.findViewById(R.id.iv_icon)
+ ivCover?.visibility = View.INVISIBLE
+ ivIconPlayer?.visibility = View.INVISIBLE
+ play()
+ setProgress()
+ }
+
+ override fun onRetry() {
+ super.onRetry()
+ singleClick {
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ mViewModel.getRecommands(currentPage, currentSize, "")
+ } else {
+ toast(getString(R.string.example_no_network))
+ }
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ player?.stop()
+ player?.release()
+ recyclerViewScrollerDetection.detachToSnapHelper()
+ }
+
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/SavedFragment.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/SavedFragment.kt
new file mode 100644
index 0000000..df6caf7
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/SavedFragment.kt
@@ -0,0 +1,142 @@
+package com.jia.er.nebuluxe.app.home
+
+import android.content.Intent
+import androidx.lifecycle.ViewModelProvider
+import com.jia.er.nebuluxe.app.data.CollectionRes
+import com.blankj.utilcode.util.NetworkUtils
+import com.chad.library.adapter4.layoutmanager.QuickGridLayoutManager
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseFragment
+import com.jia.er.nebuluxe.app.databinding.FragmentSavedBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.singleClick
+import com.jia.er.nebuluxe.app.utils.toast
+
+class SavedFragment : BaseFragment() {
+ private var page: Int = 1
+// private var myListAdapter: MyListAdapter? = null
+ private var edit = false
+ private var current: Int = 0
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+ override fun top() {
+// if (NetworkUtils.isConnected()) {
+// showLoading()
+// mViewModel.getCollections(page)
+// } else {
+// showNetError()
+// }
+// binding?.srMyList?.setOnRefreshListener {
+// page = 1
+// mViewModel.getCollections(page)
+// }
+// binding?.srMyList?.setOnLoadMoreListener {
+// page++
+// mViewModel.getCollections(page)
+// }
+// binding?.exampleIvEditMyFavorites?.setOnClickListener {
+// if (!edit) {
+// edit = true
+// binding?.exampleIvEditMyFavorites?.setImageResource(R.drawable.iv_edit_favorites_complete)
+// myListAdapter?.eidt = true
+// binding?.tvTitle?.text = "Delete"
+// binding.tvTitle.background = context?.getDrawable(R.drawable.iv_list_title_bg_h)
+// myListAdapter?.notifyDataSetChanged()
+// } else {
+// edit = false
+// binding?.exampleIvEditMyFavorites?.setImageResource(R.drawable.iv_edit_favorites)
+// binding.tvTitle.background = context?.getDrawable(R.drawable.iv_list_title_bg)
+// myListAdapter?.eidt = false
+// binding?.tvTitle?.text = "Favorites"
+// myListAdapter?.notifyDataSetChanged()
+// }
+// }
+// binding.ivHis.setOnClickListener {
+// startActivity(
+// Intent(
+// requireContext(),
+// HistoryActivity::class.java
+// ))
+// }
+ }
+
+ override fun center() {
+// mViewModel.collectionsData.observe(this) {
+// if (it != null) {
+// if (page == 1) {
+// myListAdapter = MyListAdapter()
+// val manager = QuickGridLayoutManager(requireContext(), 3)
+// binding?.rvMyList?.layoutManager = manager
+// binding?.rvMyList?.adapter = myListAdapter
+// myListAdapter?.submitList(it.data?.list)
+// myListAdapter?.isStateViewEnable = true
+// myListAdapter?.setStateViewLayout(requireContext(), R.layout.layout_emptyview)
+// myListAdapter?.addOnItemChildClickListener(R.id.iv_favorites_delete) { adapter, view, position ->
+// current = position
+// val collectionData =
+// adapter.getItem(position) as CollectionRes.CollectionData
+// DialogUtils.unFavoriteDialog(
+// requireContext(),
+// collectionData.short_play_id,
+// collectionData.short_play_video_id,
+// mViewModel
+// )
+// }
+// myListAdapter?.setOnItemClickListener { adapter, view, position ->
+// val data = adapter.getItem(position) as CollectionRes.CollectionData
+// startActivity(
+// Intent(
+// requireContext(),
+// PlayerDetailActivity::class.java
+// ).apply {
+// putExtra(
+// Constants.CONSTANTS_short_play_id,
+// data.short_play_id
+// )
+// })
+// }
+// } else {
+// if (it.data?.list?.isNotEmpty() == true) {
+// myListAdapter?.addAll(it.data.list)
+// } else {
+// toast(getString(R.string.no_more_data))
+// }
+// }
+// hideLoading()
+// hideNetError()
+// } else {
+// hideLoading()
+// toast(getString(R.string.network_error))
+// }
+// binding?.srMyList?.finishRefresh()
+// binding?.srMyList?.finishLoadMore()
+// }
+//
+// mViewModel.cancelCollectData.observe(this) {
+// if (it != null) {
+// toast(getString(R.string.success))
+// myListAdapter?.removeAt(current)
+// myListAdapter?.notifyDataSetChanged()
+// } else {
+// toast(getString(R.string.network_error))
+// }
+// }
+ }
+
+ override fun getViewBinding(): FragmentSavedBinding {
+ return FragmentSavedBinding.inflate(layoutInflater)
+ }
+
+ override fun onRetry() {
+ super.onRetry()
+ singleClick {
+ if (NetworkUtils.isConnected()) {
+ showLoading()
+ page = 1
+ mViewModel.getCollections(page)
+ } else {
+ toast(getString(R.string.example_no_network))
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/main/MainActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/main/MainActivity.kt
new file mode 100644
index 0000000..ac505b8
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/main/MainActivity.kt
@@ -0,0 +1,705 @@
+package com.jia.er.nebuluxe.app.main
+
+import android.view.KeyEvent
+import androidx.fragment.app.FragmentTransaction
+import androidx.lifecycle.ViewModelProvider
+import com.jia.er.nebuluxe.app.home.HomeFragment
+import com.jia.er.nebuluxe.app.home.ReelsFragment
+import com.jia.er.nebuluxe.app.home.SavedFragment
+import com.flyco.tablayout.listener.CustomTabEntity
+import com.flyco.tablayout.listener.OnTabSelectListener
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseActivity
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.data.TabEntity
+import com.jia.er.nebuluxe.app.databinding.ActivityMainBinding
+import com.jia.er.nebuluxe.app.me.MeFragment
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.Memory
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+
+class MainActivity : BaseActivity() {
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+
+ private var titles = arrayOf(
+ "",
+ "",
+ "",
+ ""
+ )
+ private val iconUnSelectIds by lazy {
+ intArrayOf(
+ R.drawable.iv_home_n,
+ R.drawable.iv_reels_n,
+ R.drawable.iv_saved_n,
+ R.drawable.iv_me_n
+ )
+ }
+ private val iconSelectIds by lazy {
+ intArrayOf(
+ R.drawable.iv_home_h,
+ R.drawable.iv_reels_h,
+ R.drawable.iv_saved_h,
+ R.drawable.iv_me_h
+ )
+ }
+ private val tabEntities = ArrayList()
+ private var homeFragment: HomeFragment? = null
+ private var reelsFragment: ReelsFragment? = null
+ private var myListFragment: SavedFragment? = null
+ private var meFragment: MeFragment? = null
+ private var index = 0
+ private var shortVideoId: Int = 0
+// private var notificationDialog: NotificationDialog? = null
+// private var path = ""
+// private var short_play_id = ""
+// private var message_id = ""
+// private var title = ""
+// private var scheduler: ScheduledExecutorService? = Executors.newSingleThreadScheduledExecutor()
+// private val scope = CoroutineScope(Dispatchers.Main)
+
+// override fun onNewIntent(intent: Intent?) {
+// super.onNewIntent(intent)
+// val webpageURL = intent?.data
+// uploadDDL(webpageURL)
+// path = intent?.getStringExtra("path").toString()
+// short_play_id = intent?.getStringExtra("short_play_id").toString()
+// message_id = intent?.getStringExtra("message_id").toString()
+// title = intent?.getStringExtra("title").toString()
+// notificationGo()
+// }
+
+ override fun top() {
+// val webpageURL = intent.data
+// uploadDDL(webpageURL)
+// path = intent?.getStringExtra("path").toString()
+// short_play_id = intent?.getStringExtra("short_play_id").toString()
+// message_id = intent?.getStringExtra("message_id").toString()
+// title = intent?.getStringExtra("title").toString()
+ showLoading()
+ EventBus.getDefault().register(this)
+ (titles.indices).mapTo(tabEntities) {
+ TabEntity(
+ titles[it], iconSelectIds[it], iconUnSelectIds[it]
+ )
+ }
+ binding.tabLayout.setTabData(tabEntities)
+ binding?.tabLayout?.setOnTabSelectListener(object : OnTabSelectListener {
+ override fun onTabSelect(position: Int) {
+ switchFragment(position)
+// when (position) {
+// 0 -> {
+// binding?.dialogHistory?.root?.postDelayed(
+// {
+// val string = Memory.getMMKV()
+// .getString(Constants.Constants_Main_Video_info, "")
+// if (string?.isNotEmpty() == true && NetworkUtils.isConnected()) {
+// val fromJson = Gson().fromJson(string, MainDataHis::class.java)
+// showHistoryDialog(fromJson)
+// }
+// }, 500
+// )
+// }
+//
+// else -> {
+// binding?.dialogHistory?.root?.visibility = View.INVISIBLE
+// }
+// }
+ }
+
+ override fun onTabReselect(position: Int) {
+
+ }
+ })
+// Constants.CanNotification = NotificationUtils.isNotificationEnabled(this)
+// mViewModel.uploadNoticeStatus(
+// FbNotificationReq(
+// if (Constants.CanNotification) "1" else "0"
+// )
+// )
+ mViewModel.getInfo()
+ switchFragment(index)
+// GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(this)
+// .addOnCompleteListener {
+// if (it.isSuccessful) {
+// askNotificationPermission()
+// }
+// }
+// binding?.root?.postDelayed({ notificationGo() }, 700)
+// mViewModel.enterTheApp()
+// val intervalMillis = 10 * 60 * 1000
+// scheduler?.scheduleWithFixedDelay({
+// try {
+// lifecycleScope.launch {
+// mViewModel.onLine()
+// }
+// } catch (e: Exception) {
+// e.printStackTrace()
+// }
+// }, 0, intervalMillis.toLong(), TimeUnit.MILLISECONDS)
+// binding?.root?.postDelayed({
+// if (Memory.getOrder().isNotEmpty()) {
+// val string = Memory.getOrder()
+// scope.launch {
+// flow {
+// for (item in string) {
+// emit(item)
+// }
+// }.onEach { item ->
+// upError(
+// "pay restore",
+// mViewModel,
+// "restore",
+// "pay_restore",
+// "auto", GsonUtils.toJson(item), 0, 0
+// )
+// mViewModel.restorePaid(item)
+// }.debounce(1000).collect {}
+// }
+// }
+// }, 3000)
+ }
+
+ override fun center() {
+// mViewModel.restorePaidData.observe(this) {
+// if (it != null) {
+// it.data?.order_code?.let { it1 -> Memory.removeOrderString(it1) }
+// }
+// }
+ mViewModel.infoData.observe(this) {
+ if (it != null) {
+ it.data?.let { it1 ->
+ Memory.saveUserInfo(it1)
+ }
+ }
+ }
+ mViewModel.userRegisterData.observe(this) {
+ if (it != null) {
+ Memory.getMMKV()
+ .putString(Constants.CONSTANTS_AuthorizationExample, it.data?.token)
+ EventBus.getDefault().post(Constants.CONSTANTS_refresh_me)
+ }
+ }
+// mViewModel.loginData.observe(this) {
+// if (it != null) {
+// toast(getString(R.string.success))
+// Memory.getMMKV()
+// .putString(Constants.CONSTANTS_AuthorizationExample, it.data?.token)
+// EventBus.getDefault()
+// .post(Constants.CONSTANTS_enterTheApp)
+// EventBus.getDefault()
+// .post(Constants.CONSTANTS_onLine)
+// mViewModel.getInfo()
+// EventBus.getDefault()
+// .post(Constants.CONSTANTS_refresh_me)
+// hideLoading()
+// loginDialog?.dismiss()
+// } else {
+// hideLoading()
+// toast(getString(R.string.network_error))
+// }
+// }
+ }
+
+// override fun onResume() {
+// super.onResume()
+// if (index == 0) {
+// binding?.dialogHistory?.root?.postDelayed(
+// {
+// val string = Memory.getMMKV()
+// .getString(Constants.Constants_Main_Video_info, "")
+// if (string?.isNotEmpty() == true && NetworkUtils.isConnected()) {
+// val fromJson = Gson().fromJson(string, MainDataHis::class.java)
+// showHistoryDialog(fromJson)
+// }
+// }, 500
+// )
+// }
+// }
+
+// private fun showHistoryDialog(data: MainDataHis) {
+// binding?.dialogHistory?.ivCloseHistory?.setOnClickListener {
+// Memory.getMMKV()
+// .putBoolean(Constants.Constants_Main_Video_status, false)
+// binding?.dialogHistory?.root?.visibility = View.INVISIBLE
+// }
+// if (Memory.getMMKV()
+// .getBoolean(Constants.Constants_Main_Video_status, false)
+// ) {
+// binding?.dialogHistory?.ivVideo?.let {
+// if (!isFinishing && !isDestroyed) {
+// Glide.with(this).load(
+// data.video_img
+// ).placeholder(R.drawable.iv_placeholder_v).into(it)
+// }
+// }
+// binding?.dialogHistory?.cl?.setOnClickListener {
+// singleClick {
+// startActivity(
+// Intent(
+// this, PlayerDetailActivity::class.java
+// ).apply {
+// putExtra(
+// Constants.CONSTANTS_short_play_id, data.video_id
+// )
+// })
+// }
+// }
+// binding?.dialogHistory?.root?.post {
+// binding?.dialogHistory?.tvEp?.text =
+// "Ep.".plus(data.video_last).plus("/").plus("Ep.").plus(data.episode_total)
+// }
+// binding?.dialogHistory?.root?.visibility = View.VISIBLE
+// }
+// }
+//
+// private fun askNotificationPermission() {
+// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+// if (ContextCompat.checkSelfPermission(
+// this, Manifest.permission.POST_NOTIFICATIONS
+// ) == PackageManager.PERMISSION_GRANTED
+// ) {
+// NotificationUtils.firebase(mViewModel)
+// } else {
+// if (Constants.isUat) {
+// openNotification()
+// } else {
+// if (shouldShowNotification()) {
+// openNotification()
+// }
+// }
+// }
+// } else {
+// if (NotificationUtils.isNotificationEnabled(this)) {
+// NotificationUtils.firebase(mViewModel)
+// } else {
+// if (Constants.isUat) {
+// openNotification()
+// } else {
+// if (shouldShowNotification()) {
+// openNotification()
+// }
+// }
+// }
+// }
+// }
+//
+// private fun openNotification() {
+// notificationDialog = NotificationDialog(this)
+// val example_tv_later =
+// notificationDialog?.findViewById(R.id.example_tv_unfavorite)
+// val iv_close_notification =
+// notificationDialog?.findViewById(R.id.iv_close_notification)
+// val example_open =
+// notificationDialog?.findViewById(R.id.example_tv_think_again)
+// notificationDialog?.setOnDismissListener {
+// Memory.getMMKV().putLong(
+// Constants.CONSTANTS_PREF_LAST_POPUP_TIME_Notification,
+// System.currentTimeMillis()
+// )
+// }
+// example_tv_later?.setOnClickListener { notificationDialog?.dismiss() }
+// iv_close_notification?.setOnClickListener { notificationDialog?.dismiss() }
+// example_open?.setOnClickListener {
+// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+// requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
+// notificationDialog?.dismiss()
+// } else {
+// NotificationUtils.openNotificationSettings(this)
+// notificationDialog?.dismiss()
+// }
+// }
+// notificationDialog?.show()
+// }
+//
+// private val requestPermissionLauncher = registerForActivityResult(
+// ActivityResultContracts.RequestPermission(),
+// ) { isGranted: Boolean ->
+// Constants.CanNotification = isGranted
+// if (isGranted) {
+// NotificationUtils.firebase(mViewModel)
+// mViewModel.uploadNoticeStatus(
+// FbNotificationReq(
+// if (Constants.CanNotification) "1" else "0"
+// )
+// )
+// notificationDialog?.dismiss()
+// } else {
+// NotificationUtils.openNotificationSettings(this)
+// }
+// }
+//
+// override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+// super.onActivityResult(requestCode, resultCode, data)
+// if (index == 0) {
+// if (requestCode == NotificationUtils.NOTIFICATION_SETTINGS_REQUEST_CODE) {
+// Constants.CanNotification =
+// NotificationUtils.isNotificationEnabled(this)
+// if (Constants.CanNotification) {
+// NotificationUtils.firebase(mViewModel)
+// }
+// mViewModel.uploadNoticeStatus(
+// FbNotificationReq(
+// if (Constants.CanNotification) "1" else "0"
+// )
+// )
+// }
+// } else {
+// val fragments: List = supportFragmentManager.fragments
+// if (fragments.isNotEmpty()) {
+// for (fragment in fragments) {
+// if (fragment.isAdded && !fragment.isDetached) {
+// fragment.onActivityResult(requestCode, resultCode, data)
+// }
+// }
+// }
+// }
+// }
+//
+// private fun notificationGo() {
+// if (message_id.isNotBlank() && !message_id.contentEquals("null")) {
+// if ("0" != message_id) {
+// mViewModel.sendReport(message_id, title)
+// }
+// }
+// when (path) {
+// "detail" -> {
+// if (short_play_id.isNotEmpty() && "null" != short_play_id) {
+// try {
+// val toInt = short_play_id.toInt()
+// binding?.root?.postDelayed({
+// startActivity(Intent(
+// this, PlayerDetailActivity::class.java
+// ).apply {
+// putExtra(
+// Constants.CONSTANTS_short_play_id, toInt
+// )
+// })
+// }, 700)
+// } catch (e: Exception) {
+// e.printStackTrace()
+// }
+// }
+// }
+//
+// "orderDetail" -> {
+// binding?.root?.postDelayed({
+// startActivity(
+// Intent(
+// this, StoreActivity::class.java
+// )
+// )
+// }, 500)
+// }
+//
+// "feedback" -> {
+// binding?.root?.postDelayed({
+// if (message_id.isNotBlank() && message_id != "null") {
+// Memory.getMMKV()
+// .putString(Constants.CONSTANTS_Detail_id, message_id)
+// startActivity(
+// Intent(
+// this, FeedBackDetailActivity::class.java
+// )
+// )
+// } else {
+// startActivity(
+// Intent(
+// this, FeedBackListActivity::class.java
+// )
+// )
+// }
+// }, 500)
+// }
+// }
+// }
+//
+//
+// private fun uploadDDL(webpageURL: Uri?) {
+// val ddl = webpageURL.toString()
+// if (ddl.isNotEmpty() && !ddl.contentEquals("null")) {
+// w2aSelfAttribution(ddl)
+// val regex = """short_play_id=(\d+).*""".toRegex()
+// val matchResult = regex.find(ddl)
+// if (matchResult != null) {
+// val shortPlayId = matchResult.groupValues[1]
+// shortVideoId = shortPlayId.toInt()
+// if (shortVideoId != 0) {
+// binding.root.postDelayed({
+// startActivity(
+// Intent(
+// this, PlayerDetailActivity::class.java
+// ).apply {
+// putExtra(
+// Constants.CONSTANTS_short_play_id, shortVideoId
+// )
+// })
+// }, 1000)
+// }
+// Memory.getMMKV()
+// .putString(Constants.Constants_DDL_Url, "")
+// clearClipboardContent(this)
+// }
+// }
+// }
+//
+// fun getClip() {
+// this.window.decorView.post {
+// val clipContent = getClipContent()
+// if (clipContent.isNotEmpty()) {
+// if (clipContent.startsWith("[QJ]")) {
+// val urlString = clipContent.removePrefix("[QJ]").trim()
+// val extractVideoInfo = parseVideoAndShortPlayIds(urlString)
+// if (urlString.contains("reelcrush")) {
+// shortVideoId = extractVideoInfo.second?.toInt() ?: 0
+// w2aSelfAttribution(clipContent)
+// if (shortVideoId != 0) {
+// binding.root.postDelayed({
+// startActivity(
+// Intent(
+// this, PlayerDetailActivity::class.java
+// ).apply {
+// putExtra(
+// Constants.CONSTANTS_short_play_id, shortVideoId
+// )
+// })
+// }, 3000)
+// }
+// Memory.getMMKV()
+// .putString(Constants.Constants_DDL_Url, "")
+// clearClipboardContent(this)
+// }
+// }
+// }
+// }
+// }
+
+ private fun switchFragment(position: Int) {
+ val transaction = supportFragmentManager.beginTransaction()
+ hideFragments(transaction)
+ when (position) {
+ 0 -> homeFragment?.let {
+ transaction.show(it)
+ } ?: HomeFragment().let {
+ homeFragment = it
+ transaction.add(R.id.container, it, "HomeFragment")
+ }
+
+ 1 -> reelsFragment?.let {
+ transaction.show(it)
+ } ?: ReelsFragment().let {
+ reelsFragment = it
+ transaction.add(
+ R.id.container, it, "ReelsFragment"
+ )
+ }
+
+ 2 -> myListFragment?.let {
+ transaction.show(it)
+ } ?: SavedFragment().let {
+ myListFragment = it
+ transaction.add(R.id.container, it, "SavedFragment")
+ }
+
+
+ 3 -> meFragment?.let {
+ transaction.show(it)
+ } ?: MeFragment().let {
+ meFragment = it
+ transaction.add(R.id.container, it, "MeFragment")
+ }
+
+ else -> {
+
+ }
+ }
+
+ index = position
+ binding?.tabLayout?.currentTab = index
+ transaction.commitAllowingStateLoss()
+ }
+
+
+ private fun hideFragments(transaction: FragmentTransaction) {
+ homeFragment?.let { transaction.hide(it) }
+ reelsFragment?.let { transaction.hide(it) }
+ myListFragment?.let { transaction.hide(it) }
+ meFragment?.let { transaction.hide(it) }
+ }
+
+// private fun getClipContent(): String {
+// val manager: ClipboardManager = getSystemService(
+// CLIPBOARD_SERVICE
+// ) as ClipboardManager
+// val primaryClip = manager.primaryClip
+// val itemCount = primaryClip?.itemCount
+// if (itemCount != null) {
+// if (manager.hasPrimaryClip() && itemCount > 0) {
+// val itemAt = manager.primaryClip?.getItemAt(0)
+// val addedText: CharSequence = itemAt?.text.toString()
+// val addedTextString = addedText.toString()
+// if (!TextUtils.isEmpty(addedTextString)) {
+// return addedTextString
+// }
+// }
+// }
+// return ""
+// }
+//
+// private fun w2aSelfAttribution(data: String?) {
+// data?.let { mViewModel.w2aSelfAttribution(it) }
+// }
+//
+// private fun clearClipboardContent(context: Context) {
+// val clipboardManager =
+// context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+//
+// val emptyClip = ClipData.newPlainText("", "")
+//
+// clipboardManager.setPrimaryClip(emptyClip)
+// }
+//
+// private fun parseVideoAndShortPlayIds(clipboardContent: String): Pair {
+//
+// val queryStartIndex = clipboardContent.indexOf('?')
+// val queryString =
+// if (queryStartIndex != -1) clipboardContent.substring(queryStartIndex + 1) else ""
+//
+// val videoIdRegex = Regex("video_id=(\\d+)")
+// val shortPlayIdRegex = Regex("short_play_id=(\\d+)")
+//
+// val videoIdMatch = videoIdRegex.find(queryString)?.groupValues?.get(1)
+// val shortPlayIdMatch = shortPlayIdRegex.find(queryString)?.groupValues?.get(1)
+//
+// return Pair(videoIdMatch, shortPlayIdMatch)
+// }
+
+ override fun getViewBinding(): ActivityMainBinding {
+ return ActivityMainBinding.inflate(layoutInflater)
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEvent(event: String) {
+ if (Constants.CONSTANTS_auth_refresh == event) {
+ mViewModel.createUserAccount()
+ }
+ if (Constants.CONSTANTS_main_stop == event) {
+ binding?.root?.postDelayed({ hideLoading() }, 300)
+ }
+// if (Constants.CONSTANTS_enterTheApp == event) {
+// mViewModel.enterTheApp()
+// }
+// if (Constants.CONSTANTS_leaveApp == event) {
+// mViewModel.leaveApp()
+// }
+// if (Constants.CONSTANTS_onLine == event) {
+// mViewModel.onLine()
+// }
+// if (Constants.Constants_onTokenRefresh == event) {
+// NotificationUtils.firebase(mViewModel)
+// }
+// if (Constants.Constants_getClip == event) {
+// getClip()
+// }
+// if (Constants.CONSTANTS_web_Login == event) {
+// if (!NetworkUtils.isConnected()) {
+// toast(getString(R.string.example_no_network))
+// return
+// }
+// showLogin()
+// }
+ }
+
+// private var callbackManager: CallbackManager? = null
+// private var loginDialog: LoginDialog? = null
+//
+// private fun showLogin() {
+// callbackManager = CallbackManager.Factory.create()
+// LoginManager.getInstance().registerCallback(callbackManager,
+// object : FacebookCallback {
+// override fun onSuccess(loginResult: LoginResult) {
+// val enableButtons = AccessToken.getCurrentAccessToken() != null
+// if (enableButtons) {
+// val mGraphRequest = GraphRequest.newMeRequest(
+// loginResult.accessToken
+// ) { jsonObject, response ->
+// if (response!!.error != null) {
+// toast("Facebook login exception.${response.error?.exception.toString()}")
+// loginDialog?.dismiss()
+// } else {
+// val id = jsonObject?.optString("id")
+// val name = jsonObject?.optString("name")
+// val object_pic: JSONObject? =
+// jsonObject!!.optJSONObject("picture")
+// val object_data = object_pic?.optJSONObject("data")
+// val photo = object_data?.optString("url")
+// showLoading()
+// EventBus.getDefault()
+// .post(Constants.CONSTANTS_leaveApp)
+// mViewModel.doLogin(
+// LoginReq(
+// photo.toString(),
+// "",
+// name.toString(),
+// "",
+// "facebook",
+// id.toString()
+// )
+// )
+// }
+// }
+// val parameters = Bundle()
+// parameters.putString("fields", "id,name,email,picture")
+// mGraphRequest.parameters = parameters
+// mGraphRequest.executeAsync()
+// }
+// }
+//
+// override fun onCancel() {
+// toast("Facebook login Cancel")
+// loginDialog?.dismiss()
+// }
+//
+// override fun onError(exception: FacebookException) {
+// toast("Facebook login exception.$exception")
+// loginDialog?.dismiss()
+// }
+// })
+// loginDialog = LoginDialog(this)
+// val tv_facebook_login =
+// loginDialog?.findViewById(R.id.tv_facebook_login)
+// tv_facebook_login?.setOnClickListener {
+// singleClick {
+// callbackManager?.let { it1 ->
+// LoginManager.getInstance()
+// .logInWithReadPermissions(this, it1, arrayListOf("public_profile", "email"))
+// }
+// }
+// }
+// loginDialog?.show()
+// loginDialog?.setOnDismissListener {
+// LoginManager.getInstance().unregisterCallback(callbackManager)
+// callbackManager = null
+// loginDialog = null
+// }
+// }
+
+ override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ moveTaskToBack(true)
+ return true
+ }
+ return super.onKeyDown(keyCode, event)
+ }
+
+ override fun onDestroy() {
+// scheduler?.shutdown()
+// scheduler = null
+ super.onDestroy()
+ EventBus.getDefault().unregister(this)
+ }
+
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/main/SplashActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/main/SplashActivity.kt
new file mode 100644
index 0000000..cd09b2d
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/main/SplashActivity.kt
@@ -0,0 +1,54 @@
+package com.jia.er.nebuluxe.app.main
+
+import android.content.Intent
+import androidx.lifecycle.ViewModelProvider
+import com.jia.er.nebuluxe.app.basics.BaseActivity
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.databinding.ActivitySplashBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.Memory
+
+class SplashActivity : BaseActivity() {
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+ override fun top() {
+
+ val toString = Memory.getMMKV()
+ .getString(Constants.CONSTANTS_AuthorizationExample, "")
+ .toString()
+ if (toString.isEmpty()) {
+ mViewModel.createUserAccount()
+ } else {
+ goMain()
+ }
+ }
+
+
+
+ override fun center() {
+ mViewModel.userRegisterData.observe(this) {
+ if (it != null) {
+ Memory.getMMKV()
+ .putString(Constants.CONSTANTS_AuthorizationExample, it.data?.token)
+ goMain()
+ } else {
+ goMain()
+ }
+ }
+ }
+
+ private fun goMain() {
+ binding?.root?.postDelayed({
+ startActivity(
+ Intent(
+ this,
+ MainActivity::class.java
+ )
+ )
+ finish()
+ }, 1000)
+ }
+
+ override fun getViewBinding(): ActivitySplashBinding {
+ return ActivitySplashBinding.inflate(layoutInflater)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/me/AboutActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/me/AboutActivity.kt
new file mode 100644
index 0000000..c76f7c8
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/me/AboutActivity.kt
@@ -0,0 +1,42 @@
+package com.jia.er.nebuluxe.app.me
+
+import android.content.Intent
+import android.net.Uri
+import com.jia.er.nebuluxe.app.basics.BaseActivity
+import com.jia.er.nebuluxe.app.databinding.ActivityAboutBinding
+import com.jia.er.nebuluxe.app.utils.PackageUtils
+import com.jia.er.nebuluxe.app.utils.singleClick
+
+class AboutActivity : BaseActivity() {
+ override fun top() {
+ binding.exampleIvBack.setOnClickListener { finish() }
+ }
+
+ override fun center() {
+ binding.tvVersion.text = "V".plus(PackageUtils.getPackageVersion(this))
+ binding.tvPrivacyPolicy.setOnClickListener {
+ singleClick {
+ val webIntent =
+ Intent(Intent.ACTION_VIEW, Uri.parse("https://www.nebuluxetv.com/private"))
+ startActivity(webIntent)
+ }
+ }
+ binding.tvUserAgreement.setOnClickListener {
+ singleClick {
+ val webIntent =
+ Intent(Intent.ACTION_VIEW, Uri.parse("https://www.nebuluxetv.com/user_policy"))
+ startActivity(webIntent)
+ }
+ }
+ binding.tvVisitWebsite.setOnClickListener {
+ singleClick {
+ val webIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.nebuluxetv.com"))
+ startActivity(webIntent)
+ }
+ }
+ }
+
+ override fun getViewBinding(): ActivityAboutBinding {
+ return ActivityAboutBinding.inflate(layoutInflater)
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/me/MeFragment.kt b/app/src/main/java/com/jia/er/nebuluxe/app/me/MeFragment.kt
new file mode 100644
index 0000000..26d1928
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/me/MeFragment.kt
@@ -0,0 +1,247 @@
+package com.jia.er.nebuluxe.app.me
+
+import android.annotation.SuppressLint
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import android.content.Intent
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.style.UnderlineSpan
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.engine.DiskCacheStrategy
+import com.bumptech.glide.load.resource.bitmap.CircleCrop
+import com.bumptech.glide.request.RequestOptions
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseFragment
+import com.jia.er.nebuluxe.app.basics.Constants
+import com.jia.er.nebuluxe.app.databinding.FragmentMeBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.Memory
+import com.jia.er.nebuluxe.app.utils.singleClick
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+class MeFragment : BaseFragment() {
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+
+ override fun top() {
+ EventBus.getDefault().register(this)
+ mViewModel.noticeNum()
+ binding.srMe.setOnRefreshListener {
+ mViewModel.getInfo()
+ mViewModel.noticeNum()
+ }
+// binding.llFeedback.setOnClickListener {
+// singleClick {
+// startActivity(
+// Intent(
+// requireActivity(),
+// FeedBackActivity::class.java
+// )
+// )
+// }
+// }
+// binding.clTopUp.setOnClickListener {
+// singleClick {
+// startActivity(
+// Intent(
+// requireActivity(),
+// StoreActivity::class.java
+// )
+// )
+// }
+// }
+// binding.clVip.setOnClickListener {
+// singleClick {
+// startActivity(
+// Intent(
+// requireActivity(),
+// StoreActivity::class.java
+// )
+// )
+// }
+// }
+// binding.tvExampleAbout.setOnClickListener {
+// singleClick {
+// startActivity(
+// Intent(
+// requireActivity(),
+// AboutActivity::class.java
+// )
+// )
+// }
+// }
+// binding.tvExampleSettings.setOnClickListener {
+// singleClick {
+// startActivity(
+// Intent(
+// requireActivity(),
+// SettingActivity::class.java
+// )
+// )
+// }
+// }
+// binding.tvId.setOnClickListener {
+// val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+// clipboard.setPrimaryClip(
+// ClipData.newPlainText(
+// "label",
+// Memory.getCustomId()
+// )
+// )
+// toast("Copied")
+// }
+// binding.wallet.setOnClickListener {
+// startActivity(
+// Intent(
+// requireActivity(),
+// MyWalletActivity::class.java
+// )
+// )
+// }
+// setUserUI()
+// binding.tvVipStatus.applyTextSkew(-10f)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ setUserUI()
+ }
+
+ override fun center() {
+ mViewModel.infoData.observe(this) {
+ if (it != null) {
+ it.data?.let { it1 ->
+ Memory.saveUserInfo(it1)
+ setUserUI()
+ }
+ }
+ binding.srMe.finishRefresh()
+ }
+// mViewModel.noticeNumData.observe(this) {
+// if (it != null) {
+// if (it.data?.feedback_notice_num != 0) {
+// binding?.tvBackNum?.visibility = View.VISIBLE
+// binding?.tvBackNum?.text = it.data?.feedback_notice_num.toString()
+// } else {
+// binding?.tvBackNum?.visibility = View.INVISIBLE
+// }
+// } else {
+// binding?.tvBackNum?.visibility = View.INVISIBLE
+// }
+// }
+ }
+
+
+ @SuppressLint("UseCompatLoadingForDrawables")
+ private fun setUserUI() {
+ if (Memory.isTourist()) {
+ binding?.ivAvatar?.let {
+ Glide.with(this).load(Memory.getUserInfo()?.avator).skipMemoryCache(true)
+ .diskCacheStrategy(DiskCacheStrategy.NONE)
+ .apply(RequestOptions.bitmapTransform(CircleCrop()))
+ .placeholder(R.drawable.iv_avatar)
+ .error(R.drawable.iv_avatar).into(it)
+ }
+ } else {
+ binding?.tvUserName?.text =
+ Memory.getUserInfo()?.family_name.plus(Memory.getUserInfo()?.giving_name)
+ binding?.ivAvatar?.let {
+ Glide.with(this).load(Memory.getUserInfo()?.avator).skipMemoryCache(true)
+ .diskCacheStrategy(DiskCacheStrategy.NONE)
+ .apply(RequestOptions.bitmapTransform(CircleCrop()))
+ .placeholder(R.drawable.iv_avatar)
+ .error(R.drawable.iv_avatar).into(it)
+ }
+ }
+// if (Memory.isVip()) {
+// binding.clVip.background = context?.getDrawable(R.drawable.iv_me_vip_h)
+// binding.tvVipStatus.text = Memory.getUserInfo()?.vip_type
+// val content = binding.tvVipStatus.text
+// val spannableString = SpannableString(content)
+// spannableString.setSpan(
+// UnderlineSpan(),
+// 0,
+// content.length,
+// Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+// )
+// binding.tvVipStatus.text = spannableString
+// binding?.tvInfoVip?.text =
+// "Expiration Time:".plus(Memory.getUserInfo()?.vip_end_time?.toLong()
+// ?.let { transToString(it) })
+// binding?.tvInfoVip?.setCompoundDrawablesWithIntrinsicBounds(
+// context?.getDrawable(R.drawable.iv_time),
+// null,
+// null,
+// null
+// )
+// binding?.tvVipStatus?.setCompoundDrawablesWithIntrinsicBounds(
+// context?.getDrawable(R.drawable.iv_vip_h),
+// null,
+// context?.getDrawable(R.drawable.iv_vip_right),
+// null
+// )
+// binding.tvGo.text = "Renew"
+// binding.tvGo.background = context?.getDrawable(R.drawable.bg_vip_go_h)
+// } else {
+// binding?.tvInfoVip?.setCompoundDrawablesWithIntrinsicBounds(
+// null,
+// null,
+// null,
+// null
+// )
+// val spannableString = SpannableString("VIP Membership")
+// spannableString.setSpan(
+// UnderlineSpan(),
+// 0,
+// spannableString.length,
+// Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+// )
+// binding.tvVipStatus.text = spannableString
+// binding?.tvVipStatus?.setCompoundDrawablesWithIntrinsicBounds(
+// context?.getDrawable(R.drawable.iv_vip),
+// null,
+// context?.getDrawable(R.drawable.iv_vip_right),
+// null
+// )
+// binding.tvGo.text = "Go"
+// binding.tvGo.background = context?.getDrawable(R.drawable.bg_vip_go)
+// binding?.tvInfoVip?.text = "Unlock VIP Now"
+// binding.clVip.background = context?.getDrawable(R.drawable.iv_me_vip_n)
+//
+// }
+ binding?.tvId?.text = "ID:".plus(Memory.getUserInfo()?.customer_id)
+// binding?.tvCoinNum?.text = Memory.getUserInfo()?.coin_left_total.toString()
+// binding?.tvDonateNum?.text = Memory.getUserInfo()?.send_coin_left_total.toString()
+ }
+
+
+ override fun onHiddenChanged(hidden: Boolean) {
+ super.onHiddenChanged(hidden)
+ if (!hidden) {
+ mViewModel.getInfo()
+ mViewModel.noticeNum()
+ }
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEvent(event: String) {
+ if (Constants.CONSTANTS_refresh_me == event) {
+ mViewModel.getInfo()
+ mViewModel.noticeNum()
+ }
+ }
+
+ override fun getViewBinding(): FragmentMeBinding {
+ return FragmentMeBinding.inflate(layoutInflater)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ EventBus.getDefault().unregister(this)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/me/SettingActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/me/SettingActivity.kt
new file mode 100644
index 0000000..7fe71a5
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/me/SettingActivity.kt
@@ -0,0 +1,131 @@
+package com.jia.er.nebuluxe.app.me
+
+import android.content.Context
+import android.content.Intent
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.lifecycle.ViewModelProvider
+import com.jia.er.nebuluxe.app.R
+import com.jia.er.nebuluxe.app.basics.BaseActivity
+import com.jia.er.nebuluxe.app.databinding.ActivitySettingBinding
+import com.jia.er.nebuluxe.app.net.MainViewModel
+import com.jia.er.nebuluxe.app.utils.toast
+import org.greenrobot.eventbus.EventBus
+import java.io.File
+
+class SettingActivity : BaseActivity() {
+ private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] }
+
+ override fun top() {
+ binding.exampleIvBack.setOnClickListener { finish() }
+ binding.tvClearCache.setOnClickListener {
+ clearCache(this)
+ toast(getString(R.string.success))
+ }
+ binding.exampleIvBack.setOnClickListener { finish() }
+// binding.tvExampleLogOut.setOnClickListener {
+// singleClick {
+// if (!Memory.isTourist()) {
+// startActivity(
+// Intent(
+// this,
+// AccountDeleteActivity::class.java
+// )
+// )
+// } else {
+// toast(getString(R.string.log_first))
+// }
+// }
+// }
+// binding?.tvExampleQuit?.setOnClickListener {
+// singleClick {
+// if (!Memory.isTourist()) {
+// val exampleUnFavoriteDialog = NotificationDialog(this)
+// val tvThinkAgain =
+// exampleUnFavoriteDialog.findViewById(R.id.example_tv_think_again)
+// val tvUnfavorite =
+// exampleUnFavoriteDialog.findViewById(R.id.example_tv_unfavorite)
+// val tvTitle =
+// exampleUnFavoriteDialog.findViewById(R.id.example_tv_title)
+// val tvContent =
+// exampleUnFavoriteDialog.findViewById(R.id.example_tv_content)
+// tvThinkAgain.text = "Cancel"
+// tvUnfavorite.text = "Confirm"
+// tvTitle.text = "Tips"
+// tvContent.text = "Are you sure you want to log out?"
+// tvThinkAgain.setOnClickListener { exampleUnFavoriteDialog.dismiss() }
+// tvUnfavorite.setOnClickListener {
+// singleClick {
+// showLoading()
+// EventBus.getDefault()
+// .post(Constants.CONSTANTS_leaveApp)
+// mViewModel.doSignout()
+// exampleUnFavoriteDialog.dismiss()
+// }
+// }
+// exampleUnFavoriteDialog.show()
+// } else {
+// toast(getString(R.string.log_first))
+// }
+// }
+// }
+ }
+
+// override fun onResume() {
+// super.onResume()
+// if (Constants.WebRefresh){
+// finish()
+// }
+// }
+
+
+ override fun center() {
+// mViewModel.signoutData.observe(this) {
+// if (it != null) {
+// toast(getString(R.string.success))
+// LoginManager.getInstance().logOut()
+// Memory.getMMKV()
+// .putString(Constants.CONSTANTS_AuthorizationExample, it.data?.token)
+// EventBus.getDefault()
+// .post(Constants.CONSTANTS_enterTheApp)
+// EventBus.getDefault()
+// .post(Constants.CONSTANTS_onLine)
+// EventBus.getDefault()
+// .post(Constants.CONSTANTS_refresh_me)
+// Constants.WebRefresh = true
+// finish()
+// } else {
+// toast(getString(R.string.network_error))
+// }
+// hideLoading()
+// }
+ }
+
+ override fun getViewBinding(): ActivitySettingBinding {
+ return ActivitySettingBinding.inflate(layoutInflater)
+ }
+
+
+ private fun clearCache(context: Context) {
+ deleteFilesInDirectory(context.cacheDir)
+
+ context.externalCacheDir?.let {
+ deleteFilesInDirectory(it)
+ }
+ }
+
+ private fun deleteFilesInDirectory(directory: File) {
+ if (directory.isDirectory) {
+ val files = directory.listFiles()
+ if (files != null) {
+ for (file in files) {
+ if (file.isDirectory) {
+ deleteFilesInDirectory(file)
+ } else {
+ file.delete()
+ }
+ }
+ }
+ }
+ directory.delete()
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/net/AppService.kt b/app/src/main/java/com/jia/er/nebuluxe/app/net/AppService.kt
new file mode 100644
index 0000000..38de78f
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/net/AppService.kt
@@ -0,0 +1,258 @@
+package com.jia.er.nebuluxe.app.net
+
+import com.jia.er.nebuluxe.app.data.BaseRes
+import com.jia.er.nebuluxe.app.data.BuyVideoRes
+import com.jia.er.nebuluxe.app.data.CategoriesDataRes
+import com.jia.er.nebuluxe.app.data.CollectionRes
+import com.jia.er.nebuluxe.app.data.CreateOrderReq
+import com.jia.er.nebuluxe.app.data.CreateOrderRes
+import com.jia.er.nebuluxe.app.data.CustomerBuyRecordsRes
+import com.jia.er.nebuluxe.app.data.CustomerOrderRes
+import com.jia.er.nebuluxe.app.data.DetailsRecommendRes
+import com.jia.er.nebuluxe.app.data.ExampleKeywordDataRes
+import com.jia.er.nebuluxe.app.data.FbNotificationReq
+import com.jia.er.nebuluxe.app.data.FreeSeriesMoreRes
+import com.jia.er.nebuluxe.app.data.HistoryDataRes
+import com.jia.er.nebuluxe.app.data.HomeModuleBean
+import com.jia.er.nebuluxe.app.data.HomeNewShortPlayNoPaginateRes
+import com.jia.er.nebuluxe.app.data.HomeNewShortPlayRes
+import com.jia.er.nebuluxe.app.data.HomeRankingRes
+import com.jia.er.nebuluxe.app.data.HomeTopRes
+import com.jia.er.nebuluxe.app.data.LoginReq
+import com.jia.er.nebuluxe.app.data.LoginRes
+import com.jia.er.nebuluxe.app.data.NoticeNumRes
+import com.jia.er.nebuluxe.app.data.PayReq
+import com.jia.er.nebuluxe.app.data.PayRes
+import com.jia.er.nebuluxe.app.data.PaySettingRes
+import com.jia.er.nebuluxe.app.data.PlayerDetailDataRes
+import com.jia.er.nebuluxe.app.data.RecommendDataRes
+import com.jia.er.nebuluxe.app.data.RewardCoinsRes
+import com.jia.er.nebuluxe.app.data.ShortListCategoryDataInfo
+import com.jia.er.nebuluxe.app.data.UploadHistoryReq
+import com.jia.er.nebuluxe.app.data.VideoListDataRes
+import com.jia.er.nebuluxe.app.data.UserInfoRes
+import com.jia.er.nebuluxe.app.data.UserRegisterRes
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.Field
+import retrofit2.http.FormUrlEncoded
+import retrofit2.http.GET
+import retrofit2.http.POST
+import retrofit2.http.Query
+
+interface AppService {
+
+ @POST("customer/register")
+ fun register(): Call>
+
+ @GET("customer/info")
+ fun getInfo(): Call>
+
+
+ @POST("homeTop")
+ fun homeTop(): Call>
+
+ @POST("newShortPlay")
+ fun newShortPlay(
+ @Query("current_page") current_page: Int,
+ @Query("page_size") page_size: Int = 10
+ ): Call>
+
+ @GET("myCollections")
+ fun getCollections(
+ @Query("current_page") current_page: Int,
+ @Query("page_size") page_size: Int = 10
+ ): Call>
+
+ @GET("getVideoDetails")
+ fun getVideoDetails(
+ @Query("short_play_id") short_play_id: Int,
+ @Query("video_id") video_id: Int,
+ @Query("activity_id") activity_id: Int,
+ @Query("revolution") revolution: String,
+ @Query("no_ads") no_ads: Boolean?,
+ ): Call>
+
+ @POST("newShortPlayNoPaginate")
+ fun newShortPlayNoPaginate(): Call>
+
+ @FormUrlEncoded
+ @POST("createHistory")
+ fun createHistory(
+ @Field("short_play_id") short_play_id: Int,
+ @Field("video_id") video_id: Int,
+ ): Call>
+
+ @GET("getRecommands")
+ fun getRecommands(
+ @Query("current_page") current_page: Int,
+ @Query("page_size") page_size: Int,
+ @Query("revolution") revolution: String,
+ ): Call>
+
+ @FormUrlEncoded
+ @POST("collect")
+ fun collect(
+ @Field("short_play_id") short_play_id: Int,
+ @Field("video_id") video_id: Int
+ ): Call>
+
+ @FormUrlEncoded
+ @POST("cancelCollect")
+ fun cancelCollect(
+ @Field("short_play_id") short_play_id: Int,
+ @Field("video_id") video_id: Int
+ ): Call>
+
+
+ @GET("myHistorys")
+ fun myHistorys(
+ @Query("current_page") current_page: Int,
+ @Query("page_size") page_size: Int = 10
+ ): Call>
+
+ @GET("search")
+ fun getVideoList(@Query("search") search: String): Call>
+
+ @GET("videoList")
+ fun getVideoList(
+ @Query("current_page") current_page: Int,
+ @Query("category_id") category_id: Int,
+ @Query("page_size") page_size: Int = 10
+ ): Call>
+
+ @POST("homeRanking")
+ fun homeRanking(@Query("type") type: String): Call>
+
+ @POST("uploadHistorySeconds")
+ fun uploadHistorySeconds(
+ @Body uploadHistoryReq: UploadHistoryReq
+ ): Call>
+
+ @GET("freeShorPlayListNoPaginate")
+ fun freeMoreVideo(): Call>
+
+ @GET("getDetailsRecommand")
+ fun getDetailsRecommand(
+ ): Call>
+
+ @GET("search/hots")
+ fun hots(): Call>
+
+ @POST("search/click")
+ fun click(
+ @Query("short_play_id") short_play_id: Int,
+ ): Call>
+
+
+ @GET("search")
+ fun keyword(@Query("search") search: String): Call>
+
+ @GET("home/all-modules")
+ fun allModules(): Call>
+
+ @FormUrlEncoded
+ @POST("buy_video")
+ fun buyVideo(
+ @Field("short_play_id") short_play_id: Int,
+ @Field("video_id") video_id: Int,
+ ): Call>
+
+ @GET("getCategories")
+ fun getCategories(): Call>
+
+ @POST("customer/onLine")
+ fun onLine(
+ ): Call>
+
+ @POST("customer/enterTheApp")
+ fun enterTheApp(): Call>
+
+ @POST("customer/leaveApp")
+ fun leaveApp(): Call>
+
+ @FormUrlEncoded
+ @POST("customer/firebaseToken")
+ fun firebaseToken(@Field("fcm_token") fcm_token: String): Call>
+
+ @FormUrlEncoded
+ @POST("w2aSelfAttribution")
+ fun w2aSelfAttribution(
+ @Field("data") data: String
+ ): Call>
+
+
+ @POST("openNotify")
+ fun openNotify(
+ ): Call>
+
+ @POST("customer/uploadNoticeStatus")
+ fun uploadNoticeStatus(
+ @Body fbNotificationReq: FbNotificationReq
+ ): Call>
+
+ @FormUrlEncoded
+ @POST("message/sendReport")
+ fun sendReport(
+ @Field("message_id") message_id: String, @Field("title") title: String
+ ): Call>
+
+ @POST("noticeNum")
+ fun noticeNum(): Call>
+
+ @GET("getCustomerOrder")
+ fun getCustomerOrder(
+ @Query("current_page") current_page: Int,
+ @Query("buy_type") buy_type: String,
+ @Query("page_size") page_size: Int = 10
+ ): Call>
+
+ @GET("getCustomerBuyRecords")
+ fun getCustomerBuyRecords(
+ @Query("current_page") current_page: Int,
+ @Query("page_size") page_size: Int = 10
+ ): Call>
+
+ @POST("sendCoinList")
+ fun sendCoinList(
+ @Query("current_page") current_page: Int,
+ @Query("page_size") page_size: Int = 10
+ ): Call>
+
+ @GET("paySettingsV3")
+ fun getPaySetting(
+ @Query("short_play_id") short_play_id: Int?,
+ @Query("short_play_video_id") short_play_video_id: Int?
+ ): Call>
+
+
+ @POST("createOrder")
+ fun createOrder(@Body createOrderReq: CreateOrderReq): Call>
+
+ @POST("googlePaid")
+ fun googlePaid(@Body examplePayReq: PayReq?): Call>
+
+ @POST("event/add")
+ suspend fun upError(@Body body: Map): Call>
+
+ @POST("customer/login")
+ fun login(@Body exampleLoginReq: LoginReq): Call>
+
+ @POST("customer/logoff")
+ fun logoff(): Call>
+
+ @POST("customer/signout")
+ fun signout(): Call>
+
+ @GET("highestPaymentAndHottestVideo")
+ fun homeHot(
+ @Query("buy_count_num") buycount: Int,
+ @Query("hottest_num") hottestnum: Int,
+ ): Call>
+
+ @GET("categoryListAppendShortPlay")
+ fun userCenterRecommend(
+ @Query("short_play_num") shortplaynum: Int,
+ ): Call>
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/net/BodyInterceptor.kt b/app/src/main/java/com/jia/er/nebuluxe/app/net/BodyInterceptor.kt
new file mode 100644
index 0000000..04e43f4
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/net/BodyInterceptor.kt
@@ -0,0 +1,30 @@
+package com.jia.er.nebuluxe.app.net
+
+import com.jia.er.nebuluxe.app.net.Decryption.EN_STR_TAG
+import okhttp3.Interceptor
+import okhttp3.Response
+import okhttp3.ResponseBody
+import java.io.IOException
+
+
+class BodyInterceptor : Interceptor {
+
+ @kotlin.jvm.Throws(IOException::class)
+ override fun intercept(chain: Interceptor.Chain): Response {
+ val k_center = chain.proceed(chain.request())
+ return if (k_center.body != null && k_center.body!!.contentType() != null) {
+ val actiity = k_center.body!!.contentType()
+ val circle = k_center.body!!.string()
+ val str: String = if (!circle.startsWith(EN_STR_TAG)) {
+ circle
+ } else {
+ Decryption.deStr(circle)
+ }
+ val current = ResponseBody.create(actiity, str)
+ k_center.newBuilder().body(current).build()
+ } else {
+ k_center
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/net/Decryption.kt b/app/src/main/java/com/jia/er/nebuluxe/app/net/Decryption.kt
new file mode 100644
index 0000000..b5edb57
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/net/Decryption.kt
@@ -0,0 +1,66 @@
+package com.jia.er.nebuluxe.app.net
+
+
+object Decryption {
+ const val BF_SIZE = 2048
+ const val EN_STR_TAG = '$'
+
+ fun deStr(data: String): String {
+ return String(deStrBytes(data), Charsets.UTF_8)
+ }
+
+ // Decrypt bytes from hex string
+ fun deStrBytes(data: String): ByteArray {
+ if (!data.startsWith(EN_STR_TAG)) {
+ throw IllegalArgumentException("Invalid encoded string")
+ }
+ val hexData = data.substring(1)
+ val bytes = hexData.chunked(2).map { it.toInt(16).toByte() }.toByteArray()
+ return desadasd(bytes)
+ }
+
+ // Decrypt data
+ fun desadasd(data: ByteArray): ByteArray {
+ if (data.isEmpty()) {
+ return data
+ }
+ val saltLen = data[0].toInt()
+ val salt = data.slice(1 until 1 + saltLen).toByteArray()
+ return deWithSalt(data.slice(1 + saltLen until data.size).toByteArray(), salt)
+ }
+
+ // Decrypt data with salt
+ fun deWithSalt(data: ByteArray, salt: ByteArray): ByteArray {
+ val decryptedData = cxEd(data)
+ return removeSalt(decryptedData, salt)
+ }
+
+ // Encrypt/Decrypt data by flipping bits
+ fun cxEd(data: ByteArray): ByteArray {
+ return data.map { (it.toInt() xor 0xFF).toByte() }.toByteArray()
+ }
+
+ // Remove salt from data
+ fun removeSalt(data: ByteArray, salt: ByteArray): ByteArray {
+ if (salt.isEmpty()) return data
+ val ret = mutableListOf()
+ var idx = 0
+ val sl = salt.size
+ data.forEach {
+ val s = salt[idx % sl]
+ ret.add(ssadcalRemoveSalt(it, s))
+ idx++
+ }
+ return ret.toByteArray()
+ }
+
+ fun ssadcalRemoveSalt(v: Byte, s: Byte): Byte {
+ return if (v >= s) {
+ (v - s).toByte()
+ } else {
+ (0xFF - (s - v) + 1).toByte()
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/net/MainRequest.kt b/app/src/main/java/com/jia/er/nebuluxe/app/net/MainRequest.kt
new file mode 100644
index 0000000..eb4291e
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/net/MainRequest.kt
@@ -0,0 +1,316 @@
+package com.jia.er.nebuluxe.app.net
+
+import androidx.lifecycle.LiveData
+import com.jia.er.nebuluxe.app.data.BaseRes
+import com.jia.er.nebuluxe.app.data.BuyVideoRes
+import com.jia.er.nebuluxe.app.data.CollectionRes
+import com.jia.er.nebuluxe.app.data.CreateOrderReq
+import com.jia.er.nebuluxe.app.data.CreateOrderRes
+import com.jia.er.nebuluxe.app.data.CustomerBuyRecordsRes
+import com.jia.er.nebuluxe.app.data.CustomerOrderRes
+import com.jia.er.nebuluxe.app.data.DetailsRecommendRes
+import com.jia.er.nebuluxe.app.data.ExampleKeywordDataRes
+import com.jia.er.nebuluxe.app.data.FbNotificationReq
+import com.jia.er.nebuluxe.app.data.FreeSeriesMoreRes
+import com.jia.er.nebuluxe.app.data.HistoryDataRes
+import com.jia.er.nebuluxe.app.data.HomeModuleBean
+import com.jia.er.nebuluxe.app.data.HomeNewShortPlayNoPaginateRes
+import com.jia.er.nebuluxe.app.data.HomeNewShortPlayRes
+import com.jia.er.nebuluxe.app.data.HomeRankingRes
+import com.jia.er.nebuluxe.app.data.HomeTopRes
+import com.jia.er.nebuluxe.app.data.NoticeNumRes
+import com.jia.er.nebuluxe.app.data.PayReq
+import com.jia.er.nebuluxe.app.data.PayRes
+import com.jia.er.nebuluxe.app.data.PaySettingRes
+import com.jia.er.nebuluxe.app.data.PlayerDetailDataRes
+import com.jia.er.nebuluxe.app.data.RecommendDataRes
+import com.jia.er.nebuluxe.app.data.RewardCoinsRes
+import com.jia.er.nebuluxe.app.data.UploadHistoryReq
+import com.jia.er.nebuluxe.app.data.VideoListDataRes
+import com.jia.er.nebuluxe.app.data.UserInfoRes
+import com.jia.er.nebuluxe.app.data.UserRegisterRes
+import com.jia.er.nebuluxe.app.net.Retrofit.handleData
+import com.jia.er.nebuluxe.app.net.Retrofit.response
+import com.jia.er.nebuluxe.app.data.CategoriesDataRes
+import com.jia.er.nebuluxe.app.data.LoginReq
+import com.jia.er.nebuluxe.app.data.LoginRes
+import com.jia.er.nebuluxe.app.data.ShortListCategoryDataInfo
+
+object MainRequest {
+ private val appService = Retrofit.build(AppService::class.java)
+
+
+ fun userRegister(): LiveData>> = handleData {
+ appService.register().response()
+ }
+
+ fun getInfo(): LiveData>> = handleData {
+ appService.getInfo().response()
+ }
+
+
+ fun homeTop(): LiveData>> = handleData {
+ appService.homeTop()
+ .response()
+ }
+
+
+ fun newShortPlay(current_page: Int): LiveData>> =
+ handleData {
+ appService.newShortPlay(current_page)
+ .response()
+ }
+
+
+ fun getCollections(current_page: Int): LiveData>> =
+ handleData {
+ appService.getCollections(current_page).response()
+ }
+
+ fun getVideoDetails(
+ short_play_id: Int, video_id: Int, activity_id: Int, revolution: String, no_ads: Boolean?
+ ): LiveData>> = handleData {
+ appService.getVideoDetails(
+ short_play_id,
+ video_id,
+ activity_id,
+ revolution,
+ no_ads
+ )
+ .response()
+ }
+
+
+ fun newShortPlayNoPaginate(): LiveData>> =
+ handleData {
+ appService.newShortPlayNoPaginate()
+ .response()
+ }
+
+
+ fun doCreateHistory(
+ short_play_id: Int, video_id: Int
+ ): LiveData>> = handleData {
+ appService.createHistory(short_play_id, video_id).response()
+ }
+
+
+ fun getRecommands(
+ current_page: Int, page_size: Int, revolution: String
+ ): LiveData>> = handleData {
+ appService.getRecommands(current_page, page_size, revolution).response()
+ }
+
+
+ private suspend fun collect(short_play_id: Int, video_id: Int) =
+ appService.collect(short_play_id, video_id).response()
+
+ fun doCollect(
+ short_play_id: Int, video_id: Int
+ ): LiveData>> = handleData {
+ collect(short_play_id, video_id)
+ }
+
+ private suspend fun cancelCollect(short_play_id: Int, video_id: Int) =
+ appService.cancelCollect(short_play_id, video_id).response()
+
+ fun doCancelCollect(
+ short_play_id: Int, video_id: Int
+ ): LiveData>> = handleData {
+ cancelCollect(short_play_id, video_id)
+ }
+
+
+ fun myHistorys(
+ current_page: Int
+ ): LiveData>> = handleData {
+ appService.myHistorys(current_page).response()
+ }
+
+
+ fun getVideoList(search: String): LiveData>> =
+ handleData {
+ appService.getVideoList(search).response()
+ }
+
+ fun getVideoList(
+ current_page: Int,
+ category_id: Int
+ ): LiveData>> =
+ handleData {
+ appService.getVideoList(current_page, category_id).response()
+ }
+
+
+ fun homeRanking(type: String): LiveData>> = handleData {
+ appService.homeRanking(type)
+ .response()
+ }
+
+ fun freeMoreVideo(
+ ): LiveData>> =
+ handleData {
+ appService.freeMoreVideo().response()
+ }
+
+
+ fun getDetailsRecommand(
+ ): LiveData>> =
+ handleData {
+ appService.getDetailsRecommand().response()
+ }
+
+ fun uploadHistorySeconds(
+ uploadHistoryReq: UploadHistoryReq
+ ): LiveData>> =
+ handleData {
+ appService.uploadHistorySeconds(uploadHistoryReq).response()
+ }
+
+
+ fun hots(): LiveData>> =
+ handleData {
+ appService.hots().response()
+ }
+
+ fun click(short_play_id: Int): LiveData>> =
+ handleData {
+ appService.click(short_play_id).response()
+ }
+
+ fun keyword(search: String): LiveData>> =
+ handleData {
+ appService.keyword(search).response()
+ }
+
+
+ fun allModules(): LiveData>> = handleData {
+ appService.allModules().response()
+ }
+
+ fun doBuyVideo(
+ short_play_id: Int, video_id: Int
+ ): LiveData>> = handleData {
+ appService.buyVideo(short_play_id, video_id).response()
+ }
+
+ fun getCategories(): LiveData>> =
+ handleData {
+ appService.getCategories().response()
+ }
+
+ fun enterTheApp(): LiveData>> = handleData {
+ appService.enterTheApp().response()
+ }
+
+ fun leaveApp(): LiveData>> = handleData {
+ appService.leaveApp().response()
+ }
+
+ fun onLine(
+ ): LiveData>> =
+ handleData {
+ appService.onLine().response()
+ }
+
+ fun firebaseToken(fcm_token: String): LiveData>> = handleData {
+ appService.firebaseToken(fcm_token).response()
+ }
+
+ fun w2aSelfAttribution(
+ data: String
+ ): LiveData>> =
+ handleData {
+ appService.w2aSelfAttribution(data).response()
+ }
+
+ fun openNotify(
+ ): LiveData>> =
+ handleData {
+ appService.openNotify().response()
+ }
+
+ fun uploadNoticeStatus(fbNotificationReq: FbNotificationReq): LiveData>> =
+ handleData {
+ appService.uploadNoticeStatus(fbNotificationReq)
+ .response()
+ }
+
+ fun sendReport(
+ message_id: String, title: String
+ ): LiveData>> =
+ handleData {
+ appService.sendReport(message_id, title).response()
+ }
+
+ fun noticeNum(): LiveData>> =
+ handleData {
+ appService.noticeNum().response()
+ }
+
+ fun getCustomerOrder(
+ current_page: Int,
+ buy_type: String
+ ): LiveData>> = handleData {
+ appService.getCustomerOrder(current_page, buy_type).response()
+ }
+
+ fun getCustomerBuyRecords(current_page: Int): LiveData>> =
+ handleData {
+ appService.getCustomerBuyRecords(current_page).response()
+ }
+
+
+ fun sendCoinList(current_page: Int): LiveData>> =
+ handleData {
+ appService.sendCoinList(current_page).response()
+ }
+
+ fun getPaySetting(
+ short_play_id: Int?,
+ video_id: Int?
+ ): LiveData>> = handleData {
+ appService.getPaySetting(short_play_id, video_id).response()
+ }
+
+ fun doGooglePaid(examplePayReq: PayReq?): LiveData>> =
+ handleData {
+ appService.googlePaid(examplePayReq).response()
+ }
+
+ fun doCreateOrder(createOrderReq: CreateOrderReq): LiveData>> =
+ handleData {
+ appService.createOrder(createOrderReq).response()
+ }
+
+
+ fun upError(body: Map): LiveData>> =
+ handleData {
+ appService.upError(body).response()
+ }
+
+ fun doLogin(exampleLoginReq: LoginReq): LiveData>> =
+ handleData {
+ appService.login(exampleLoginReq).response()
+ }
+
+ fun doLogoff(): LiveData>> = handleData {
+ appService.logoff().response()
+ }
+
+ fun doSignout(): LiveData>> = handleData {
+ appService.signout().response()
+ }
+
+ fun homeHot(buycount: Int, hottestnum: Int): LiveData>> =
+ handleData {
+ appService.homeHot(buycount, hottestnum)
+ .response()
+ }
+
+ fun userCenterRecommend(): LiveData>> =
+ handleData {
+ appService.userCenterRecommend(5)
+ .response()
+ }
+}
diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/net/MainViewModel.kt b/app/src/main/java/com/jia/er/nebuluxe/app/net/MainViewModel.kt
new file mode 100644
index 0000000..dee5ef1
--- /dev/null
+++ b/app/src/main/java/com/jia/er/nebuluxe/app/net/MainViewModel.kt
@@ -0,0 +1,403 @@
+package com.jia.er.nebuluxe.app.net
+
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import com.jia.er.nebuluxe.app.data.LoginRes
+import com.jia.er.nebuluxe.app.data.BaseRes
+import com.jia.er.nebuluxe.app.data.BuyVideoRes
+import com.jia.er.nebuluxe.app.data.CategoriesDataRes
+import com.jia.er.nebuluxe.app.data.CollectionRes
+import com.jia.er.nebuluxe.app.data.CreateOrderReq
+import com.jia.er.nebuluxe.app.data.CreateOrderRes
+import com.jia.er.nebuluxe.app.data.CustomerBuyRecordsRes
+import com.jia.er.nebuluxe.app.data.CustomerOrderRes
+import com.jia.er.nebuluxe.app.data.DetailsRecommendRes
+import com.jia.er.nebuluxe.app.data.ExampleKeywordDataRes
+import com.jia.er.nebuluxe.app.data.FbNotificationReq
+import com.jia.er.nebuluxe.app.data.FreeSeriesMoreRes
+import com.jia.er.nebuluxe.app.data.HistoryDataRes
+import com.jia.er.nebuluxe.app.data.HomeModuleBean
+import com.jia.er.nebuluxe.app.data.HomeNewShortPlayNoPaginateRes
+import com.jia.er.nebuluxe.app.data.HomeNewShortPlayRes
+import com.jia.er.nebuluxe.app.data.HomeRankingRes
+import com.jia.er.nebuluxe.app.data.LoginReq
+import com.jia.er.nebuluxe.app.data.NoticeNumRes
+import com.jia.er.nebuluxe.app.data.PayReq
+import com.jia.er.nebuluxe.app.data.PayRes
+import com.jia.er.nebuluxe.app.data.PaySettingRes
+import com.jia.er.nebuluxe.app.data.PlayerDetailDataRes
+import com.jia.er.nebuluxe.app.data.RecommendDataRes
+import com.jia.er.nebuluxe.app.data.RewardCoinsRes
+import com.jia.er.nebuluxe.app.data.ShortListCategoryDataInfo
+import com.jia.er.nebuluxe.app.data.UploadHistoryReq
+import com.jia.er.nebuluxe.app.data.UserInfoRes
+import com.jia.er.nebuluxe.app.data.UserRegisterRes
+import com.jia.er.nebuluxe.app.data.VideoListDataRes
+import com.jia.er.nebuluxe.app.net.MainRequest
+
+class MainViewModel : ViewModel() {
+ private val userRegisterLiveData = MutableLiveData>()
+ val userRegisterData: MutableLiveData> get() = userRegisterLiveData
+ fun createUserAccount(
+ ) {
+ MainRequest.userRegister().observeForever { result ->
+ userRegisterLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val infoLiveData = MutableLiveData>()
+ val infoData: MutableLiveData> get() = infoLiveData
+ fun getInfo() {
+ MainRequest.getInfo().observeForever { result ->
+ infoLiveData.value = result.getOrNull()
+ }
+ }
+
+
+ private val newShortPlayLiveData = MutableLiveData>()
+ val newShortPlayData: MutableLiveData> get() = newShortPlayLiveData
+ fun newShortPlay(current_page: Int) {
+ MainRequest.newShortPlay(current_page)
+ .observeForever {
+ newShortPlayLiveData.value = it.getOrNull()
+ }
+ }
+
+ private val videoDetailsLiveData = MutableLiveData>()
+ val videoDetailsData: MutableLiveData> get() = videoDetailsLiveData
+ fun getVideoDetails(
+ short_play_id: Int,
+ video_id: Int,
+ activity_id: Int,
+ revolution: String,
+ no_ads: Boolean?
+ ) {
+ MainRequest.getVideoDetails(
+ short_play_id,
+ video_id,
+ activity_id,
+ revolution,
+ no_ads
+ )
+ .observeForever { result ->
+ videoDetailsLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val homeNewLiveData = MutableLiveData>()
+ val homeNewData: MutableLiveData> get() = homeNewLiveData
+ fun newShortPlayNoPaginate() {
+ MainRequest.newShortPlayNoPaginate()
+ .observeForever {
+ homeNewLiveData.value = it.getOrNull()
+ }
+ }
+
+
+ fun doCreateHistory(short_play_id: Int, video_id: Int) {
+ MainRequest.doCreateHistory(short_play_id, video_id).observeForever {}
+ }
+
+ private val searchLiveData = MutableLiveData>()
+ val searchData: MutableLiveData> get() = searchLiveData
+ fun getVideoList(search: String) {
+ MainRequest.getVideoList(search).observeForever { result ->
+ searchLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val videoListLiveData = MutableLiveData>()
+ val videoListData: MutableLiveData> get() = videoListLiveData
+ fun getVideoList(current_page: Int, category_id: Int) {
+ MainRequest.getVideoList(current_page, category_id).observeForever { result ->
+ videoListLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val homeRankingLiveData = MutableLiveData>()
+ val homeRankingData: MutableLiveData> get() = homeRankingLiveData
+ fun homeRanking(type: String) {
+ MainRequest.homeRanking(type)
+ .observeForever {
+ homeRankingLiveData.value = it.getOrNull()
+ }
+ }
+
+
+ private val freeMoreLiveData = MutableLiveData>()
+ val freeMoreData: MutableLiveData> get() = freeMoreLiveData
+
+ fun freeMoreVideo() {
+ MainRequest.freeMoreVideo().observeForever { result ->
+ freeMoreLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val recommendLiveData = MutableLiveData>()
+ val recommendData: MutableLiveData> get() = recommendLiveData
+ fun getRecommands(current_page: Int, page_size: Int, revolution: String) {
+ MainRequest.getRecommands(current_page, page_size, revolution)
+ .observeForever { result ->
+ recommendLiveData.value = result.getOrNull()
+ }
+ }
+
+
+ private val collectLiveData = MutableLiveData>()
+ val collectData: MutableLiveData> get() = collectLiveData
+ fun doCollect(short_play_id: Int, video_id: Int) {
+ MainRequest.doCollect(short_play_id, video_id).observeForever { result ->
+ collectLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val cancelCollectLiveData = MutableLiveData>()
+ val cancelCollectData: MutableLiveData> get() = cancelCollectLiveData
+ fun doCancelCollect(short_play_id: Int, video_id: Int) {
+ MainRequest.doCancelCollect(short_play_id, video_id).observeForever { result ->
+ cancelCollectLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val collectionsLiveData = MutableLiveData>()
+ val collectionsData: MutableLiveData> get() = collectionsLiveData
+ fun getCollections(current_page: Int) {
+ MainRequest.getCollections(current_page).observeForever { result ->
+ collectionsLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val historysLiveData = MutableLiveData>()
+ val historysData: MutableLiveData> get() = historysLiveData
+ fun myHistorys(
+ current_page: Int
+ ) {
+ MainRequest.myHistorys(current_page).observeForever { result ->
+ historysLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val getDetailsRecommandLiveData = MutableLiveData>()
+ val getDetailsRecommandData: MutableLiveData> get() = getDetailsRecommandLiveData
+
+ fun getDetailsRecommand() {
+ MainRequest.getDetailsRecommand().observeForever { result ->
+ getDetailsRecommandLiveData.value = result.getOrNull()
+ }
+ }
+
+ fun uploadHistorySeconds(uploadHistoryReq: UploadHistoryReq) {
+ MainRequest.uploadHistorySeconds(uploadHistoryReq).observeForever {}
+ }
+
+
+ private val hotsLiveData = MutableLiveData>()
+ val hotsData: MutableLiveData> get() = hotsLiveData
+ fun hots() {
+ MainRequest.hots().observeForever { result ->
+ hotsLiveData.value = result.getOrNull()
+ }
+ }
+
+ fun click(short_play_id: Int) {
+ MainRequest.click(short_play_id).observeForever {}
+ }
+
+ private val keywordLiveData = MutableLiveData>()
+ val keywordData: MutableLiveData> get() = keywordLiveData
+ fun keyword(search: String) {
+ MainRequest.keyword(search).observeForever { result ->
+ keywordLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val allModulesLiveData = MutableLiveData>()
+ val allModulesData: MutableLiveData> get() = allModulesLiveData
+ fun allModules() {
+ MainRequest.allModules().observeForever { result ->
+ allModulesLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val buy_videoLiveData = MutableLiveData>()
+ val buy_videoData: MutableLiveData> get() = buy_videoLiveData
+ fun doBuyVideo(short_play_id: Int, video_id: Int) {
+ MainRequest.doBuyVideo(short_play_id, video_id).observeForever { result ->
+ buy_videoLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val categoriesLiveData = MutableLiveData>()
+ val categoriesData: MutableLiveData> get() = categoriesLiveData
+ fun getCategories() {
+ MainRequest.getCategories().observeForever { result ->
+ categoriesLiveData.value = result.getOrNull()
+ }
+ }
+
+ fun enterTheApp() {
+ MainRequest.enterTheApp().observeForever {}
+ }
+
+ fun leaveApp() {
+ MainRequest.leaveApp().observeForever {}
+ }
+
+ fun onLine() {
+ MainRequest.onLine().observeForever {}
+ }
+
+ fun firebaseToken(
+ fcm_token: String
+ ) {
+ MainRequest.firebaseToken(fcm_token).observeForever {}
+ }
+
+ private val w2aSelfAttributionLiveData =
+ MutableLiveData>()
+
+ fun w2aSelfAttribution(data: String) {
+ MainRequest.w2aSelfAttribution(data).observeForever { result ->
+ w2aSelfAttributionLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val openNotifyLiveData = MutableLiveData>()
+ val openNotifyData: MutableLiveData> get() = openNotifyLiveData
+
+ fun openNotify() {
+ MainRequest.openNotify().observeForever { result ->
+ openNotifyLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val notificationLiveData = MutableLiveData>()
+ fun uploadNoticeStatus(fbNotificationReq: FbNotificationReq) {
+ MainRequest.uploadNoticeStatus(fbNotificationReq)
+ .observeForever {
+ notificationLiveData.value = it.getOrNull()
+ }
+ }
+
+ fun sendReport(message_id: String, title: String) {
+ MainRequest.sendReport(message_id, title).observeForever {}
+ }
+
+ private val noticeNumLiveData =
+ MutableLiveData>()
+ val noticeNumData: MutableLiveData> get() = noticeNumLiveData
+ fun noticeNum() {
+ MainRequest.noticeNum().observeForever { result ->
+ noticeNumLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val getPaySettingLiveData = MutableLiveData>()
+ val getPaySettingData: MutableLiveData> get() = getPaySettingLiveData
+ fun getPaySetting(
+ short_play_id: Int?,
+ video_id: Int?
+ ) {
+ MainRequest.getPaySetting(short_play_id, video_id).observeForever { result ->
+ getPaySettingLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val restorePaidLiveData = MutableLiveData>()
+ val restorePaidData: MutableLiveData> get() = restorePaidLiveData
+ fun restorePaid(examplePayReq: PayReq?) {
+ MainRequest.doGooglePaid(examplePayReq).observeForever { result ->
+ restorePaidLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val createOrderLiveData = MutableLiveData>()
+ val createOrderData: MutableLiveData> get() = createOrderLiveData
+ fun createOrder(createOrderReq: CreateOrderReq) {
+ MainRequest.doCreateOrder(createOrderReq).observeForever { result ->
+ createOrderLiveData.value = result.getOrNull()
+ }
+ }
+
+ private val googlePaidLiveData = MutableLiveData