diff --git a/README.md b/README.md index 8d8c699..7ebdab1 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Comming soon! ## Features - Show recent, popular and local list of videos. -- Reproduce videos (very simple) +- Reproduce videos - Login and register in your instance - Pull to refresh - Show uploaded videos @@ -34,12 +34,12 @@ Comming soon! - Splash screen - Search videos - Infinite scroll - -## What to do? (in next version) - - Share videos - Report videos - Peertube profiles + +## What to do? (in next version) + - History of videos watched - Notifications diff --git a/app/build.gradle b/app/build.gradle index 7cd9331..8c8b1b7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,11 +7,12 @@ apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 27 defaultConfig { - applicationId "mx.agosto182.p2play" + applicationId "org.libre.agosto.p2play" minSdkVersion 21 + //noinspection OldTargetApi targetSdkVersion 27 - versionCode 4 - versionName "0.3" + versionCode 5 + versionName "0.4" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dd6f1cb..e03938d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,8 @@ android:roundIcon="@mipmap/ic_p2play" android:supportsRtl="true" android:theme="@style/P2playTheme"> + @@ -27,8 +29,9 @@ android:theme="@style/P2playTheme.NoActionBar" /> + android:theme="@style/P2playTheme.noBar" /> diff --git a/app/src/main/java/org/libre/agosto/p2play/ChannelActivity.kt b/app/src/main/java/org/libre/agosto/p2play/ChannelActivity.kt new file mode 100644 index 0000000..dc58c7b --- /dev/null +++ b/app/src/main/java/org/libre/agosto/p2play/ChannelActivity.kt @@ -0,0 +1,149 @@ +package org.libre.agosto.p2play + +import android.os.AsyncTask +import android.support.v7.app.AppCompatActivity +import android.os.Bundle +import android.support.v7.widget.LinearLayoutManager +import android.support.v7.widget.RecyclerView +import android.view.View +import com.squareup.picasso.Picasso +import kotlinx.android.synthetic.main.activity_channel.* +import org.libre.agosto.p2play.adapters.VideosAdapter +import org.libre.agosto.p2play.ajax.Actions +import org.libre.agosto.p2play.ajax.Channels +import org.libre.agosto.p2play.ajax.Videos +import org.libre.agosto.p2play.models.ChannelModel +import org.libre.agosto.p2play.models.VideoModel + +class ChannelActivity : AppCompatActivity() { + private lateinit var channelId: String + private lateinit var channel: ChannelModel + private var isSubcribed: Boolean = false + private val _channel = Channels() + private val _videos = Videos() + private val _actions = Actions() + + private lateinit var recyclerView: RecyclerView + private lateinit var viewAdapter: RecyclerView.Adapter + private lateinit var viewManager: RecyclerView.LayoutManager + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_channel) + + channelId = this.intent.extras.getString("channel") + + viewManager = LinearLayoutManager(this) + + subcriptionBtn.setOnClickListener { + subscribeAction() + } + } + + override fun onResume() { + super.onResume() + + getChannel() + getSubscription() + getVideos() + + if(ManagerSingleton.user.status == 1) { + subcriptionBtn.visibility = View.VISIBLE + getSubscription() + } + } + + private fun getChannel() { + AsyncTask.execute { + channel = _channel.getChannelInfo(channelId) + runOnUiThread { + usernameProfile.text = channel.name + hostTxt.text = channel.host + subcriptionsTxt.text = channel.followers.toString() + if(channel.channelImg != "") + Picasso.get().load("https://${ManagerSingleton.url}${channel.channelImg}").into(channelImg) + } + } + } + + private fun subscribe() { + AsyncTask.execute { + val res = _actions.subscribe(ManagerSingleton.token.token, channel.getAccount()) + runOnUiThread { + if(res == 1){ + subcriptionBtn.text = getString(R.string.unSubscribeBtn) + ManagerSingleton.Toast(getString(R.string.subscribeMsg), this) + getSubscription() + } + else { + ManagerSingleton.Toast(getString(R.string.errorMsg), this) + } + } + } + } + + private fun unSubscribe() { + AsyncTask.execute { + val res = _actions.unSubscribe(ManagerSingleton.token.token, channel.getAccount()) + runOnUiThread { + if(res == 1){ + subcriptionBtn.text = getString(R.string.subscribeBtn) + ManagerSingleton.Toast(getString(R.string.unSubscribeMsg), this) + getSubscription() + } + else { + ManagerSingleton.Toast(getString(R.string.errorMsg), this) + } + } + } + } + + private fun subscribeAction() { + if(isSubcribed) + unSubscribe() + else + subscribe() + } + + private fun getSubscription() { + AsyncTask.execute { + isSubcribed = _actions.getSubscription(ManagerSingleton.token.token, channel.getAccount()) + runOnUiThread { + if(isSubcribed){ + subcriptionBtn.text = getText(R.string.unSubscribeBtn) + } + else { + subcriptionBtn.text = getText(R.string.subscribeBtn) + } + } + } + } + + private fun getVideos() { + AsyncTask.execute { + val videos = _videos.channelVideos(channel.getAccount(), 0) + runOnUiThread { + initRecycler(videos) + } + } + } + + // Generic function for set data to RecyclerView + private fun initRecycler(data: ArrayList){ + // val data = arrayListOf() + viewAdapter = VideosAdapter(data) + + recyclerView = findViewById(R.id.listVideosChannel).apply { + // use this setting to improve performance if you know that changes + // in content do not change the layout size of the RecyclerView + setHasFixedSize(true) + + // use a linear layout manager + layoutManager = viewManager + + // specify an viewAdapter (see also next example) + adapter = viewAdapter + } + // swipeContainer.isRefreshing = false + } +} \ No newline at end of file diff --git a/app/src/main/java/org/libre/agosto/p2play/MainActivity.kt b/app/src/main/java/org/libre/agosto/p2play/MainActivity.kt index 97a823f..1ef6fa8 100644 --- a/app/src/main/java/org/libre/agosto/p2play/MainActivity.kt +++ b/app/src/main/java/org/libre/agosto/p2play/MainActivity.kt @@ -60,7 +60,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte // Init RecyclerView this.initRecycler() - this.getLastVideos() + this.getTrengindVideos() swipeContainer.setOnRefreshListener { this.refresh() @@ -127,6 +127,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte when(section){ "local" -> this.getLocalVideos() "popular" -> this.getPopularVideos() + "trending" -> this.getTrengindVideos() "last" -> this.getLastVideos() "sub" -> this.getSubscriptionVideos() "search" -> this.searchVideos() @@ -182,6 +183,19 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte } } + // Trending videos + private fun getTrengindVideos(){ + swipeContainer.isRefreshing = true + section = "trending" + setTitle(R.string.title_trending) + AsyncTask.execute { + val videos = client.getTrendingVideos(this.pagination) + runOnUiThread { + this.addVideos(videos) + } + } + } + // Local videos private fun getLocalVideos(){ swipeContainer.isRefreshing = true @@ -286,19 +300,12 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte // item.isChecked = true when (item.itemId) { - R.id.nav_subscriptions->{ - getSubscriptionVideos() - } - R.id.nav_popular-> { - getPopularVideos() - } - R.id.nav_recent-> { - getLastVideos() - } - R.id.nav_local-> { - getLocalVideos() - } - R.id.nav_about-> { + R.id.nav_subscriptions -> getSubscriptionVideos() + R.id.nav_popular -> getPopularVideos() + R.id.nav_trending -> getTrengindVideos() + R.id.nav_recent -> getLastVideos() + R.id.nav_local -> getLocalVideos() + R.id.nav_about -> { val intent = Intent(this, AboutActivity::class.java) startActivity(intent) } @@ -320,6 +327,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte if(ManagerSingleton.user.avatar!="" && side_imageView != null) Picasso.get().load("https://"+ManagerSingleton.url+ManagerSingleton.user.avatar).into(side_imageView) side_imageView?.setOnClickListener { + pagination = 0 getMyVideos() drawer_layout.closeDrawer(GravityCompat.START) } @@ -355,6 +363,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte when(section){ "local" -> this.getLocalVideos() "popular" -> this.getPopularVideos() + "trending" -> this.getTrengindVideos() "last" -> this.getLastVideos() "sub" -> this.getSubscriptionVideos() "search" -> this.searchVideos() diff --git a/app/src/main/java/org/libre/agosto/p2play/ReproductorActivity.kt b/app/src/main/java/org/libre/agosto/p2play/ReproductorActivity.kt index 365168c..575ea1d 100644 --- a/app/src/main/java/org/libre/agosto/p2play/ReproductorActivity.kt +++ b/app/src/main/java/org/libre/agosto/p2play/ReproductorActivity.kt @@ -1,6 +1,10 @@ package org.libre.agosto.p2play +import android.annotation.SuppressLint import android.app.Activity +import android.content.DialogInterface +import android.content.Intent +import android.content.pm.ActivityInfo import android.graphics.Bitmap import android.graphics.BitmapFactory import android.os.AsyncTask @@ -8,30 +12,40 @@ import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.os.Looper import android.support.v4.content.ContextCompat +import android.support.v7.app.AlertDialog import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.util.Log import android.view.View +import android.view.WindowManager import android.webkit.WebChromeClient +import android.widget.EditText import android.widget.FrameLayout import com.squareup.picasso.Picasso import kotlinx.android.synthetic.main.activity_reproductor.* import org.libre.agosto.p2play.adapters.CommentariesAdapter import org.libre.agosto.p2play.ajax.Actions import org.libre.agosto.p2play.ajax.Comments +import org.libre.agosto.p2play.ajax.Videos import org.libre.agosto.p2play.models.CommentaryModel import org.libre.agosto.p2play.models.VideoModel + + + + class ReproductorActivity : AppCompatActivity() { - lateinit var video:VideoModel + lateinit var video: VideoModel private val _actions: Actions = Actions() private val client: Comments = Comments() + private val videos: Videos = Videos() // Commentaries adapter values private lateinit var recyclerView: RecyclerView private lateinit var viewAdapter: RecyclerView.Adapter<*> private lateinit var viewManager: RecyclerView.LayoutManager + @SuppressLint("SetJavaScriptEnabled", "SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_reproductor) @@ -46,24 +60,25 @@ class ReproductorActivity : AppCompatActivity() { videoView.settings.domStorageEnabled = true try { - this.video = this.intent.extras.getSerializable("video") as VideoModel + this.video = this.intent.extras.getSerializable("video") as VideoModel tittleVideoTxt.text = this.video.name - viewsTxt.text = this.video.views.toString() + ' ' + getString(R.string.view_text) + viewsTxt.text = "${this.video.views} ${getString(R.string.view_text)}" userTxt.text = this.video.username - descriptionVideoTxt.text = this.video.description.toString() - hostTxt.text = this.video.userHost.toString() + descriptionVideoTxt.text = this.video.description + val haveDescription = this.video.description.endsWith("...") + if (haveDescription) { + showMoreBtn.visibility = View.VISIBLE + } + hostTxt.text = this.video.userHost // Check if user had profile image - if(this.video.userImageUrl!="") - Picasso.get().load("https://"+ManagerSingleton.url+this.video.userImageUrl).into(userImg) + if (this.video.userImageUrl != "") + Picasso.get().load("https://" + ManagerSingleton.url + this.video.userImageUrl).into(userImg) // Load the video - videoView.loadUrl("https://"+ManagerSingleton.url+this.video.embedUrl) + videoView.loadUrl("https://" + ManagerSingleton.url + this.video.embedUrl) - - } - catch (err:Exception){ + } catch (err: Exception) { err.printStackTrace() - Log.d("Error", err?.message) } viewManager = LinearLayoutManager(this) @@ -75,14 +90,22 @@ class ReproductorActivity : AppCompatActivity() { likeLayout.setOnClickListener { rate("like") } dislikeLayout.setOnClickListener { rate("dislike") } commentaryBtn.setOnClickListener { makeComment() } + showMoreBtn.setOnClickListener { getDescription() } + shareLayout.setOnClickListener { shareIntent() } + reportLayout.setOnClickListener { reportIntent() } + + userImg.setOnClickListener { + val intent = Intent(this, ChannelActivity::class.java) + intent.putExtra("channel", video.getAccount()) + startActivity(intent) + } } - private fun subscribe(){ - val account = this.video.nameChannel+"@"+this.video.userHost + private fun subscribe() { AsyncTask.execute { if (Looper.myLooper() == null) Looper.prepare() - val res = this._actions.subscribe(ManagerSingleton.token.token, account) + val res = this._actions.subscribe(ManagerSingleton.token.token, video.getAccount()) if (res == 1) { runOnUiThread { ManagerSingleton.Toast(getString(R.string.subscribeMsg), this) @@ -92,12 +115,11 @@ class ReproductorActivity : AppCompatActivity() { } } - private fun unSubscribe(){ - val account = this.video.nameChannel+"@"+this.video.userHost + private fun unSubscribe() { AsyncTask.execute { if (Looper.myLooper() == null) Looper.prepare() - val res = this._actions.unSubscribe(ManagerSingleton.token.token, account) + val res = this._actions.unSubscribe(ManagerSingleton.token.token, video.getAccount()) if (res == 1) { runOnUiThread { ManagerSingleton.Toast(getString(R.string.unSubscribeMsg), this) @@ -107,7 +129,7 @@ class ReproductorActivity : AppCompatActivity() { } } - private fun rate(rate: String){ + private fun rate(rate: String) { AsyncTask.execute { if (Looper.myLooper() == null) Looper.prepare() @@ -115,11 +137,10 @@ class ReproductorActivity : AppCompatActivity() { if (res == 1) { runOnUiThread { ManagerSingleton.Toast(getString(R.string.rateMsg), this) - if(rate=="like"){ + if (rate == "like") { textViewLike.setTextColor(ContextCompat.getColor(this, R.color.colorLike)) textViewDislike.setTextColor(ContextCompat.getColor(this, R.color.primary_dark_material_light)) - } - else if(rate=="dislike"){ + } else if (rate == "dislike") { textViewDislike.setTextColor(ContextCompat.getColor(this, R.color.colorDislike)) textViewLike.setTextColor(ContextCompat.getColor(this, R.color.primary_dark_material_light)) } @@ -128,13 +149,13 @@ class ReproductorActivity : AppCompatActivity() { } } - private fun getRate(){ + private fun getRate() { AsyncTask.execute { if (Looper.myLooper() == null) Looper.prepare() val rate = this._actions.getRate(ManagerSingleton.token.token, this.video.id) runOnUiThread { - when (rate){ + when (rate) { "like" -> { textViewLike.setTextColor(ContextCompat.getColor(this, R.color.colorLike)) textViewDislike.setTextColor(ContextCompat.getColor(this, R.color.primary_dark_material_light)) @@ -152,8 +173,8 @@ class ReproductorActivity : AppCompatActivity() { } } - private fun getSubscription(){ - val account = this.video.nameChannel+"@"+this.video.userHost + private fun getSubscription() { + val account = this.video.nameChannel + "@" + this.video.userHost AsyncTask.execute { if (Looper.myLooper() == null) Looper.prepare() @@ -164,12 +185,11 @@ class ReproductorActivity : AppCompatActivity() { } } - private fun changeSubscribeBtn(subscribed: Boolean){ - if(subscribed){ + private fun changeSubscribeBtn(subscribed: Boolean) { + if (subscribed) { subscribeBtn.text = getText(R.string.unSubscribeBtn) subscribeBtn.setOnClickListener { this.unSubscribe() } - } - else{ + } else { subscribeBtn.text = getText(R.string.subscribeBtn) subscribeBtn.setOnClickListener { this.subscribe() } } @@ -202,7 +222,7 @@ class ReproductorActivity : AppCompatActivity() { } private fun makeComment() { - if(commentaryText.text.toString() == ""){ + if (commentaryText.text.toString() == "") { ManagerSingleton.Toast(getString(R.string.emptyCommentaryMsg), this) return } @@ -214,8 +234,7 @@ class ReproductorActivity : AppCompatActivity() { ManagerSingleton.Toast(getString(R.string.makedCommentaryMsg), this) commentaryText.text.clear() this.getComments() - } - else { + } else { ManagerSingleton.Toast(getString(R.string.errorCommentaryMsg), this) } } @@ -224,14 +243,70 @@ class ReproductorActivity : AppCompatActivity() { override fun onResume() { super.onResume() - if(ManagerSingleton.user.status == 1) { + if (ManagerSingleton.user.status == 1) { this.getRate() this.getSubscription() actionsLayout.visibility = View.VISIBLE subscribeBtn.visibility = View.VISIBLE commentaryLayout.visibility = View.VISIBLE - if(ManagerSingleton.user.avatar != ""){ - Picasso.get().load("https://"+ManagerSingleton.url+ManagerSingleton.user.avatar).into(userImgCom) + if (ManagerSingleton.user.avatar != "") { + Picasso.get().load("https://" + ManagerSingleton.url + ManagerSingleton.user.avatar).into(userImgCom) + } + } + } + + fun getDescription() { + AsyncTask.execute { + val fullDescription = this.videos.fullDescription(this.video.id) + runOnUiThread { + descriptionVideoTxt.text = fullDescription + showMoreBtn.visibility = View.GONE + } + } + } + + private fun shareIntent() { + val sendIntent: Intent = Intent().apply { + action = Intent.ACTION_SEND + putExtra(Intent.EXTRA_TEXT, "${video.name} ${video.getVideoUrl()}") + type = "text/plain" + } + startActivity(Intent.createChooser(sendIntent, resources.getText(R.string.shareBtn))) + } + + private fun reportIntent() { + val builder = AlertDialog.Builder(this) + // Get the layout inflater + val dialog = layoutInflater.inflate(R.layout.report_dialog, null) + + val inputReason = dialog.findViewById(R.id.reportText) + + // Inflate and set the layout for the dialog + // Pass null as the parent view because its going in the dialog layout + builder.setView(dialog) + // Add action buttons + .setPositiveButton(R.string.reportBtn) { dialog, id -> + val reason = inputReason.text.toString() + reportVideo(reason) + } + .setNegativeButton("Cancel") { dialog, id -> + dialog.cancel() + } + val alertDialog = builder.create() + alertDialog.show() + } + + private fun reportVideo(reason: String){ + AsyncTask.execute { + val res = _actions.reportVideo(video.id, reason, ManagerSingleton.token.token) + + runOnUiThread { + if(res) { + ManagerSingleton.Toast(getText(R.string.reportDialogMsg).toString(), this) + } + else { + ManagerSingleton.Toast(getText(R.string.errorMsg).toString(), this) + } } } } @@ -250,12 +325,22 @@ class ReproductorActivity : AppCompatActivity() { override fun onHideCustomView() { try { - (this@ReproductorActivity.window.decorView as FrameLayout).removeView(this.mCustomView) + this@ReproductorActivity.nonFullScreen.visibility = View.VISIBLE + this@ReproductorActivity.fullScreen.visibility = View.GONE + this@ReproductorActivity.fullScreen.removeView(this.mCustomView) this.mCustomView = null - this@ReproductorActivity.window.decorView.systemUiVisibility = this.mOriginalSystemUiVisibility - this@ReproductorActivity.requestedOrientation = this.mOriginalOrientation - this.mCustomViewCallback?.onCustomViewHidden() + + this.mCustomViewCallback!!.onCustomViewHidden() this.mCustomViewCallback = null + + this@ReproductorActivity.requestedOrientation = this.mOriginalOrientation + // this@ReproductorActivity.window.decorView.systemUiVisibility = this.mOriginalSystemUiVisibility + + val attrs = this@ReproductorActivity.window.attributes + attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN.inv() + attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON.inv() + window.attributes = attrs + this@ReproductorActivity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE } catch (err: Exception){ err.printStackTrace() @@ -272,8 +357,21 @@ class ReproductorActivity : AppCompatActivity() { this.mOriginalSystemUiVisibility = this@ReproductorActivity.window.decorView.systemUiVisibility this.mOriginalOrientation = this@ReproductorActivity.requestedOrientation this.mCustomViewCallback = paramCustomViewCallback - (this@ReproductorActivity.window.decorView as FrameLayout).addView(this.mCustomView, FrameLayout.LayoutParams(-1, -1)) - this@ReproductorActivity.window.decorView.systemUiVisibility = 3846 + val match_parent = WindowManager.LayoutParams.MATCH_PARENT + + this@ReproductorActivity.nonFullScreen.visibility = View.GONE + this@ReproductorActivity.fullScreen.visibility = View.VISIBLE + + this@ReproductorActivity.fullScreen.addView(paramView, FrameLayout.LayoutParams(match_parent, match_parent)) + + + val attrs = this@ReproductorActivity.window.attributes + attrs.flags = attrs.flags or WindowManager.LayoutParams.FLAG_FULLSCREEN + attrs.flags = attrs.flags or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + window.attributes = attrs + this@ReproductorActivity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LOW_PROFILE + + this@ReproductorActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE } catch (err: Exception){ err.printStackTrace() diff --git a/app/src/main/java/org/libre/agosto/p2play/adapters/CommentariesAdapter.kt b/app/src/main/java/org/libre/agosto/p2play/adapters/CommentariesAdapter.kt index 77a93df..96165ec 100644 --- a/app/src/main/java/org/libre/agosto/p2play/adapters/CommentariesAdapter.kt +++ b/app/src/main/java/org/libre/agosto/p2play/adapters/CommentariesAdapter.kt @@ -6,6 +6,7 @@ import android.content.Intent import android.graphics.drawable.Drawable import android.os.AsyncTask import android.support.v7.widget.RecyclerView +import android.text.Html import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -13,10 +14,7 @@ import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import com.squareup.picasso.Picasso -import org.libre.agosto.p2play.MainActivity -import org.libre.agosto.p2play.ManagerSingleton -import org.libre.agosto.p2play.R -import org.libre.agosto.p2play.ReproductorActivity +import org.libre.agosto.p2play.* import org.libre.agosto.p2play.models.CommentaryModel import org.libre.agosto.p2play.models.VideoModel import java.io.InputStream @@ -62,10 +60,16 @@ class CommentariesAdapter(private val myDataset: ArrayList) : // - replace the contents of the view with that element holder.username.text = myDataset[position].username + // holder.userImg.setOnClickListener { + // val intent = Intent(holder.context, ChannelActivity::class.java) + // intent.putExtra("channel", myDataset[position]) + // holder.context.startActivity(intent) + // } + if(myDataset[position].userImageUrl!="") Picasso.get().load("https://"+ManagerSingleton.url+myDataset[position].userImageUrl).into(holder.userImg); - holder.commentary.text = myDataset[position].commentary + holder.commentary.text = Html.fromHtml(myDataset[position].commentary) } diff --git a/app/src/main/java/org/libre/agosto/p2play/adapters/VideosAdapter.kt b/app/src/main/java/org/libre/agosto/p2play/adapters/VideosAdapter.kt index 4a5624c..8281661 100644 --- a/app/src/main/java/org/libre/agosto/p2play/adapters/VideosAdapter.kt +++ b/app/src/main/java/org/libre/agosto/p2play/adapters/VideosAdapter.kt @@ -13,10 +13,7 @@ import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import com.squareup.picasso.Picasso -import org.libre.agosto.p2play.MainActivity -import org.libre.agosto.p2play.ManagerSingleton -import org.libre.agosto.p2play.R -import org.libre.agosto.p2play.ReproductorActivity +import org.libre.agosto.p2play.* import org.libre.agosto.p2play.models.VideoModel import java.io.InputStream import java.io.Serializable @@ -69,6 +66,13 @@ class VideosAdapter(private val myDataset: ArrayList) : intent.putExtra("video", myDataset[position] as Serializable) holder.context.startActivity(intent) } + + holder.userImg.setOnClickListener { + val intent = Intent(holder.context, ChannelActivity::class.java) + intent.putExtra("channel", myDataset[position].getAccount()) + holder.context.startActivity(intent) + } + if(myDataset[position].userImageUrl!="") Picasso.get().load("https://"+ManagerSingleton.url+myDataset[position].userImageUrl).into(holder.userImg) else diff --git a/app/src/main/java/org/libre/agosto/p2play/ajax/Actions.kt b/app/src/main/java/org/libre/agosto/p2play/ajax/Actions.kt index 93b81da..47a0b47 100644 --- a/app/src/main/java/org/libre/agosto/p2play/ajax/Actions.kt +++ b/app/src/main/java/org/libre/agosto/p2play/ajax/Actions.kt @@ -6,7 +6,7 @@ import java.io.InputStreamReader class Actions: Client() { fun subscribe(token: String, account: String):Int{ - var con=this._newCon("users/me/subscriptions","POST", token) + val con = this._newCon("users/me/subscriptions","POST", token) val params:String= "uri=$account" con.outputStream.write(params.toByteArray()) var response = 0 @@ -21,11 +21,12 @@ class Actions: Client() { response = -1 } + con.disconnect() return response } fun unSubscribe(token: String, account: String):Int{ - var con=this._newCon("users/me/subscriptions/$account","DELETE", token) + val con = this._newCon("users/me/subscriptions/$account","DELETE", token) var response = 0 try { @@ -38,17 +39,18 @@ class Actions: Client() { response = -1 } + con.disconnect() return response } fun getSubscription(token: String, account: String): Boolean{ - var con=this._newCon("users/me/subscriptions/exist?uris=$account","GET", token) + val con = this._newCon("users/me/subscriptions/exist?uris=$account","GET", token) var isSubscribed = false try { if (con.responseCode == 200) { - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) data.beginObject() while (data.hasNext()){ val key = data.nextName() @@ -61,6 +63,7 @@ class Actions: Client() { } } } + data.close() } } catch (err: Exception){ @@ -68,12 +71,13 @@ class Actions: Client() { isSubscribed = false } + con.disconnect() return isSubscribed } fun rate(token: String, id_video: Int, rate: String):Int{ - var con=this._newCon("videos/$id_video/rate","PUT", token) - val params:String= "rating=$rate" + val con = this._newCon("videos/$id_video/rate","PUT", token) + val params = "rating=$rate" con.outputStream.write(params.toByteArray()) var response = 0 @@ -87,17 +91,18 @@ class Actions: Client() { response = -1 } + con.disconnect() return response } fun getRate(token: String, id_video: Int):String{ - var con=this._newCon("users/me/videos/$id_video/rating","GET", token) + val con = this._newCon("users/me/videos/$id_video/rating","GET", token) var rating = "none" try { if (con.responseCode == 200) { - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) data.beginObject() while (data.hasNext()){ val key = data.nextName() @@ -110,6 +115,7 @@ class Actions: Client() { } } } + con.disconnect() } } catch (err: Exception){ @@ -117,7 +123,25 @@ class Actions: Client() { rating = "none" } + con.disconnect() return rating } + fun reportVideo(videoId: Int, reason: String, token: String): Boolean { + val con = this._newCon("videos/$videoId/abuse", "POST", token) + val params = "reason=$reason" + con.outputStream.write(params.toByteArray()) + + var response = false + try { + if(con.responseCode == 200){ + response = true + } + } catch (err: Exception) { + err.printStackTrace() + response = false + } + + return response + } } \ No newline at end of file diff --git a/app/src/main/java/org/libre/agosto/p2play/ajax/Auth.kt b/app/src/main/java/org/libre/agosto/p2play/ajax/Auth.kt index bba67ec..fc88bdb 100644 --- a/app/src/main/java/org/libre/agosto/p2play/ajax/Auth.kt +++ b/app/src/main/java/org/libre/agosto/p2play/ajax/Auth.kt @@ -10,19 +10,19 @@ import org.libre.agosto.p2play.models.UserModel import java.io.InputStreamReader class Auth: Client() { - val stockParams = "grant_type=password" + private val stockParams = "grant_type=password" fun login(username: String, password: String, client_id: String, client_secret: String): TokenModel{ - var con = this._newCon("users/token","POST") - val params:String= "$stockParams&username=$username&password=$password&client_id=$client_id&client_secret=$client_secret" + val con = this._newCon("users/token","POST") + val params = "$stockParams&username=$username&password=$password&client_id=$client_id&client_secret=$client_secret" con.outputStream.write(params.toByteArray()) - var token = TokenModel() + val token = TokenModel() try { if(con.responseCode==200){ - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) data.beginObject() while(data.hasNext()){ @@ -35,6 +35,7 @@ class Auth: Client() { } data.endObject() + data.close() token.status = 1 } @@ -47,12 +48,13 @@ class Auth: Client() { token.status = 0 } + con.disconnect() return token } fun register(username: String, password: String, email: String): Int{ - var con = this._newCon("users/register","POST") - val params:String= "username=$username&password=$password&email=$email" + val con = this._newCon("users/register","POST") + val params = "username=$username&password=$password&email=$email" con.outputStream.write(params.toByteArray()) var response = 0 @@ -67,20 +69,21 @@ class Auth: Client() { response = -1 } + con.disconnect() return response } fun refreshToken(token: TokenModel, client_id: String, client_secret: String): TokenModel{ - var con = this._newCon("users/token", "POST", token.token) - val params:String = "refresh_token=${token.refresh_token}&response_type=code&grant_type=refresh_token&client_id=$client_id&client_secret=$client_secret" + val con = this._newCon("users/token", "POST", token.token) + val params = "refresh_token=${token.refresh_token}&response_type=code&grant_type=refresh_token&client_id=$client_id&client_secret=$client_secret" con.outputStream.write(params.toByteArray()) - var token = TokenModel() + // val token = TokenModel() try { if(con.responseCode==200){ - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) data.beginObject() while(data.hasNext()){ @@ -93,6 +96,7 @@ class Auth: Client() { } data.endObject() + data.close() token.status = 1 } @@ -105,19 +109,19 @@ class Auth: Client() { token.status = 0 } + con.disconnect() return token } fun me(token: String): UserModel{ - var con = this._newCon("users/me","GET", token) - - var user = UserModel() + val con = this._newCon("users/me","GET", token) + val user = UserModel() try { if(con.responseCode==200){ - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) data.beginObject() while(data.hasNext()){ @@ -159,6 +163,7 @@ class Auth: Client() { } data.endObject() + data.close() user.status = 1 } @@ -171,6 +176,7 @@ class Auth: Client() { user.status = 0 } + con.disconnect() return user } diff --git a/app/src/main/java/org/libre/agosto/p2play/ajax/Channels.kt b/app/src/main/java/org/libre/agosto/p2play/ajax/Channels.kt new file mode 100644 index 0000000..906b907 --- /dev/null +++ b/app/src/main/java/org/libre/agosto/p2play/ajax/Channels.kt @@ -0,0 +1,35 @@ +package org.libre.agosto.p2play.ajax + +import android.util.JsonReader +import android.util.JsonToken +import org.libre.agosto.p2play.models.ChannelModel +import org.libre.agosto.p2play.models.CommentaryModel +import java.io.InputStreamReader + +class Channels: Client() { + + private fun parseChannel(data: JsonReader): ChannelModel{ + val channel = ChannelModel() + + data.close() + + return channel + } + + fun getChannelInfo(account: String): ChannelModel { + val con = this._newCon("video-channels/$account", "GET") + var channel = ChannelModel() + try { + if(con.responseCode == 200){ + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) + channel.parseChannel(data) + data.close() + } + }catch (err: Exception) { + err.printStackTrace() + } + + return channel + } +} \ No newline at end of file diff --git a/app/src/main/java/org/libre/agosto/p2play/ajax/Client.kt b/app/src/main/java/org/libre/agosto/p2play/ajax/Client.kt index 475cd00..b4d627c 100644 --- a/app/src/main/java/org/libre/agosto/p2play/ajax/Client.kt +++ b/app/src/main/java/org/libre/agosto/p2play/ajax/Client.kt @@ -1,11 +1,11 @@ package org.libre.agosto.p2play.ajax -import android.content.SharedPreferences import android.util.JsonReader import android.util.Log import org.libre.agosto.p2play.ManagerSingleton import org.libre.agosto.p2play.models.HostModel import java.io.InputStreamReader +import java.io.Reader import java.net.HttpURLConnection import java.net.URL @@ -13,22 +13,22 @@ open class Client { protected fun _newCon(uri: String, method: String, token: String = ""): HttpURLConnection { - var url = URL("https://"+ManagerSingleton.url+"/api/v1/"+uri) - var con = url.openConnection() as HttpURLConnection + val url = URL("https://${ManagerSingleton.url}/api/v1/$uri") + val con = url.openConnection() as HttpURLConnection con.setRequestProperty("User-Agent", "P2play/0.1") con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") con.setRequestProperty("Accept", "*/*") if(token != ""){ - con.setRequestProperty("Authorization", "Bearer ${token}") + con.setRequestProperty("Authorization", "Bearer $token") } con.requestMethod=method con.connectTimeout=10000 con.readTimeout=10000 - if(method.equals("POST")) + if(method == "POST") con.doOutput=true Log.d("Petition", url.toString()) @@ -36,12 +36,12 @@ open class Client { } fun getKeys():HostModel{ - var con=this._newCon("oauth-clients/local","GET") - var keys = HostModel("","") + val con = this._newCon("oauth-clients/local","GET") + val keys = HostModel("","") try { if (con.responseCode == 200) { - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) data.beginObject() while (data.hasNext()) { val key = data.nextName() @@ -57,13 +57,14 @@ open class Client { } } } + data.close() } - Log.d("Key",keys.client_id) - return keys } catch(err:Exception){ - Log.d("Error",err.message) - return keys + err.printStackTrace() } + + con.disconnect() + return keys } diff --git a/app/src/main/java/org/libre/agosto/p2play/ajax/Comments.kt b/app/src/main/java/org/libre/agosto/p2play/ajax/Comments.kt index a909a60..9cf1190 100644 --- a/app/src/main/java/org/libre/agosto/p2play/ajax/Comments.kt +++ b/app/src/main/java/org/libre/agosto/p2play/ajax/Comments.kt @@ -8,8 +8,8 @@ import java.io.InputStreamReader class Comments: Client() { - fun parseCommentaries(data: JsonReader): ArrayList { - var commentaries = arrayListOf() + private fun parseCommentaries(data: JsonReader): ArrayList { + val commentaries = arrayListOf() data.beginObject() while (data.hasNext()){ when(data.nextName()) { @@ -17,47 +17,7 @@ class Comments: Client() { data.beginArray() while (data.hasNext()) { val comment = CommentaryModel() - data.beginObject() - while (data.hasNext()) { - val key = data.nextName() - when (key.toString()) { - "id" -> comment.id = data.nextInt() - "threadId" -> comment.threadId = data.nextInt() - "text" -> comment.commentary = data.nextString() - "totalReplies" -> comment.replies = data.nextInt() - "account" -> { - data.beginObject() - while (data.hasNext()){ - val acKey = data.nextName() - when(acKey.toString()){ - "displayName"-> comment.username=data.nextString() - "avatar"-> { - if(data.peek() == JsonToken.BEGIN_OBJECT){ - data.beginObject() - while (data.hasNext()){ - val avKey = data.nextName() - when(avKey){ - "path"-> comment.userImageUrl = data.nextString() - else-> data.skipValue() - } - } - data.endObject() - } - else - data.skipValue() - - } - "uuid" -> comment.userUuid = data.nextString() - "host" -> comment.userHost = data.nextString() - else -> data.skipValue() - } - } - data.endObject() - } - else -> data.skipValue() - } - } - data.endObject() + comment.parseCommentary(data) commentaries.add(comment) } data.endArray() @@ -76,37 +36,42 @@ class Comments: Client() { try { if (con.responseCode == 200) { - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) commentaries = parseCommentaries(data) + data.close() } } catch(err:Exception){ - err?.printStackTrace() - Log.d("TypeErr",err?.message ,err.cause) - Log.d("Error","fallo la coneccion") + err.printStackTrace() } - + con.disconnect() return commentaries } fun makeCommentary(token: String, videoId: Int, text: String): Boolean { val con = this._newCon("videos/$videoId/comment-threads", "POST", token) - val params:String= "text=$text" + val params = "text=$text" con.outputStream.write(params.toByteArray()) + var response: Boolean + try { if (con.responseCode == 200) { - return true + con.disconnect() + response = true } else{ Log.d("Status", con.responseMessage) + response = false } } catch (err: Exception){ err.printStackTrace() + response = false } - return false + con.disconnect() + return response } } \ No newline at end of file diff --git a/app/src/main/java/org/libre/agosto/p2play/ajax/Videos.kt b/app/src/main/java/org/libre/agosto/p2play/ajax/Videos.kt index 795b8f6..fb47ff2 100644 --- a/app/src/main/java/org/libre/agosto/p2play/ajax/Videos.kt +++ b/app/src/main/java/org/libre/agosto/p2play/ajax/Videos.kt @@ -2,7 +2,6 @@ package org.libre.agosto.p2play.ajax import android.util.JsonReader import android.util.JsonToken -import android.util.Log import org.libre.agosto.p2play.ManagerSingleton import org.libre.agosto.p2play.models.VideoModel import java.io.InputStreamReader @@ -10,7 +9,7 @@ import java.io.InputStreamReader class Videos: Client() { private fun parseVideos(data: JsonReader): ArrayList{ - var videos = arrayListOf() + val videos = arrayListOf() data.beginObject() while (data.hasNext()){ when(data.nextName()){ @@ -18,68 +17,7 @@ class Videos: Client() { data.beginArray() while (data.hasNext()) { val video = VideoModel() - data.beginObject() - while (data.hasNext()){ - val key = data.nextName() - when (key.toString()) { - "id"-> video.id = data.nextInt() - "name"->{ - video.name= data.nextString() - } - "description"->{ - if(data.peek() == JsonToken.STRING) - video.description = data.nextString() - else - data.skipValue() - } - "duration"->{ - video.duration = data.nextInt() - } - "thumbnailPath"->{ - video.thumbUrl = data.nextString() - } - "embedPath"->{ - video.embedUrl = data.nextString() - } - "views"->{ - video.views = data.nextInt() - } - "channel"->{ - data.beginObject() - while (data.hasNext()){ - val acKey = data.nextName() - when(acKey.toString()){ - "displayName"-> video.username=data.nextString() - "avatar"-> { - if(data.peek() == JsonToken.BEGIN_OBJECT){ - data.beginObject() - while (data.hasNext()){ - val avKey = data.nextName() - when(avKey){ - "path"-> video.userImageUrl = data.nextString() - else-> data.skipValue() - } - } - data.endObject() - } - else - data.skipValue() - - } - "uuid" -> video.userUuid = data.nextString() - "host" -> video.userHost = data.nextString() - "name" -> video.nameChannel = data.nextString() - else-> data.skipValue() - } - } - data.endObject() - } - else->{ - data.skipValue() - } - } - } - data.endObject() + video.parseVideo(data) videos.add(video) } data.endArray() @@ -98,17 +36,19 @@ class Videos: Client() { var params = "start=$start&count=$count&sort=$sort&nsfw=$nsfw" if(filter != "") params+="&filter=$filter" - var con=this._newCon("videos?$params","GET") + val con = this._newCon("videos?$params","GET") var videos = arrayListOf() try { if (con.responseCode == 200) { - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) videos = parseVideos(data) + data.close() } } catch(err:Exception){ - err?.printStackTrace() + err.printStackTrace() } + con.disconnect() return videos } @@ -120,6 +60,10 @@ class Videos: Client() { return this.getVideos(start,"-views") } + fun getTrendingVideos(start:Int = 0): ArrayList{ + return this.getVideos(start,"-trending") + } + fun getLocalVideos(start:Int = 0): ArrayList{ return this.getVideos(start,"-publishedAt", "local") } @@ -127,34 +71,40 @@ class Videos: Client() { fun myVideos(token: String, start: Int = 0): ArrayList{ val count = ManagerSingleton.videos_count val params = "start=$start&count=$count" - var con=this._newCon("users/me/videos?$params","GET", token) + val con = this._newCon("users/me/videos?$params","GET", token) var videos = arrayListOf() try { if (con.responseCode == 200) { - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) videos = parseVideos(data) + data.close() } } catch(err:Exception){ - err?.printStackTrace() + err.printStackTrace() } + + con.disconnect() return videos } fun videoSubscriptions(token: String, start: Int = 0): ArrayList{ val count = ManagerSingleton.videos_count val params = "start=$start&count=$count" - var con=this._newCon("users/me/subscriptions/videos?$params","GET", token) + val con = this._newCon("users/me/subscriptions/videos?$params","GET", token) var videos = arrayListOf() try { if (con.responseCode == 200) { - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) videos = parseVideos(data) + data.close() } } catch(err:Exception){ - err?.printStackTrace() + err.printStackTrace() } + + con.disconnect() return videos } @@ -162,17 +112,66 @@ class Videos: Client() { val count = ManagerSingleton.videos_count val nsfw = ManagerSingleton.nfsw val params = "search=$text&start=$start&count=$count&nsfw=$nsfw" - var con=this._newCon("search/videos?$params","GET") + val con = this._newCon("search/videos?$params","GET") var videos = arrayListOf() try { if (con.responseCode == 200) { - var response = InputStreamReader(con.inputStream) - var data = JsonReader(response) + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) videos = parseVideos(data) + data.close() } } catch(err:Exception){ - err?.printStackTrace() + err.printStackTrace() } + con.disconnect() + return videos + } + + fun fullDescription(videoId: Int): String{ + val con = this._newCon("videos/$videoId/description","GET") + var description = "" + try { + if (con.responseCode == 200) { + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) + + data.beginObject() + while (data.hasNext()){ + val name = data.nextName() + when(name){ + "description" -> description = data.nextString() + else -> data.skipValue() + } + } + data.endObject() + data.close() + } + } catch(err:Exception){ + err.printStackTrace() + description = "Error!" + } + con.disconnect() + return description + } + + fun channelVideos(account: String, start: Int): ArrayList { + val count = ManagerSingleton.videos_count + val params = "start=$start&count=$count" + val con = this._newCon("video-channels/$account/videos","GET") + var videos = arrayListOf() + try { + if (con.responseCode == 200) { + val response = InputStreamReader(con.inputStream) + val data = JsonReader(response) + videos = parseVideos(data) + data.close() + } + } catch(err:Exception){ + err.printStackTrace() + } + + con.disconnect() return videos } } \ No newline at end of file diff --git a/app/src/main/java/org/libre/agosto/p2play/models/ChannelModel.kt b/app/src/main/java/org/libre/agosto/p2play/models/ChannelModel.kt new file mode 100644 index 0000000..1966c70 --- /dev/null +++ b/app/src/main/java/org/libre/agosto/p2play/models/ChannelModel.kt @@ -0,0 +1,64 @@ +package org.libre.agosto.p2play.models + +import android.util.JsonReader +import android.util.JsonToken + +class ChannelModel ( + var id: Int = 0, + var url: String = "", + var nameChannel: String = "", + var followers: Int = 0, + var host: String = "", + var name: String = "", + var description: String = "", + var support: String = "", + var channelImg: String = "" +) { + fun getAccount(): String { + return "$nameChannel@$host" + } + + fun parseChannel(data: JsonReader) { + data.beginObject() + + while (data.hasNext()) { + + when(data.nextName()){ + "id" -> this.id = data.nextInt() + "url" -> this.url = data.nextString() + "name" -> this.nameChannel = data.nextString() + "host" -> this.host = data.nextString() + "followersCount" -> this.followers = data.nextInt() + "displayName" -> this.name = data.nextString() + "description" -> { + if(data.peek() == JsonToken.STRING) + this.description = data.nextString() + else + data.skipValue() + } + "support" -> { + if(data.peek() == JsonToken.STRING) + this.support = data.nextString() + else + data.skipValue() + } + "avatar" -> { + if(data.peek() == JsonToken.BEGIN_OBJECT){ + data.beginObject() + while (data.hasNext()){ + when(data.nextName()){ + "path" -> this.channelImg = data.nextString() + else -> data.skipValue() + } + } + data.endObject() + } + else + data.skipValue() + } + else -> data.skipValue() + } + } + data.endObject() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/libre/agosto/p2play/models/CommentaryModel.kt b/app/src/main/java/org/libre/agosto/p2play/models/CommentaryModel.kt index f1b5b47..55543c2 100644 --- a/app/src/main/java/org/libre/agosto/p2play/models/CommentaryModel.kt +++ b/app/src/main/java/org/libre/agosto/p2play/models/CommentaryModel.kt @@ -1,5 +1,8 @@ package org.libre.agosto.p2play.models +import android.util.JsonReader +import android.util.JsonToken + class CommentaryModel ( var id: Int = 0, var threadId: Int = 0, @@ -9,4 +12,48 @@ class CommentaryModel ( var commentary: String = "", var userHost: String = "", var replies: Int = 0 -) \ No newline at end of file +) { + fun parseCommentary(data: JsonReader) { + data.beginObject() + while (data.hasNext()) { + val key = data.nextName() + when (key.toString()) { + "id" -> this.id = data.nextInt() + "threadId" -> this.threadId = data.nextInt() + "text" -> this.commentary = data.nextString() + "totalReplies" -> this.replies = data.nextInt() + "account" -> { + data.beginObject() + while (data.hasNext()){ + val acKey = data.nextName() + when(acKey.toString()){ + "displayName"-> this.username=data.nextString() + "avatar"-> { + if(data.peek() == JsonToken.BEGIN_OBJECT){ + data.beginObject() + while (data.hasNext()){ + val avKey = data.nextName() + when(avKey){ + "path"-> this.userImageUrl = data.nextString() + else-> data.skipValue() + } + } + data.endObject() + } + else + data.skipValue() + + } + "uuid" -> this.userUuid = data.nextString() + "host" -> this.userHost = data.nextString() + else -> data.skipValue() + } + } + data.endObject() + } + else -> data.skipValue() + } + } + data.endObject() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/libre/agosto/p2play/models/VideoModel.kt b/app/src/main/java/org/libre/agosto/p2play/models/VideoModel.kt index e7bfa95..6059a94 100644 --- a/app/src/main/java/org/libre/agosto/p2play/models/VideoModel.kt +++ b/app/src/main/java/org/libre/agosto/p2play/models/VideoModel.kt @@ -1,9 +1,12 @@ package org.libre.agosto.p2play.models +import android.util.JsonReader +import android.util.JsonToken import java.io.Serializable class VideoModel( var id: Int = 0, + var uuid: String = "", var name: String = "", var description: String = "", var thumbUrl: String = "", @@ -15,4 +18,78 @@ class VideoModel( var userUuid: String = "", var userHost: String = "", var nameChannel: String = "" - ):Serializable \ No newline at end of file +):Serializable { + fun getAccount(): String { + return "$nameChannel@$userHost" + } + + fun getVideoUrl(): String { + return "https://$userHost/videos/watch/$uuid" + } + + fun parseVideo(data: JsonReader){ + data.beginObject() + while (data.hasNext()){ + val key = data.nextName() + when (key.toString()) { + "id"-> this.id = data.nextInt() + "uuid" -> this.uuid = data.nextString() + "name"->{ + this.name= data.nextString() + } + "description"->{ + if(data.peek() == JsonToken.STRING) + this.description = data.nextString() + else + data.skipValue() + } + "duration"->{ + this.duration = data.nextInt() + } + "thumbnailPath"->{ + this.thumbUrl = data.nextString() + } + "embedPath"->{ + this.embedUrl = data.nextString() + } + "views"->{ + this.views = data.nextInt() + } + "channel"->{ + data.beginObject() + while (data.hasNext()){ + val acKey = data.nextName() + when(acKey.toString()){ + "displayName"-> this.username=data.nextString() + "avatar"-> { + if(data.peek() == JsonToken.BEGIN_OBJECT){ + data.beginObject() + while (data.hasNext()){ + val avKey = data.nextName() + when(avKey){ + "path"-> this.userImageUrl = data.nextString() + else-> data.skipValue() + } + } + data.endObject() + } + else + data.skipValue() + + } + "uuid" -> this.userUuid = data.nextString() + "host" -> this.userHost = data.nextString() + "name" -> this.nameChannel = data.nextString() + else-> data.skipValue() + } + } + data.endObject() + } + else->{ + data.skipValue() + } + } + } + data.endObject() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_alert.xml b/app/src/main/res/drawable/ic_alert.xml new file mode 100644 index 0000000..8ef6143 --- /dev/null +++ b/app/src/main/res/drawable/ic_alert.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_share.xml b/app/src/main/res/drawable/ic_share.xml new file mode 100644 index 0000000..e8ba475 --- /dev/null +++ b/app/src/main/res/drawable/ic_share.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_trending_up_black_24dp.xml b/app/src/main/res/drawable/ic_trending_up_black_24dp.xml new file mode 100644 index 0000000..4c9da94 --- /dev/null +++ b/app/src/main/res/drawable/ic_trending_up_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_channel.xml b/app/src/main/res/layout/activity_channel.xml new file mode 100644 index 0000000..c78b087 --- /dev/null +++ b/app/src/main/res/layout/activity_channel.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +