mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2026-05-16 04:52:39 +02:00
Upgraded all dependencies and changed double tap to long press on comment text.
This commit is contained in:
+42
-44
@@ -1,8 +1,8 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.21'
|
id 'org.jetbrains.kotlin.plugin.serialization' version '2.2.21'
|
||||||
id 'org.ajoberstar.grgit' version '5.2.2'
|
id 'org.ajoberstar.grgit' version '5.3.3'
|
||||||
id 'com.google.protobuf'
|
id 'com.google.protobuf'
|
||||||
id 'kotlin-parcelize'
|
id 'kotlin-parcelize'
|
||||||
id 'com.google.devtools.ksp'
|
id 'com.google.devtools.ksp'
|
||||||
@@ -97,7 +97,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk 28
|
minSdk 28
|
||||||
targetSdk 35
|
targetSdk 36
|
||||||
versionCode gitVersionCode
|
versionCode gitVersionCode
|
||||||
versionName gitVersionName
|
versionName gitVersionName
|
||||||
|
|
||||||
@@ -155,82 +155,80 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
//implementation 'com.google.dagger:dagger:2.48'
|
//implementation 'com.google.dagger:dagger:2.48'
|
||||||
implementation 'androidx.test:monitor:1.7.2'
|
implementation 'androidx.test:monitor:1.8.0'
|
||||||
implementation 'com.google.android.material:material:1.12.0'
|
implementation 'com.google.android.material:material:1.13.0'
|
||||||
//annotationProcessor 'com.google.dagger:dagger-compiler:2.48'
|
//annotationProcessor 'com.google.dagger:dagger-compiler:2.48'
|
||||||
|
|
||||||
//Core
|
//Core
|
||||||
implementation 'androidx.core:core-ktx:1.12.0'
|
implementation 'androidx.core:core-ktx:1.17.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
implementation 'androidx.appcompat:appcompat:1.7.1'
|
||||||
implementation 'com.google.android.material:material:1.11.0'
|
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
implementation 'androidx.documentfile:documentfile:1.1.0'
|
||||||
|
|
||||||
//Images
|
//Images
|
||||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
|
annotationProcessor 'com.github.bumptech.glide:compiler:5.0.5'
|
||||||
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
implementation 'com.github.bumptech.glide:glide:5.0.5'
|
||||||
|
|
||||||
//Async
|
//Async
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2"
|
||||||
|
|
||||||
//HTTP
|
//HTTP
|
||||||
implementation "com.squareup.okhttp3:okhttp:4.11.0"
|
implementation "com.squareup.okhttp3:okhttp:5.3.0"
|
||||||
|
|
||||||
//JSON
|
//JSON
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2" //Used for structured json
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0" //Used for structured json
|
||||||
implementation 'com.google.code.gson:gson:2.10.1' //Used for complex/anonymous cases like during development conversions (eg. V8RemoteObject)
|
implementation 'com.google.code.gson:gson:2.13.2' //Used for complex/anonymous cases like during development conversions (eg. V8RemoteObject)
|
||||||
|
|
||||||
//JS
|
//JS
|
||||||
implementation("com.caoccao.javet:javet-android:3.0.2")
|
implementation 'com.caoccao.javet:javet-v8-android:5.0.1'
|
||||||
//implementation 'com.caoccao.javet:javet-v8-android:4.1.4' //Change after extensive testing the freezing edge cases are solved.
|
|
||||||
|
|
||||||
//Exoplayer
|
//Exoplayer
|
||||||
implementation 'androidx.media3:media3-exoplayer:1.2.1'
|
implementation 'androidx.media3:media3-exoplayer:1.8.0'
|
||||||
implementation 'androidx.media3:media3-exoplayer-dash:1.2.1'
|
implementation 'androidx.media3:media3-exoplayer-dash:1.8.0'
|
||||||
implementation 'androidx.media3:media3-ui:1.2.1'
|
implementation 'androidx.media3:media3-ui:1.8.0'
|
||||||
implementation 'androidx.media3:media3-exoplayer-hls:1.2.1'
|
implementation 'androidx.media3:media3-exoplayer-hls:1.8.0'
|
||||||
implementation 'androidx.media3:media3-exoplayer-rtsp:1.2.1'
|
implementation 'androidx.media3:media3-exoplayer-rtsp:1.8.0'
|
||||||
implementation 'androidx.media3:media3-exoplayer-smoothstreaming:1.2.1'
|
implementation 'androidx.media3:media3-exoplayer-smoothstreaming:1.8.0'
|
||||||
implementation 'androidx.media3:media3-transformer:1.2.1'
|
implementation 'androidx.media3:media3-transformer:1.8.0'
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.6'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.9.6'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.7.6'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.9.6'
|
||||||
implementation 'androidx.media:media:1.7.0'
|
implementation 'androidx.media:media:1.7.1'
|
||||||
|
|
||||||
//Other
|
//Other
|
||||||
implementation 'org.jsoup:jsoup:1.15.3'
|
implementation 'org.jsoup:jsoup:1.21.2'
|
||||||
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
implementation fileTree(dir: 'aar', include: ['*.aar'])
|
implementation fileTree(dir: 'aar', include: ['*.aar'])
|
||||||
implementation 'com.arthenica:smart-exception-java:0.2.1'
|
implementation 'com.arthenica:smart-exception-java:0.2.1'
|
||||||
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.9.0'
|
implementation 'org.jetbrains.kotlin:kotlin-reflect:2.2.0'
|
||||||
implementation 'com.github.dhaval2404:imagepicker:2.1'
|
implementation 'com.github.dhaval2404:imagepicker:2.1'
|
||||||
implementation 'com.google.zxing:core:3.4.1'
|
implementation 'com.google.zxing:core:3.5.3'
|
||||||
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
|
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
|
||||||
implementation 'com.caverock:androidsvg-aar:1.4'
|
implementation 'com.caverock:androidsvg-aar:1.4'
|
||||||
|
|
||||||
//Protobuf
|
//Protobuf
|
||||||
implementation 'com.google.protobuf:protobuf-javalite:3.25.1'
|
implementation 'com.google.protobuf:protobuf-javalite:4.33.0'
|
||||||
|
|
||||||
implementation 'com.polycentric.core:app:1.0'
|
implementation 'com.polycentric.core:app:1.0'
|
||||||
implementation 'com.futo.futopay:app:1.0'
|
implementation 'com.futo.futopay:app:1.0'
|
||||||
implementation 'androidx.work:work-runtime-ktx:2.9.0'
|
implementation 'androidx.work:work-runtime-ktx:2.11.0'
|
||||||
implementation 'androidx.concurrent:concurrent-futures-ktx:1.1.0'
|
implementation 'androidx.concurrent:concurrent-futures-ktx:1.3.0'
|
||||||
|
|
||||||
//Database
|
//Database
|
||||||
implementation("androidx.room:room-runtime:2.6.1")
|
implementation("androidx.room:room-runtime:2.8.3")
|
||||||
annotationProcessor("androidx.room:room-compiler:2.6.1")
|
ksp("androidx.room:room-compiler:2.8.3")
|
||||||
ksp("androidx.room:room-compiler:2.6.1")
|
implementation("androidx.room:room-ktx:2.8.3")
|
||||||
implementation("androidx.room:room-ktx:2.6.1")
|
|
||||||
|
|
||||||
//Payment
|
//Payment
|
||||||
implementation 'com.stripe:stripe-android:20.35.1'
|
implementation 'com.stripe:stripe-android:22.0.0'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
|
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2'
|
||||||
testImplementation "org.jetbrains.kotlin:kotlin-test:1.8.22"
|
testImplementation "org.jetbrains.kotlin:kotlin-test:2.0.21"
|
||||||
testImplementation "org.xmlunit:xmlunit-core:2.9.1"
|
testImplementation "org.xmlunit:xmlunit-core:2.11.0"
|
||||||
testImplementation "org.mockito:mockito-core:5.4.0"
|
testImplementation "org.mockito:mockito-core:5.20.0"
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0'
|
||||||
|
|
||||||
//Rust casting SDK
|
//Rust casting SDK
|
||||||
implementation('org.futo.gitlab.videostreaming.fcast-sdk-jitpack:sender-sdk-minimal:0.3.1') {
|
implementation('org.futo.gitlab.videostreaming.fcast-sdk-jitpack:sender-sdk-minimal:0.3.1') {
|
||||||
|
|||||||
@@ -107,10 +107,9 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
onNewIntent(intent);
|
onNewIntent(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent?) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
var url = intent?.dataString;
|
var url = intent.dataString;
|
||||||
|
|
||||||
if(url == null)
|
if(url == null)
|
||||||
UIDialogs.showDialog(this, R.drawable.ic_error, getString(R.string.no_valid_url_provided), null, null,
|
UIDialogs.showDialog(this, R.drawable.ic_error, getString(R.string.no_valid_url_provided), null, null,
|
||||||
0, UIDialogs.Action(getString(R.string.ok), { finish() }, UIDialogs.ActionStyle.PRIMARY));
|
0, UIDialogs.Action(getString(R.string.ok), { finish() }, UIDialogs.ActionStyle.PRIMARY));
|
||||||
|
|||||||
@@ -708,17 +708,13 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
|
|||||||
_wasStopped = true;
|
_wasStopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent?) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
super.onNewIntent(intent);
|
super.onNewIntent(intent);
|
||||||
handleIntent(intent);
|
handleIntent(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleIntent(intent: Intent?) {
|
private fun handleIntent(intent: Intent) {
|
||||||
if (intent == null)
|
|
||||||
return;
|
|
||||||
Logger.i(TAG, "handleIntent started by " + intent.action);
|
Logger.i(TAG, "handleIntent started by " + intent.action);
|
||||||
|
|
||||||
|
|
||||||
var targetData: String? = null;
|
var targetData: String? = null;
|
||||||
|
|
||||||
when (intent.action) {
|
when (intent.action) {
|
||||||
|
|||||||
@@ -54,14 +54,16 @@ interface IPlatformChannelContent : IPlatformContent {
|
|||||||
val subscribers: Long?
|
val subscribers: Long?
|
||||||
}
|
}
|
||||||
|
|
||||||
open class JSChannelContent : JSContent, IPlatformChannelContent {
|
open class JSChannelContent(
|
||||||
override val contentType: ContentType get() = ContentType.CHANNEL
|
config: SourcePluginConfig,
|
||||||
override val thumbnail: String?
|
obj: V8ValueObject
|
||||||
override val subscribers: Long?
|
) : JSContent(config, obj), IPlatformChannelContent {
|
||||||
|
|
||||||
constructor(config: SourcePluginConfig, obj: V8ValueObject) : super(config, obj) {
|
final override val contentType: ContentType = ContentType.CHANNEL
|
||||||
val contextName = "Channel";
|
|
||||||
thumbnail = obj.getOrDefault<String>(config, "thumbnail", contextName, null)
|
override val thumbnail: String? =
|
||||||
subscribers = if(obj.has("subscribers")) obj.getOrThrow(config,"subscribers", contextName) else null
|
_content.getOrDefault<String>(_pluginConfig, "thumbnail", "Channel", null)
|
||||||
}
|
|
||||||
|
override val subscribers: Long? =
|
||||||
|
_content.getOrDefault<Long>(_pluginConfig, "subscribers", "Channel", null)?.toLong()
|
||||||
}
|
}
|
||||||
+10
-20
@@ -6,25 +6,15 @@ import com.futo.platformplayer.api.media.models.ratings.IRating
|
|||||||
import com.futo.platformplayer.api.media.structures.IPager
|
import com.futo.platformplayer.api.media.structures.IPager
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
open class PlatformComment : IPlatformComment {
|
open class PlatformComment(
|
||||||
override val contextUrl: String;
|
override val contextUrl: String,
|
||||||
override val author: PlatformAuthorLink;
|
override val author: PlatformAuthorLink,
|
||||||
override val message: String;
|
override val message: String,
|
||||||
override val rating: IRating;
|
override val rating: IRating,
|
||||||
override val date: OffsetDateTime;
|
override val date: OffsetDateTime,
|
||||||
|
override val replyCount: Int? = null
|
||||||
|
) : IPlatformComment {
|
||||||
|
|
||||||
override val replyCount: Int?;
|
override fun getReplies(client: IPlatformClient): IPager<IPlatformComment> =
|
||||||
|
NoCommentsPager()
|
||||||
constructor(contextUrl: String, author: PlatformAuthorLink, msg: String, rating: IRating, date: OffsetDateTime, replyCount: Int? = null) {
|
|
||||||
this.contextUrl = contextUrl;
|
|
||||||
this.author = author;
|
|
||||||
this.message = msg;
|
|
||||||
this.rating = rating;
|
|
||||||
this.date = date;
|
|
||||||
this.replyCount = replyCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getReplies(client: IPlatformClient): IPager<IPlatformComment> {
|
|
||||||
return NoCommentsPager();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ open class JSClient : IPlatformClient {
|
|||||||
|
|
||||||
override val id: String get() = config.id;
|
override val id: String get() = config.id;
|
||||||
override val name: String get() = config.name;
|
override val name: String get() = config.name;
|
||||||
override val icon: ImageVariable;
|
override val icon: ImageVariable get() = StatePlatform.instance.getPlatformIcon(config.id) ?: ImageVariable(config.absoluteIconUrl, null, null)
|
||||||
override var capabilities: PlatformClientCapabilities = PlatformClientCapabilities();
|
override var capabilities: PlatformClientCapabilities = PlatformClientCapabilities();
|
||||||
|
|
||||||
private var _busyAction = "";
|
private var _busyAction = "";
|
||||||
@@ -147,7 +147,6 @@ open class JSClient : IPlatformClient {
|
|||||||
constructor(context: Context, descriptor: SourcePluginDescriptor, saveState: String? = null) {
|
constructor(context: Context, descriptor: SourcePluginDescriptor, saveState: String? = null) {
|
||||||
this._context = context;
|
this._context = context;
|
||||||
this.config = descriptor.config;
|
this.config = descriptor.config;
|
||||||
icon = StatePlatform.instance.getPlatformIcon(config.id) ?: ImageVariable(config.absoluteIconUrl, null, null);
|
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
_injectedSaveState = saveState;
|
_injectedSaveState = saveState;
|
||||||
_auth = descriptor.getAuth();
|
_auth = descriptor.getAuth();
|
||||||
@@ -178,7 +177,6 @@ open class JSClient : IPlatformClient {
|
|||||||
constructor(context: Context, descriptor: SourcePluginDescriptor, saveState: String?, script: String, withoutCredentials: Boolean = false) {
|
constructor(context: Context, descriptor: SourcePluginDescriptor, saveState: String?, script: String, withoutCredentials: Boolean = false) {
|
||||||
this._context = context;
|
this._context = context;
|
||||||
this.config = descriptor.config;
|
this.config = descriptor.config;
|
||||||
icon = StatePlatform.instance.getPlatformIcon(config.id) ?: ImageVariable(config.absoluteIconUrl, null, null);
|
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
_injectedSaveState = saveState;
|
_injectedSaveState = saveState;
|
||||||
if(!withoutCredentials)
|
if(!withoutCredentials)
|
||||||
|
|||||||
+15
-10
@@ -23,17 +23,22 @@ import com.futo.platformplayer.getOrThrow
|
|||||||
import com.futo.platformplayer.getOrThrowNullableList
|
import com.futo.platformplayer.getOrThrowNullableList
|
||||||
import com.futo.platformplayer.states.StateDeveloper
|
import com.futo.platformplayer.states.StateDeveloper
|
||||||
|
|
||||||
open class JSArticle : JSContent, IPlatformArticle, IPluginSourced {
|
open class JSArticle(
|
||||||
final override val contentType: ContentType get() = ContentType.ARTICLE;
|
config: SourcePluginConfig,
|
||||||
|
obj: V8ValueObject
|
||||||
|
) : JSContent(config, obj), IPlatformArticle, IPluginSourced {
|
||||||
|
|
||||||
override val summary: String;
|
final override val contentType: ContentType = ContentType.ARTICLE
|
||||||
override val thumbnails: Thumbnails?;
|
|
||||||
|
|
||||||
constructor(config: SourcePluginConfig, obj: V8ValueObject): super(config, obj) {
|
override val summary: String =
|
||||||
val contextName = "PlatformArticle";
|
obj.getOrDefault<String>(config, "summary", "PlatformArticle", "") ?: ""
|
||||||
|
|
||||||
summary = _content.getOrDefault(config, "summary", contextName, "") ?: "";
|
override val thumbnails: Thumbnails? =
|
||||||
thumbnails = Thumbnails.fromV8(config, _content.getOrThrow(config, "thumbnails", contextName));
|
if (obj.has("thumbnails"))
|
||||||
|
Thumbnails.fromV8(
|
||||||
}
|
config,
|
||||||
|
obj.getOrThrow<V8ValueObject>(config, "thumbnails", "PlatformArticle")
|
||||||
|
)
|
||||||
|
else
|
||||||
|
null
|
||||||
}
|
}
|
||||||
+24
-23
@@ -24,36 +24,37 @@ import com.futo.platformplayer.getOrThrowNullableList
|
|||||||
import com.futo.platformplayer.invokeV8
|
import com.futo.platformplayer.invokeV8
|
||||||
import com.futo.platformplayer.states.StateDeveloper
|
import com.futo.platformplayer.states.StateDeveloper
|
||||||
|
|
||||||
open class JSArticleDetails : JSContent, IPlatformArticleDetails, IPluginSourced, IPlatformContentDetails {
|
open class JSArticleDetails(
|
||||||
final override val contentType: ContentType get() = ContentType.ARTICLE;
|
private val client: JSClient,
|
||||||
|
obj: V8ValueObject
|
||||||
|
) : JSContent(client.config, obj), IPlatformArticleDetails, IPluginSourced, IPlatformContentDetails {
|
||||||
|
|
||||||
private val _hasGetComments: Boolean;
|
final override val contentType: ContentType = ContentType.ARTICLE
|
||||||
private val _hasGetContentRecommendations: Boolean;
|
|
||||||
|
|
||||||
override val rating: IRating;
|
private val _hasGetComments: Boolean = _content.has("getComments")
|
||||||
|
private val _hasGetContentRecommendations: Boolean = _content.has("getContentRecommendations")
|
||||||
|
|
||||||
override val summary: String;
|
override val rating: IRating =
|
||||||
override val thumbnails: Thumbnails?;
|
obj.getOrDefault<V8ValueObject>(client.config, "rating", "PlatformArticle", null)
|
||||||
override val segments: List<IJSArticleSegment>;
|
?.let { IRating.fromV8(client.config, it, "PlatformArticle") }
|
||||||
|
?: RatingLikes(0)
|
||||||
|
|
||||||
constructor(client: JSClient, obj: V8ValueObject): super(client.config, obj) {
|
override val summary: String =
|
||||||
val contextName = "PlatformArticle";
|
_content.getOrThrow(client.config, "summary", "PlatformArticle")
|
||||||
|
|
||||||
rating = obj.getOrDefault<V8ValueObject>(client.config, "rating", contextName, null)?.let { IRating.fromV8(client.config, it, contextName) } ?: RatingLikes(0);
|
override val thumbnails: Thumbnails? =
|
||||||
summary = _content.getOrThrow(client.config, "summary", contextName);
|
if (_content.has("thumbnails"))
|
||||||
if(_content.has("thumbnails"))
|
Thumbnails.fromV8(
|
||||||
thumbnails = Thumbnails.fromV8(client.config, _content.getOrThrow(client.config, "thumbnails", contextName));
|
client.config,
|
||||||
|
_content.getOrThrow(client.config, "thumbnails", "PlatformArticle")
|
||||||
|
)
|
||||||
else
|
else
|
||||||
thumbnails = null;
|
null
|
||||||
|
|
||||||
|
override val segments: List<IJSArticleSegment> =
|
||||||
segments = (obj.getOrThrowNullableList<V8ValueObject>(client.config, "segments", contextName)
|
obj.getOrThrowNullableList<V8ValueObject>(client.config, "segments", "PlatformArticle")
|
||||||
?.map { fromV8Segment(client, it) }
|
?.mapNotNull { fromV8Segment(client, it) }
|
||||||
?.filterNotNull() ?: listOf());
|
?: emptyList()
|
||||||
|
|
||||||
_hasGetComments = _content.has("getComments");
|
|
||||||
_hasGetContentRecommendations = _content.has("getContentRecommendations");
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getComments(client: IPlatformClient): IPager<IPlatformComment>? {
|
override fun getComments(client: IPlatformClient): IPager<IPlatformComment>? {
|
||||||
if(!_hasGetComments || _content.isClosed)
|
if(!_hasGetComments || _content.isClosed)
|
||||||
|
|||||||
+35
-37
@@ -16,51 +16,49 @@ import java.time.LocalDateTime
|
|||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
import java.time.ZoneOffset
|
import java.time.ZoneOffset
|
||||||
|
|
||||||
open class JSContent : IPlatformContent, IPluginSourced {
|
open class JSContent(
|
||||||
protected val _pluginConfig: SourcePluginConfig;
|
protected val _pluginConfig: SourcePluginConfig,
|
||||||
protected val _content : V8ValueObject;
|
protected val _content: V8ValueObject
|
||||||
|
) : IPlatformContent, IPluginSourced {
|
||||||
|
|
||||||
protected val _hasGetDetails: Boolean;
|
override val contentType: ContentType = ContentType.UNKNOWN
|
||||||
|
|
||||||
override val contentType: ContentType get() = ContentType.UNKNOWN;
|
protected val _hasGetDetails: Boolean = _content.has("getDetails")
|
||||||
|
|
||||||
override val id: PlatformID;
|
override val id: PlatformID =
|
||||||
override val name: String;
|
PlatformID.fromV8(_pluginConfig, _content.getOrThrow(_pluginConfig, "id", CTX))
|
||||||
override val author: PlatformAuthorLink;
|
|
||||||
override val datetime: OffsetDateTime?;
|
|
||||||
|
|
||||||
override val url: String;
|
override val name: String =
|
||||||
override val shareUrl: String;
|
HtmlCompat.fromHtml(
|
||||||
|
_content.getOrThrow<String>(_pluginConfig, "name", CTX).decodeUnicode(),
|
||||||
|
HtmlCompat.FROM_HTML_MODE_LEGACY
|
||||||
|
).toString()
|
||||||
|
|
||||||
override val sourceConfig: SourcePluginConfig get() = _pluginConfig;
|
override val author: PlatformAuthorLink =
|
||||||
|
_content.getOrDefault<V8ValueObject>(_pluginConfig, "author", CTX, null)
|
||||||
|
?.let { PlatformAuthorLink.fromV8(_pluginConfig, it) }
|
||||||
|
?: PlatformAuthorLink.UNKNOWN
|
||||||
|
|
||||||
constructor(config: SourcePluginConfig, obj: V8ValueObject) {
|
private val _epoch: Long? =
|
||||||
_pluginConfig = config;
|
_content.getOrDefault<Long>(_pluginConfig, "datetime", CTX, null)?.toLong()
|
||||||
_content = obj;
|
|
||||||
|
|
||||||
val contextName = "PlatformContent";
|
override val datetime: OffsetDateTime? =
|
||||||
|
_epoch?.takeIf { it != 0L }?.let {
|
||||||
id = PlatformID.fromV8(_pluginConfig, _content.getOrThrow(config, "id", contextName));
|
OffsetDateTime.of(LocalDateTime.ofEpochSecond(it, 0, ZoneOffset.UTC), ZoneOffset.UTC)
|
||||||
name = HtmlCompat.fromHtml(_content.getOrThrow<String>(config, "name", contextName).decodeUnicode(), HtmlCompat.FROM_HTML_MODE_LEGACY).toString();
|
|
||||||
|
|
||||||
val authorObj = _content.getOrDefault<V8ValueObject>(config, "author", contextName, null);
|
|
||||||
if(authorObj != null)
|
|
||||||
author = PlatformAuthorLink.fromV8(_pluginConfig, authorObj);
|
|
||||||
else
|
|
||||||
author = PlatformAuthorLink.UNKNOWN;
|
|
||||||
|
|
||||||
val datetimeInt = _content.getOrDefault<Int>(config, "datetime", contextName, null)?.toLong();
|
|
||||||
if(datetimeInt == null || datetimeInt == 0.toLong())
|
|
||||||
datetime = null;
|
|
||||||
else
|
|
||||||
datetime = OffsetDateTime.of(LocalDateTime.ofEpochSecond(datetimeInt, 0, ZoneOffset.UTC), ZoneOffset.UTC);
|
|
||||||
url = _content.getOrThrow(config, "url", contextName);
|
|
||||||
shareUrl = _content.getOrDefault<String>(config, "shareUrl", contextName, null) ?: url;
|
|
||||||
|
|
||||||
_hasGetDetails = _content.has("getDetails");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUnderlyingObject(): V8ValueObject? {
|
override val url: String =
|
||||||
return _content;
|
_content.getOrThrow<String>(_pluginConfig, "url", CTX)
|
||||||
|
|
||||||
|
override val shareUrl: String =
|
||||||
|
_content.getOrDefault<String>(_pluginConfig, "shareUrl", CTX, null) ?: url
|
||||||
|
|
||||||
|
override val sourceConfig: SourcePluginConfig
|
||||||
|
get() = _pluginConfig
|
||||||
|
|
||||||
|
fun getUnderlyingObject(): V8ValueObject? = _content
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val CTX = "PlatformContent"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+11
-9
@@ -6,14 +6,16 @@ import com.futo.platformplayer.api.media.models.playlists.IPlatformPlaylist
|
|||||||
import com.futo.platformplayer.api.media.platforms.js.SourcePluginConfig
|
import com.futo.platformplayer.api.media.platforms.js.SourcePluginConfig
|
||||||
import com.futo.platformplayer.getOrDefault
|
import com.futo.platformplayer.getOrDefault
|
||||||
|
|
||||||
open class JSPlaylist : JSContent, IPlatformPlaylist {
|
open class JSPlaylist(
|
||||||
override val contentType: ContentType get() = ContentType.PLAYLIST;
|
config: SourcePluginConfig,
|
||||||
override val thumbnail: String?;
|
obj: V8ValueObject
|
||||||
override val videoCount: Int;
|
) : JSContent(config, obj), IPlatformPlaylist {
|
||||||
|
|
||||||
constructor(config: SourcePluginConfig, obj: V8ValueObject) : super(config, obj) {
|
override val contentType: ContentType = ContentType.PLAYLIST
|
||||||
val contextName = "Playlist";
|
|
||||||
thumbnail = obj.getOrDefault(config, "thumbnail", contextName, null);
|
override val thumbnail: String? =
|
||||||
videoCount = obj.getOrDefault(config, "videoCount", contextName, -1)!!;
|
_content.getOrDefault<String>(_pluginConfig, "thumbnail", "Playlist", null)
|
||||||
}
|
|
||||||
|
override val videoCount: Int =
|
||||||
|
_content.getOrDefault<Int>(_pluginConfig, "videoCount", "Playlist", null)?.toInt() ?: -1
|
||||||
}
|
}
|
||||||
+30
-29
@@ -8,43 +8,44 @@ import com.futo.platformplayer.engine.V8Plugin
|
|||||||
import com.futo.platformplayer.getOrDefault
|
import com.futo.platformplayer.getOrDefault
|
||||||
import com.futo.platformplayer.getOrThrow
|
import com.futo.platformplayer.getOrThrow
|
||||||
|
|
||||||
open class JSAudioUrlSource : IAudioUrlSource, JSSource {
|
open class JSAudioUrlSource(
|
||||||
override val name: String;
|
plugin: JSClient,
|
||||||
override val bitrate : Int;
|
obj: V8ValueObject
|
||||||
override val container : String;
|
) : JSSource(TYPE_AUDIOURL, plugin, obj), IAudioUrlSource {
|
||||||
override val codec: String;
|
|
||||||
private val url : String;
|
|
||||||
|
|
||||||
override val language: String;
|
private val ctx = "AudioUrlSource"
|
||||||
|
private val cfg = plugin.config
|
||||||
|
|
||||||
override val duration: Long?;
|
override val bitrate: Int =
|
||||||
|
_obj.getOrThrow<Int>(cfg, "bitrate", ctx)
|
||||||
|
|
||||||
override var priority: Boolean = false;
|
override val container: String =
|
||||||
|
_obj.getOrThrow<String>(cfg, "container", ctx)
|
||||||
|
|
||||||
override var original: Boolean = false;
|
override val codec: String =
|
||||||
|
_obj.getOrThrow<String>(cfg, "codec", ctx)
|
||||||
|
|
||||||
constructor(plugin: JSClient, obj: V8ValueObject) : super(TYPE_AUDIOURL, plugin, obj) {
|
private val url: String =
|
||||||
val contextName = "AudioUrlSource";
|
_obj.getOrThrow<String>(cfg, "url", ctx)
|
||||||
val config = plugin.config;
|
|
||||||
|
|
||||||
bitrate = _obj.getOrThrow(config, "bitrate", contextName);
|
override val language: String =
|
||||||
container = _obj.getOrThrow(config, "container", contextName);
|
_obj.getOrThrow<String>(cfg, "language", ctx)
|
||||||
codec = _obj.getOrThrow(config, "codec", contextName);
|
|
||||||
url = _obj.getOrThrow(config, "url", contextName);
|
|
||||||
language = _obj.getOrThrow(config, "language", contextName);
|
|
||||||
duration = _obj.getOrDefault(config, "duration", contextName, null);
|
|
||||||
|
|
||||||
name = _obj.getOrDefault(config, "name", contextName, "${container} ${bitrate}") ?: "${container} ${bitrate}";
|
override val duration: Long? =
|
||||||
|
_obj.getOrDefault<Long>(cfg, "duration", ctx, null)?.toLong()
|
||||||
|
|
||||||
priority = if(_obj.has("priority")) obj.getOrThrow(config, "priority", contextName) else false;
|
override val name: String =
|
||||||
original = if(_obj.has("original")) obj.getOrThrow(config, "original", contextName) else false;
|
_obj.getOrDefault<String>(cfg, "name", ctx, null)
|
||||||
}
|
?: "$container $bitrate"
|
||||||
|
|
||||||
override fun getAudioUrl() : String {
|
override var priority: Boolean =
|
||||||
return url;
|
if (_obj.has("priority")) _obj.getOrThrow<Boolean>(cfg, "priority", ctx) else false
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
override var original: Boolean =
|
||||||
return "(name=$name, container=$container, bitrate=$bitrate, codec=$codec, url=$url, language=$language, duration=$duration)";
|
if (_obj.has("original")) _obj.getOrThrow<Boolean>(cfg, "original", ctx) else false
|
||||||
}
|
|
||||||
|
override fun getAudioUrl(): String = url
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
"(name=$name, container=$container, bitrate=$bitrate, codec=$codec, url=$url, language=$language, duration=$duration)"
|
||||||
}
|
}
|
||||||
+41
-31
@@ -31,42 +31,52 @@ interface IJSDashManifestRawSource {
|
|||||||
fun generateAsync(scope: CoroutineScope): Deferred<String?>;
|
fun generateAsync(scope: CoroutineScope): Deferred<String?>;
|
||||||
fun generate(): String?;
|
fun generate(): String?;
|
||||||
}
|
}
|
||||||
open class JSDashManifestRawSource: JSSource, IVideoSource, IJSDashManifestRawSource, IStreamMetaDataSource {
|
open class JSDashManifestRawSource(
|
||||||
override val container : String;
|
plugin: JSClient,
|
||||||
override val name : String;
|
obj: V8ValueObject
|
||||||
override val width: Int;
|
) : JSSource(TYPE_DASH_RAW, plugin, obj), IVideoSource, IJSDashManifestRawSource, IStreamMetaDataSource {
|
||||||
override val height: Int;
|
|
||||||
override val codec: String;
|
|
||||||
override val bitrate: Int?;
|
|
||||||
override val duration: Long;
|
|
||||||
override val priority: Boolean;
|
|
||||||
|
|
||||||
val url: String?;
|
private val ctx = "DashRawSource"
|
||||||
override var manifest: String?;
|
private val cfg = plugin.config
|
||||||
|
|
||||||
override val hasGenerate: Boolean;
|
override val container: String =
|
||||||
val canMerge: Boolean;
|
_obj.getOrDefault<String>(cfg, "container", ctx, null) ?: "application/dash+xml"
|
||||||
|
|
||||||
override var streamMetaData: StreamMetaData? = null;
|
override val name: String =
|
||||||
|
_obj.getOrThrow<String>(cfg, "name", ctx)
|
||||||
|
|
||||||
constructor(plugin: JSClient, obj: V8ValueObject) : super(TYPE_DASH_RAW, plugin, obj) {
|
override val width: Int =
|
||||||
val contextName = "DashRawSource";
|
_obj.getOrDefault<Int>(cfg, "width", ctx, null)?.toInt() ?: 0
|
||||||
val config = plugin.config;
|
|
||||||
name = _obj.getOrThrow(config, "name", contextName);
|
|
||||||
url = _obj.getOrThrow(config, "url", contextName);
|
|
||||||
container = _obj.getOrDefault<String>(config, "container", contextName, null) ?: "application/dash+xml";
|
|
||||||
manifest = _obj.getOrDefault<String>(config, "manifest", contextName, null);
|
|
||||||
width = _obj.getOrDefault(config, "width", contextName, 0) ?: 0;
|
|
||||||
height = _obj.getOrDefault(config, "height", contextName, 0) ?: 0;
|
|
||||||
codec = _obj.getOrDefault(config, "codec", contextName, "") ?: "";
|
|
||||||
bitrate = _obj.getOrDefault(config, "bitrate", contextName, 0) ?: 0;
|
|
||||||
duration = _obj.getOrDefault(config, "duration", contextName, 0) ?: 0;
|
|
||||||
priority = _obj.getOrDefault(config, "priority", contextName, false) ?: false;
|
|
||||||
canMerge = _obj.getOrDefault(config, "canMerge", contextName, false) ?: false;
|
|
||||||
hasGenerate = _obj.has("generate");
|
|
||||||
}
|
|
||||||
|
|
||||||
private var _pregenerate: V8Deferred<String?>? = null;
|
override val height: Int =
|
||||||
|
_obj.getOrDefault<Int>(cfg, "height", ctx, null)?.toInt() ?: 0
|
||||||
|
|
||||||
|
override val codec: String =
|
||||||
|
_obj.getOrDefault<String>(cfg, "codec", ctx, "") ?: ""
|
||||||
|
|
||||||
|
override val bitrate: Int? =
|
||||||
|
_obj.getOrDefault<Int>(cfg, "bitrate", ctx, null)?.toInt()
|
||||||
|
|
||||||
|
override val duration: Long =
|
||||||
|
_obj.getOrDefault<Long>(cfg, "duration", ctx, 0)?.toLong() ?: 0L
|
||||||
|
|
||||||
|
override val priority: Boolean =
|
||||||
|
_obj.getOrDefault<Boolean>(cfg, "priority", ctx, false) ?: false
|
||||||
|
|
||||||
|
val url: String? =
|
||||||
|
_obj.getOrDefault<String>(cfg, "url", ctx, null)
|
||||||
|
|
||||||
|
override var manifest: String? =
|
||||||
|
_obj.getOrDefault<String>(cfg, "manifest", ctx, null)
|
||||||
|
|
||||||
|
override val hasGenerate: Boolean = _obj.has("generate")
|
||||||
|
|
||||||
|
val canMerge: Boolean =
|
||||||
|
_obj.getOrDefault<Boolean>(cfg, "canMerge", ctx, false) ?: false
|
||||||
|
|
||||||
|
override var streamMetaData: StreamMetaData? = null
|
||||||
|
|
||||||
|
private var _pregenerate: V8Deferred<String?>? = null
|
||||||
fun pregenerateAsync(scope: CoroutineScope): V8Deferred<String?>? {
|
fun pregenerateAsync(scope: CoroutineScope): V8Deferred<String?>? {
|
||||||
_pregenerate = generateAsync(scope);
|
_pregenerate = generateAsync(scope);
|
||||||
return _pregenerate;
|
return _pregenerate;
|
||||||
|
|||||||
+34
-29
@@ -5,42 +5,47 @@ import com.futo.platformplayer.api.media.models.streams.sources.IVideoUrlSource
|
|||||||
import com.futo.platformplayer.api.media.platforms.js.JSClient
|
import com.futo.platformplayer.api.media.platforms.js.JSClient
|
||||||
import com.futo.platformplayer.engine.IV8PluginConfig
|
import com.futo.platformplayer.engine.IV8PluginConfig
|
||||||
import com.futo.platformplayer.engine.V8Plugin
|
import com.futo.platformplayer.engine.V8Plugin
|
||||||
|
import com.futo.platformplayer.getOrDefault
|
||||||
import com.futo.platformplayer.getOrNull
|
import com.futo.platformplayer.getOrNull
|
||||||
import com.futo.platformplayer.getOrThrow
|
import com.futo.platformplayer.getOrThrow
|
||||||
|
|
||||||
open class JSVideoUrlSource : IVideoUrlSource, JSSource {
|
open class JSVideoUrlSource(
|
||||||
override val width : Int;
|
plugin: JSClient,
|
||||||
override val height : Int;
|
obj: V8ValueObject
|
||||||
override val container : String;
|
) : JSSource(TYPE_VIDEOURL, plugin, obj), IVideoUrlSource {
|
||||||
override val codec: String;
|
|
||||||
override val name : String;
|
|
||||||
override val bitrate : Int;
|
|
||||||
override val duration: Long;
|
|
||||||
private val url : String;
|
|
||||||
|
|
||||||
override var priority: Boolean = false;
|
private val ctx = "JSVideoUrlSource"
|
||||||
|
private val cfg = plugin.config
|
||||||
|
|
||||||
constructor(plugin: JSClient, obj: V8ValueObject): super(TYPE_VIDEOURL, plugin, obj) {
|
override val width: Int =
|
||||||
val contextName = "JSVideoUrlSource";
|
_obj.getOrThrow<Int>(cfg, "width", ctx)
|
||||||
val config = plugin.config;
|
|
||||||
|
|
||||||
width = _obj.getOrThrow(config, "width", contextName);
|
override val height: Int =
|
||||||
height = _obj.getOrThrow(config, "height", contextName);
|
_obj.getOrThrow<Int>(cfg, "height", ctx)
|
||||||
container = _obj.getOrThrow(config, "container", contextName);
|
|
||||||
codec = _obj.getOrThrow(config, "codec", contextName);
|
|
||||||
name = _obj.getOrThrow(config, "name", contextName);
|
|
||||||
bitrate = _obj.getOrThrow(config, "bitrate", contextName);
|
|
||||||
duration = _obj.getOrThrow<Int>(config, "duration", contextName).toLong();
|
|
||||||
url = _obj.getOrThrow(config, "url", contextName);
|
|
||||||
|
|
||||||
priority = obj.getOrNull(config, "priority", contextName) ?: false;
|
override val container: String =
|
||||||
}
|
_obj.getOrThrow<String>(cfg, "container", ctx)
|
||||||
|
|
||||||
override fun getVideoUrl() : String {
|
override val codec: String =
|
||||||
return url;
|
_obj.getOrThrow<String>(cfg, "codec", ctx)
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
override val name: String =
|
||||||
return "(width=$width, height=$height, container=$container, codec=$codec, name=$name, bitrate=$bitrate, duration=$duration, url=$url)"
|
_obj.getOrThrow<String>(cfg, "name", ctx)
|
||||||
}
|
|
||||||
|
override val bitrate: Int =
|
||||||
|
_obj.getOrThrow<Int>(cfg, "bitrate", ctx)
|
||||||
|
|
||||||
|
override val duration: Long =
|
||||||
|
_obj.getOrThrow<Long>(cfg, "duration", ctx)
|
||||||
|
|
||||||
|
private val url: String =
|
||||||
|
_obj.getOrThrow<String>(cfg, "url", ctx)
|
||||||
|
|
||||||
|
override var priority: Boolean =
|
||||||
|
_obj.getOrDefault<Boolean>(cfg, "priority", ctx, false) ?: false
|
||||||
|
|
||||||
|
override fun getVideoUrl(): String = url
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
"(width=$width, height=$height, container=$container, codec=$codec, name=$name, bitrate=$bitrate, duration=$duration, url=$url)"
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,8 @@ import android.content.Context
|
|||||||
import com.caoccao.javet.exceptions.JavetCompilationException
|
import com.caoccao.javet.exceptions.JavetCompilationException
|
||||||
import com.caoccao.javet.exceptions.JavetException
|
import com.caoccao.javet.exceptions.JavetException
|
||||||
import com.caoccao.javet.exceptions.JavetExecutionException
|
import com.caoccao.javet.exceptions.JavetExecutionException
|
||||||
|
import com.caoccao.javet.interfaces.IJavetEntityError
|
||||||
|
import com.caoccao.javet.interfaces.IJavetEntityMap
|
||||||
import com.caoccao.javet.interop.V8Host
|
import com.caoccao.javet.interop.V8Host
|
||||||
import com.caoccao.javet.interop.V8Runtime
|
import com.caoccao.javet.interop.V8Runtime
|
||||||
import com.caoccao.javet.values.V8Value
|
import com.caoccao.javet.values.V8Value
|
||||||
@@ -409,6 +411,12 @@ class V8Plugin {
|
|||||||
return _runtimeMap.getOrDefault(runtime, null);
|
return _runtimeMap.getOrDefault(runtime, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ctxString(ctx: Any?, key: String): String? = when (ctx) {
|
||||||
|
is Map<*, *> -> ctx[key]?.toString()
|
||||||
|
is V8ValueObject -> if (ctx.has(key)) ctx.getString(key) else null
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
fun <T: Any?> catchScriptErrors(config: IV8PluginConfig, context: String, code: String? = null, handle: ()->T): T {
|
fun <T: Any?> catchScriptErrors(config: IV8PluginConfig, context: String, code: String? = null, handle: ()->T): T {
|
||||||
var codeStripped = code;
|
var codeStripped = code;
|
||||||
if(codeStripped != null) { //TODO: Improve code stripped
|
if(codeStripped != null) { //TODO: Improve code stripped
|
||||||
@@ -442,37 +450,6 @@ class V8Plugin {
|
|||||||
throw ScriptCompilationException(config, "Compilation: [${context}]: ${scriptEx.message}\n(${scriptEx.scriptingError.lineNumber})[${scriptEx.scriptingError.startColumn}-${scriptEx.scriptingError.endColumn}]: ${scriptEx.scriptingError.sourceLine}", null, codeStripped);
|
throw ScriptCompilationException(config, "Compilation: [${context}]: ${scriptEx.message}\n(${scriptEx.scriptingError.lineNumber})[${scriptEx.scriptingError.startColumn}-${scriptEx.scriptingError.endColumn}]: ${scriptEx.scriptingError.sourceLine}", null, codeStripped);
|
||||||
}
|
}
|
||||||
catch(executeEx: JavetExecutionException) {
|
catch(executeEx: JavetExecutionException) {
|
||||||
val obj = executeEx.scriptingError?.context
|
|
||||||
if(obj != null && obj.containsKey("plugin_type") == true) {
|
|
||||||
val pluginType = obj["plugin_type"].toString();
|
|
||||||
|
|
||||||
//Captcha
|
|
||||||
if (pluginType == "CaptchaRequiredException") {
|
|
||||||
throw ScriptCaptchaRequiredException(config,
|
|
||||||
obj["url"]?.toString(),
|
|
||||||
obj["body"]?.toString(),
|
|
||||||
executeEx, executeEx.scriptingError?.stack, codeStripped);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Reload Required
|
|
||||||
if (pluginType == "ReloadRequiredException") {
|
|
||||||
throw ScriptReloadRequiredException(config,
|
|
||||||
obj["msg"]?.toString(),
|
|
||||||
obj["reloadData"]?.toString(),
|
|
||||||
executeEx, executeEx.scriptingError?.stack, codeStripped);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Others
|
|
||||||
throwExceptionFromV8(
|
|
||||||
config,
|
|
||||||
pluginType,
|
|
||||||
(extractJSExceptionMessage(executeEx) ?: ""),
|
|
||||||
executeEx,
|
|
||||||
executeEx.scriptingError?.stack,
|
|
||||||
codeStripped
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/* //Required for newer V8 versions
|
|
||||||
if(executeEx.scriptingError?.context is IJavetEntityError) {
|
if(executeEx.scriptingError?.context is IJavetEntityError) {
|
||||||
val obj = executeEx.scriptingError?.context as IJavetEntityError
|
val obj = executeEx.scriptingError?.context as IJavetEntityError
|
||||||
if(obj.context.containsKey("plugin_type") == true) {
|
if(obj.context.containsKey("plugin_type") == true) {
|
||||||
@@ -506,7 +483,6 @@ class V8Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
throw ScriptExecutionException(config, extractJSExceptionMessage(executeEx) ?: "", null, executeEx.scriptingError?.stack, codeStripped);
|
throw ScriptExecutionException(config, extractJSExceptionMessage(executeEx) ?: "", null, executeEx.scriptingError?.stack, codeStripped);
|
||||||
}
|
}
|
||||||
catch(ex: Exception) {
|
catch(ex: Exception) {
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ class CommentViewHolder : ViewHolder {
|
|||||||
private val _imageLikeIcon: ImageView;
|
private val _imageLikeIcon: ImageView;
|
||||||
private val _textLikes: TextView;
|
private val _textLikes: TextView;
|
||||||
private val _imageDislikeIcon: ImageView;
|
private val _imageDislikeIcon: ImageView;
|
||||||
private val _imageCopy: ImageView;
|
|
||||||
private val _textDislikes: TextView;
|
private val _textDislikes: TextView;
|
||||||
private val _buttonReplies: PillButton;
|
private val _buttonReplies: PillButton;
|
||||||
private val _layoutRating: LinearLayout;
|
private val _layoutRating: LinearLayout;
|
||||||
@@ -77,7 +76,6 @@ class CommentViewHolder : ViewHolder {
|
|||||||
_layoutRating = itemView.findViewById(R.id.layout_rating);
|
_layoutRating = itemView.findViewById(R.id.layout_rating);
|
||||||
_pillRatingLikesDislikes = itemView.findViewById(R.id.rating);
|
_pillRatingLikesDislikes = itemView.findViewById(R.id.rating);
|
||||||
_buttonDelete = itemView.findViewById(R.id.button_delete);
|
_buttonDelete = itemView.findViewById(R.id.button_delete);
|
||||||
_imageCopy = itemView.findViewById(R.id.button_copy)
|
|
||||||
|
|
||||||
_containerComments = itemView.findViewById(R.id.comment_container);
|
_containerComments = itemView.findViewById(R.id.comment_container);
|
||||||
_loader = itemView.findViewById(R.id.loader);
|
_loader = itemView.findViewById(R.id.loader);
|
||||||
@@ -105,30 +103,13 @@ class CommentViewHolder : ViewHolder {
|
|||||||
StatePolycentric.instance.updateLikeMap(c.reference, args.hasLiked, args.hasDisliked)
|
StatePolycentric.instance.updateLikeMap(c.reference, args.hasLiked, args.hasDisliked)
|
||||||
};
|
};
|
||||||
|
|
||||||
val listener = object : GestureDetector.SimpleOnGestureListener() {
|
_textBody.setOnLongClickListener {
|
||||||
override fun onDown(e: MotionEvent): Boolean = true
|
|
||||||
|
|
||||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
|
||||||
val clipboard = viewGroup.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
val clipboard = viewGroup.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
val text = comment?.message.orEmpty()
|
val text = comment?.message.orEmpty()
|
||||||
val clip = ClipData.newPlainText("Comment", text)
|
val clip = ClipData.newPlainText("Comment", text)
|
||||||
clipboard.setPrimaryClip(clip)
|
clipboard.setPrimaryClip(clip)
|
||||||
UIDialogs.toast(viewGroup.context, "Copied", false)
|
UIDialogs.toast(viewGroup.context, "Copied", false)
|
||||||
return true
|
true
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val detector = GestureDetector(viewGroup.context, listener).apply {
|
|
||||||
setOnDoubleTapListener(listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
_imageCopy.apply {
|
|
||||||
isClickable = true
|
|
||||||
setOnTouchListener { v, event ->
|
|
||||||
val consumed = detector.onTouchEvent(event)
|
|
||||||
if (!consumed && event.actionMasked == MotionEvent.ACTION_UP) v.performClick()
|
|
||||||
consumed
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_creatorThumbnail.onClick.subscribe {
|
_creatorThumbnail.onClick.subscribe {
|
||||||
|
|||||||
@@ -159,13 +159,6 @@
|
|||||||
app:pillText="55 Replies"
|
app:pillText="55 Replies"
|
||||||
android:layout_marginStart="15dp" />
|
android:layout_marginStart="15dp" />
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/button_copy"
|
|
||||||
android:layout_width="18dp"
|
|
||||||
android:layout_height="18dp"
|
|
||||||
android:src="@drawable/ic_copy"
|
|
||||||
android:layout_marginLeft="15dp"/>
|
|
||||||
|
|
||||||
<Space android:layout_width="0dp"
|
<Space android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
|
|||||||
+5
-5
@@ -1,8 +1,8 @@
|
|||||||
// 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.
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '8.5.2' apply false
|
id 'com.android.application' version '8.13.0' apply false
|
||||||
id 'com.android.library' version '8.5.2' apply false
|
id 'com.android.library' version '8.13.0' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
|
id 'org.jetbrains.kotlin.android' version '2.2.21' apply false
|
||||||
id 'com.google.protobuf' version '0.9.4' apply false
|
id 'com.google.protobuf' version '0.9.5' apply false
|
||||||
id 'com.google.devtools.ksp' version '1.9.0-1.0.13' apply false
|
id 'com.google.devtools.ksp' version '2.2.21-2.0.4' apply false
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
Submodule dep/futopay updated: 224d69764c...6857c8f0bc
+1
-1
Submodule dep/polycentricandroid updated: 8ee5a329e2...642747fae8
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#Fri Nov 11 13:25:09 CET 2022
|
#Fri Nov 11 13:25:09 CET 2022
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
Reference in New Issue
Block a user