Merge branch 'feature/update-video-view' into 'master'

Feature/update video view

See merge request agosto182/p2play!13
This commit is contained in:
Ivan Agosto 2024-03-28 02:54:14 +00:00
commit a3cd0b92ed
20 changed files with 226 additions and 68 deletions

View File

@ -6,14 +6,13 @@ plugins {
} }
android { android {
compileSdkVersion 30 compileSdkVersion 32
defaultConfig { defaultConfig {
applicationId "org.libre.agosto.p2play" applicationId "org.libre.agosto.p2play"
minSdkVersion 26 minSdkVersion 26
//noinspection OldTargetApi targetSdkVersion 32
targetSdkVersion 28 versionCode 9
versionCode 8 versionName "0.6.0"
versionName "0.5.2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@ -22,7 +21,6 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
} }
buildToolsVersion '30.0.2'
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
@ -31,6 +29,7 @@ android {
checkReleaseBuilds false checkReleaseBuilds false
abortOnError false abortOnError false
} }
namespace 'org.libre.agosto.p2play'
} }
dependencies { dependencies {
@ -40,7 +39,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.4.0' implementation 'com.google.android.material:material:1.6.0'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.5.2' androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="org.libre.agosto.p2play">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@ -13,10 +12,12 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.P2play"> android:theme="@style/Theme.P2play">
<activity android:name=".ChannelActivity" <activity android:name=".ChannelActivity"
android:theme="@style/Theme.P2play.NoActionBar" /> android:theme="@style/Theme.P2play.NoActionBar"
android:exported="false" />
<activity <activity
android:name=".SplashActivity" android:name=".SplashActivity"
android:theme="@style/Theme.P2play.NoActionBar"> android:theme="@style/Theme.P2play.NoActionBar"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@ -25,22 +26,26 @@
</activity> </activity>
<activity <activity
android:name=".HostActivity" android:name=".HostActivity"
android:theme="@style/Theme.P2play.NoActionBar"/> android:theme="@style/Theme.P2play.NoActionBar"
android:exported="false" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:theme="@style/Theme.P2play.NoActionBar" /> android:theme="@style/Theme.P2play.NoActionBar"
android:exported="false" />
<activity <activity
android:name=".ReproductorActivity" android:name=".ReproductorActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:theme="@style/Theme.P2play.NoActionBar" /> android:theme="@style/Theme.P2play.NoActionBar"
<activity android:name=".LoginActivity" /> android:exported="false" />
<activity android:name=".RegisterActivity" /> <activity android:name=".LoginActivity" android:exported="false" />
<activity android:name=".AboutActivity" /> <activity android:name=".RegisterActivity" android:exported="false" />
<activity android:name=".AboutActivity" android:exported="false" />
<activity <activity
android:name=".SettingsActivity" android:name=".SettingsActivity"
android:label="@string/title_activity_settings" android:label="@string/title_activity_settings"
android:theme="@style/Theme.P2play"/> android:theme="@style/Theme.P2play"
android:exported="false"/>
</application> </application>
</manifest> </manifest>

View File

@ -50,8 +50,6 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
.setAction("Action", null).show() .setAction("Action", null).show()
} */ } */
val toggle = ActionBarDrawerToggle(this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) val toggle = ActionBarDrawerToggle(this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer_layout.addDrawerListener(toggle) drawer_layout.addDrawerListener(toggle)
toggle.syncState() toggle.syncState()
@ -376,6 +374,8 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
myMenu.findItem(R.id.action_logout).isVisible = true myMenu.findItem(R.id.action_logout).isVisible = true
} }
} else {
nav_view.menu.findItem(R.id.ml).isVisible = false
} }
} }
@ -394,7 +394,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
this.refresh() this.refresh()
ManagerSingleton.Toast(getString(R.string.logout_msg), this) ManagerSingleton.Toast(getString(R.string.logout_msg), this)
setSideData()
} }
private fun loadMore(){ private fun loadMore(){

View File

@ -1,8 +1,6 @@
package org.libre.agosto.p2play package org.libre.agosto.p2play
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.graphics.Bitmap import android.graphics.Bitmap
@ -96,7 +94,7 @@ class ReproductorActivity : AppCompatActivity() {
userImg.setOnClickListener { userImg.setOnClickListener {
val intent = Intent(this, ChannelActivity::class.java) val intent = Intent(this, ChannelActivity::class.java)
intent.putExtra("channel", video.getAccount()) intent.putExtra("channel", video.getChannel())
startActivity(intent) startActivity(intent)
} }
} }
@ -105,7 +103,7 @@ class ReproductorActivity : AppCompatActivity() {
AsyncTask.execute { AsyncTask.execute {
if (Looper.myLooper() == null) if (Looper.myLooper() == null)
Looper.prepare() Looper.prepare()
val res = this._actions.subscribe(ManagerSingleton.token.token, video.getAccount()) val res = this._actions.subscribe(ManagerSingleton.token.token, video.getChannel())
if (res == 1) { if (res == 1) {
runOnUiThread { runOnUiThread {
ManagerSingleton.Toast(getString(R.string.subscribeMsg), this) ManagerSingleton.Toast(getString(R.string.subscribeMsg), this)
@ -119,7 +117,7 @@ class ReproductorActivity : AppCompatActivity() {
AsyncTask.execute { AsyncTask.execute {
if (Looper.myLooper() == null) if (Looper.myLooper() == null)
Looper.prepare() Looper.prepare()
val res = this._actions.unSubscribe(ManagerSingleton.token.token, video.getAccount()) val res = this._actions.unSubscribe(ManagerSingleton.token.token, video.getChannel())
if (res == 1) { if (res == 1) {
runOnUiThread { runOnUiThread {
ManagerSingleton.Toast(getString(R.string.unSubscribeMsg), this) ManagerSingleton.Toast(getString(R.string.unSubscribeMsg), this)

View File

@ -1,6 +1,7 @@
package org.libre.agosto.p2play.adapters package org.libre.agosto.p2play.adapters
import android.content.Context import android.content.Context
import android.content.Intent
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import android.text.Html import android.text.Html
import android.view.LayoutInflater import android.view.LayoutInflater
@ -9,6 +10,7 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.view_video.view.userImg
import org.libre.agosto.p2play.* import org.libre.agosto.p2play.*
import org.libre.agosto.p2play.models.CommentaryModel import org.libre.agosto.p2play.models.CommentaryModel
@ -42,6 +44,7 @@ class CommentariesAdapter(private val myDataset: ArrayList<CommentaryModel>) :
// create a new view // create a new view
val view = LayoutInflater.from(parent.context) val view = LayoutInflater.from(parent.context)
.inflate(R.layout.view_commentary, parent, false) as View .inflate(R.layout.view_commentary, parent, false) as View
// set the view's size, margins, paddings and layout parameters // set the view's size, margins, paddings and layout parameters
return ViewHolder(view) return ViewHolder(view)
} }
@ -63,6 +66,12 @@ class CommentariesAdapter(private val myDataset: ArrayList<CommentaryModel>) :
holder.commentary.text = Html.fromHtml(myDataset[position].commentary) holder.commentary.text = Html.fromHtml(myDataset[position].commentary)
// TODO: Support for view and account (is different than a video channel)
// holder.userImg.setOnClickListener {
// val intent = Intent(holder.context, ChannelActivity::class.java)
// intent.putExtra("channel", myDataset[position].getAccount())
// holder.context.startActivity(intent)
// }
} }
// Return the size of your dataset (invoked by the layout manager) // Return the size of your dataset (invoked by the layout manager)

View File

@ -10,6 +10,7 @@ import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import org.libre.agosto.p2play.* import org.libre.agosto.p2play.*
import org.libre.agosto.p2play.helpers.mapSeconds
import org.libre.agosto.p2play.models.VideoModel import org.libre.agosto.p2play.models.VideoModel
import java.io.Serializable import java.io.Serializable
@ -27,6 +28,8 @@ class VideosAdapter(private val myDataset: ArrayList<VideoModel>) :
val tittle: TextView val tittle: TextView
val description: TextView val description: TextView
val context: Context val context: Context
val duration: TextView
val isLive: TextView
init { init {
// Define click listener for the ViewHolder's View // Define click listener for the ViewHolder's View
@ -35,6 +38,8 @@ class VideosAdapter(private val myDataset: ArrayList<VideoModel>) :
thumb = view.findViewById(R.id.thumb) thumb = view.findViewById(R.id.thumb)
userImg = view.findViewById(R.id.userImg) userImg = view.findViewById(R.id.userImg)
context = view.context context = view.context
duration = view.findViewById(R.id.duration)
isLive = view.findViewById(R.id.isLive)
} }
} }
@ -52,16 +57,17 @@ class VideosAdapter(private val myDataset: ArrayList<VideoModel>) :
// - get element from your dataset at this position // - get element from your dataset at this position
// - replace the contents of the view with that element // - replace the contents of the view with that element
holder.tittle.text = myDataset[position].name holder.tittle.text = myDataset[position].name
holder.tittle.setOnClickListener {
this.launchChannelActivity(myDataset[position] as Serializable, holder.context)
}
Picasso.get().load("https://"+ManagerSingleton.url+myDataset[position].thumbUrl).into(holder.thumb) Picasso.get().load("https://"+ManagerSingleton.url+myDataset[position].thumbUrl).into(holder.thumb)
holder.thumb.setOnClickListener { holder.thumb.setOnClickListener {
val intent = Intent(holder.context, ReproductorActivity::class.java) this.launchChannelActivity(myDataset[position] as Serializable, holder.context)
intent.putExtra("video", myDataset[position] as Serializable)
holder.context.startActivity(intent)
} }
holder.userImg.setOnClickListener { holder.userImg.setOnClickListener {
val intent = Intent(holder.context, ChannelActivity::class.java) val intent = Intent(holder.context, ChannelActivity::class.java)
intent.putExtra("channel", myDataset[position].getAccount()) intent.putExtra("channel", myDataset[position].getChannel())
holder.context.startActivity(intent) holder.context.startActivity(intent)
} }
@ -71,20 +77,16 @@ class VideosAdapter(private val myDataset: ArrayList<VideoModel>) :
Picasso.get().load(R.drawable.default_avatar).into(holder.userImg) Picasso.get().load(R.drawable.default_avatar).into(holder.userImg)
val viewsText = holder.context.getString(R.string.view_text) val viewsText = holder.context.getString(R.string.view_text)
var timeText = holder.context.getString(R.string.timeSec_text)
var timeString = myDataset[position].duration.toString()
val seconds = myDataset[position].duration.toInt(); val seconds = myDataset[position].duration.toInt();
if(seconds > 60 && seconds < (60 * 60)){ val timeString = mapSeconds(seconds)
timeText = holder.context.getString(R.string.timeMin_text)
timeString = (seconds / 60).toString() + ":" + (seconds % 60).toString()
}
else if(seconds > (60 * 60)){
timeText = holder.context.getString(R.string.timeHrs_text)
timeString = (seconds / 60 / 60).toString() + ":" + (seconds / 60 % 60).toString()
}
holder.description.text = myDataset[position].username+" - "+myDataset[position].views+" "+viewsText+" - "+timeString+" "+timeText holder.duration.text = timeString
holder.description.text = myDataset[position].username+" - "+myDataset[position].views+" "+viewsText
if (myDataset[position].isLive) {
holder.isLive.visibility = View.VISIBLE
}
} }
// Return the size of your dataset (invoked by the layout manager) // Return the size of your dataset (invoked by the layout manager)
@ -101,5 +103,9 @@ class VideosAdapter(private val myDataset: ArrayList<VideoModel>) :
notifyItemRangeInserted(lastPos, newItems.size) notifyItemRangeInserted(lastPos, newItems.size)
} }
private fun launchChannelActivity (data: Serializable, context: Context) {
val intent = Intent(context, ReproductorActivity::class.java)
intent.putExtra("video", data)
context.startActivity(intent)
}
} }

View File

@ -10,8 +10,6 @@ import java.net.HttpURLConnection
import java.net.URL import java.net.URL
open class Client { open class Client {
protected fun _newCon(uri: String, method: String, token: String = ""): HttpURLConnection { protected fun _newCon(uri: String, method: String, token: String = ""): HttpURLConnection {
val url = URL("https://${ManagerSingleton.url}/api/v1/$uri") val url = URL("https://${ManagerSingleton.url}/api/v1/$uri")
val con = url.openConnection() as HttpURLConnection val con = url.openConnection() as HttpURLConnection
@ -67,5 +65,4 @@ open class Client {
return keys return keys
} }
} }

View File

@ -0,0 +1,20 @@
package org.libre.agosto.p2play.helpers
fun mapSeconds (inputSeconds: Int): String {
val seconds = (inputSeconds % 60)
var minutes = inputSeconds / 60
var hours = 0
if (minutes > 60) {
hours = minutes / 60
minutes = minutes % 60
}
var result = minutes.toString().padStart(2, '0') + ":" + seconds.toString().padStart(2, '0')
if (hours > 0) {
result = hours.toString().padStart(2, '0') + ":" + result
}
return result
}

View File

@ -11,7 +11,8 @@ class CommentaryModel (
var userImageUrl: String = "", var userImageUrl: String = "",
var commentary: String = "", var commentary: String = "",
var userHost: String = "", var userHost: String = "",
var replies: Int = 0 var replies: Int = 0,
var nameChannel: String = ""
) { ) {
fun parseCommentary(data: JsonReader) { fun parseCommentary(data: JsonReader) {
data.beginObject() data.beginObject()
@ -46,6 +47,7 @@ class CommentaryModel (
} }
"uuid" -> this.userUuid = data.nextString() "uuid" -> this.userUuid = data.nextString()
"host" -> this.userHost = data.nextString() "host" -> this.userHost = data.nextString()
"name" -> this.nameChannel = data.nextString()
else -> data.skipValue() else -> data.skipValue()
} }
} }
@ -56,4 +58,9 @@ class CommentaryModel (
} }
data.endObject() data.endObject()
} }
fun getAccount(): String {
return "$nameChannel@$userHost"
}
} }

View File

@ -0,0 +1,25 @@
package org.libre.agosto.p2play.models
import android.util.JsonReader
class StreamingModel(
var playlistUrl: String = "",
var segmentsSha256Url: String = "",
// TODO: Download Files
) {
fun parse(data: JsonReader) {
data.beginObject()
while (data.hasNext()) {
val key = data.nextName()
when (key.toString()) {
"playlistUrl"->{
this.playlistUrl = data.nextString()
}
"segmentsSha256Url"->{
this.segmentsSha256Url = data.nextString()
}
else -> data.skipValue()
}
}
}
}

View File

@ -17,9 +17,11 @@ class VideoModel(
var views: Number = 0, var views: Number = 0,
var userUuid: String = "", var userUuid: String = "",
var userHost: String = "", var userHost: String = "",
var nameChannel: String = "" var nameChannel: String = "",
var isLive: Boolean = false,
var streamingData: StreamingModel? = null
):Serializable { ):Serializable {
fun getAccount(): String { fun getChannel(): String {
return "$nameChannel@$userHost" return "$nameChannel@$userHost"
} }
@ -55,6 +57,18 @@ class VideoModel(
"views"->{ "views"->{
this.views = data.nextInt() this.views = data.nextInt()
} }
"isLive"-> {
this.isLive = data.nextBoolean()
}
"streamingPlaylists"-> {
data.beginArray()
if (data.hasNext()) {
val streamingData = StreamingModel()
streamingData.parse(data)
this.streamingData = streamingData
}
data.endArray()
}
"channel"->{ "channel"->{
data.beginObject() data.beginObject()
while (data.hasNext()){ while (data.hasNext()){

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp" />
<!-- This is the border color -->
<!--- This is the background color -->
<solid android:color="@color/colorDislike" />
</shape>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp" />
<!-- This is the border color -->
<!--- This is the background color -->
<solid android:color="?attr/colorSecondary" />
</shape>

View File

@ -14,12 +14,55 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView <ImageView
android:id="@+id/thumb" android:id="@+id/thumb"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="230dp" android:layout_height="230dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@android:drawable/ic_menu_gallery" /> app:srcCompat="@android:drawable/ic_menu_gallery" />
<TextView
android:id="@+id/isLive"
android:layout_width="65dp"
android:layout_height="19dp"
android:layout_marginStart="8dp"
android:layout_marginBottom="16dp"
android:background="@drawable/live_shape"
android:ems="10"
android:paddingHorizontal="3dp"
android:text="@string/is_live_video"
android:textAlignment="center"
android:textColor="@color/durationColor"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="invisible" />
<TextView
android:id="@+id/duration"
android:layout_width="65dp"
android:layout_height="19dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
android:textColor="?attr/colorOnSecondary"
android:background="@drawable/round_text"
android:ems="10"
android:text="00:00"
android:paddingHorizontal="3dp"
android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="63dp" android:layout_height="63dp"

View File

@ -48,6 +48,7 @@
<string name="timeMin_text">minutos</string> <string name="timeMin_text">minutos</string>
<string name="timeHrs_text">horas</string> <string name="timeHrs_text">horas</string>
<string name="nav_header_title">Inicia session</string> <string name="nav_header_title">Inicia session</string>
<string name="is_live_video">En vivo</string>
<!-- Toast msg --> <!-- Toast msg -->
<string name="logout_msg">Te has desconectado</string> <string name="logout_msg">Te has desconectado</string>
<!-- End Main strings --> <!-- End Main strings -->

View File

@ -11,6 +11,9 @@
<color name="colorDislike">#ec020e</color> <color name="colorDislike">#ec020e</color>
<color name="colorProfile">#262626</color> <color name="colorProfile">#262626</color>
<color name="durationBackground">#88000000</color>
<color name="durationColor">#ffffff</color>
<color name="seed">#f16805</color> <color name="seed">#f16805</color>
<color name="md_theme_light_primary">#9F4200</color> <color name="md_theme_light_primary">#9F4200</color>
<color name="md_theme_light_onPrimary">#FFFFFF</color> <color name="md_theme_light_onPrimary">#FFFFFF</color>

View File

@ -9,7 +9,6 @@
<string name="charging">Loading…</string> <string name="charging">Loading…</string>
<!-- End Global string --> <!-- End Global string -->
<!-- Start About strings --> <!-- Start About strings -->
<string name="aboutGitUrl" translatable="false">https://gitlab.com/agosto182/p2play/</string> <string name="aboutGitUrl" translatable="false">https://gitlab.com/agosto182/p2play/</string>
<string name="aboutGnuUrl" translatable="false">https://personaljournal.ca/p2play/</string> <string name="aboutGnuUrl" translatable="false">https://personaljournal.ca/p2play/</string>
@ -60,6 +59,7 @@
<string name="timeHrs_text">hours</string> <string name="timeHrs_text">hours</string>
<string name="nav_header_title">Log In</string> <string name="nav_header_title">Log In</string>
<string name="nav_header_subtitle" translatable="false">P2Play</string> <string name="nav_header_subtitle" translatable="false">P2Play</string>
<string name="is_live_video">Live</string>
<!-- Toast msg --> <!-- Toast msg -->
<string name="logout_msg">You are now disconnected</string> <string name="logout_msg">You are now disconnected</string>
<!-- End Main strings --> <!-- End Main strings -->

View File

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.6.20' ext.kotlin_version = '1.6.21'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.4.2' classpath 'com.android.tools.build:gradle:8.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

View File

@ -9,6 +9,9 @@
org.gradle.jvmargs=-Xmx1536m org.gradle.jvmargs=-Xmx1536m
android.enableJetifier=true android.enableJetifier=true
android.useAndroidX=true android.useAndroidX=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit

View File

@ -1,6 +1,6 @@
#Mon Mar 18 13:17:32 CST 2024 #Mon Mar 18 13:17:32 CST 2024
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists