mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-04-29 22:24:29 +02:00
Merge branch 'master' of gitlab.futo.org:videostreaming/grayjay
This commit is contained in:
commit
4a708e316a
@ -882,7 +882,10 @@ class Settings : FragmentedStorageFileJson() {
|
|||||||
@FormFieldWarning(R.string.bypass_rotation_prevention_warning)
|
@FormFieldWarning(R.string.bypass_rotation_prevention_warning)
|
||||||
var bypassRotationPrevention: Boolean = false;
|
var bypassRotationPrevention: Boolean = false;
|
||||||
|
|
||||||
@FormField(R.string.enable_polycentric, FieldForm.TOGGLE, R.string.can_be_disabled_when_you_are_experiencing_issues, 1)
|
@FormField(R.string.playlist_delete_confirmation, FieldForm.TOGGLE, R.string.playlist_delete_confirmation_description, 2)
|
||||||
|
var playlistDeleteConfirmation: Boolean = true;
|
||||||
|
|
||||||
|
@FormField(R.string.enable_polycentric, FieldForm.TOGGLE, R.string.can_be_disabled_when_you_are_experiencing_issues, 3)
|
||||||
var polycentricEnabled: Boolean = true;
|
var polycentricEnabled: Boolean = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,6 +348,13 @@ class UIDialogs {
|
|||||||
showDialog(context, R.drawable.ic_error, text, null, null, 0, cancelButtonAction, confirmButtonAction)
|
showDialog(context, R.drawable.ic_error, text, null, null, 0, cancelButtonAction, confirmButtonAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showConfirmationDialog(context: Context, text: String, action: () -> Unit, cancelAction: (() -> Unit)? = null, doNotAskAgainAction: (() -> Unit)? = null) {
|
||||||
|
val confirmButtonAction = Action(context.getString(R.string.confirm), action, ActionStyle.PRIMARY)
|
||||||
|
val cancelButtonAction = Action(context.getString(R.string.cancel), cancelAction ?: {}, ActionStyle.ACCENT)
|
||||||
|
val doNotAskAgain = Action(context.getString(R.string.do_not_ask_again), doNotAskAgainAction ?: {}, ActionStyle.NONE)
|
||||||
|
showDialog(context, R.drawable.ic_error, text, null, null, 0, doNotAskAgain, cancelButtonAction, confirmButtonAction)
|
||||||
|
}
|
||||||
|
|
||||||
fun showUpdateAvailableDialog(context: Context, lastVersion: Int, hideExceptionButtons: Boolean = false) {
|
fun showUpdateAvailableDialog(context: Context, lastVersion: Int, hideExceptionButtons: Boolean = false) {
|
||||||
val dialog = AutoUpdateDialog(context);
|
val dialog = AutoUpdateDialog(context);
|
||||||
registerDialogOpened(dialog);
|
registerDialogOpened(dialog);
|
||||||
|
@ -101,7 +101,7 @@ class VideoDetailFragment : MainFragment {
|
|||||||
val currentRequestedOrientation = a.requestedOrientation
|
val currentRequestedOrientation = a.requestedOrientation
|
||||||
var currentOrientation = if (_currentOrientation == -1) currentRequestedOrientation else _currentOrientation
|
var currentOrientation = if (_currentOrientation == -1) currentRequestedOrientation else _currentOrientation
|
||||||
if (currentOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT && !Settings.instance.playback.reversePortrait)
|
if (currentOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT && !Settings.instance.playback.reversePortrait)
|
||||||
currentOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
currentOrientation = currentRequestedOrientation
|
||||||
|
|
||||||
val isAutoRotate = Settings.instance.playback.isAutoRotate()
|
val isAutoRotate = Settings.instance.playback.isAutoRotate()
|
||||||
val isFs = isFullscreen
|
val isFs = isFullscreen
|
||||||
@ -347,7 +347,7 @@ class VideoDetailFragment : MainFragment {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State.MAXIMIZED && isFullscreen && !Settings.instance.playback.fullscreenPortrait && (_currentOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT || _currentOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT)) {
|
if (state == State.MAXIMIZED && isFullscreen && !Settings.instance.playback.fullscreenPortrait && (_currentOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT || (Settings.instance.playback.reversePortrait && _currentOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT))) {
|
||||||
_viewDetail?.setFullscreen(false)
|
_viewDetail?.setFullscreen(false)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,10 @@ class MDNSListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
if (_started) throw Exception("Already running.")
|
if (_started) {
|
||||||
|
Logger.i(TAG, "Already started.")
|
||||||
|
return
|
||||||
|
}
|
||||||
_started = true
|
_started = true
|
||||||
|
|
||||||
_scope = CoroutineScope(Dispatchers.IO);
|
_scope = CoroutineScope(Dispatchers.IO);
|
||||||
|
@ -100,33 +100,34 @@ class ServiceRecordAggregator {
|
|||||||
Logger.i(TAG, "$builder")*/
|
Logger.i(TAG, "$builder")*/
|
||||||
|
|
||||||
val currentServices: MutableList<DnsService>
|
val currentServices: MutableList<DnsService>
|
||||||
|
ptrRecords.forEach { record ->
|
||||||
|
val cachedPtrRecord = _cachedPtrRecords.getOrPut(record.first.name) { mutableListOf() }
|
||||||
|
val newPtrRecord = CachedDnsPtrRecord(Date(System.currentTimeMillis() + record.first.timeToLive.toLong() * 1000L), record.second.domainName)
|
||||||
|
cachedPtrRecord.replaceOrAdd(newPtrRecord) { it.target == record.second.domainName }
|
||||||
|
}
|
||||||
|
|
||||||
|
aRecords.forEach { aRecord ->
|
||||||
|
val cachedARecord = _cachedAddressRecords.getOrPut(aRecord.first.name) { mutableListOf() }
|
||||||
|
val newARecord = CachedDnsAddressRecord(Date(System.currentTimeMillis() + aRecord.first.timeToLive.toLong() * 1000L), aRecord.second.address)
|
||||||
|
cachedARecord.replaceOrAdd(newARecord) { it.address == newARecord.address }
|
||||||
|
}
|
||||||
|
|
||||||
|
aaaaRecords.forEach { aaaaRecord ->
|
||||||
|
val cachedAaaaRecord = _cachedAddressRecords.getOrPut(aaaaRecord.first.name) { mutableListOf() }
|
||||||
|
val newAaaaRecord = CachedDnsAddressRecord(Date(System.currentTimeMillis() + aaaaRecord.first.timeToLive.toLong() * 1000L), aaaaRecord.second.address)
|
||||||
|
cachedAaaaRecord.replaceOrAdd(newAaaaRecord) { it.address == newAaaaRecord.address }
|
||||||
|
}
|
||||||
|
|
||||||
|
txtRecords.forEach { txtRecord ->
|
||||||
|
_cachedTxtRecords[txtRecord.first.name] = CachedDnsTxtRecord(Date(System.currentTimeMillis() + txtRecord.first.timeToLive.toLong() * 1000L), txtRecord.second.texts)
|
||||||
|
}
|
||||||
|
|
||||||
|
srvRecords.forEach { srvRecord ->
|
||||||
|
_cachedSrvRecords[srvRecord.first.name] = CachedDnsSrvRecord(Date(System.currentTimeMillis() + srvRecord.first.timeToLive.toLong() * 1000L), srvRecord.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Maybe this can be debounced?
|
||||||
synchronized(this._currentServices) {
|
synchronized(this._currentServices) {
|
||||||
ptrRecords.forEach { record ->
|
|
||||||
val cachedPtrRecord = _cachedPtrRecords.getOrPut(record.first.name) { mutableListOf() }
|
|
||||||
val newPtrRecord = CachedDnsPtrRecord(Date(System.currentTimeMillis() + record.first.timeToLive.toLong() * 1000L), record.second.domainName)
|
|
||||||
cachedPtrRecord.replaceOrAdd(newPtrRecord) { it.target == record.second.domainName }
|
|
||||||
}
|
|
||||||
|
|
||||||
aRecords.forEach { aRecord ->
|
|
||||||
val cachedARecord = _cachedAddressRecords.getOrPut(aRecord.first.name) { mutableListOf() }
|
|
||||||
val newARecord = CachedDnsAddressRecord(Date(System.currentTimeMillis() + aRecord.first.timeToLive.toLong() * 1000L), aRecord.second.address)
|
|
||||||
cachedARecord.replaceOrAdd(newARecord) { it.address == newARecord.address }
|
|
||||||
}
|
|
||||||
|
|
||||||
aaaaRecords.forEach { aaaaRecord ->
|
|
||||||
val cachedAaaaRecord = _cachedAddressRecords.getOrPut(aaaaRecord.first.name) { mutableListOf() }
|
|
||||||
val newAaaaRecord = CachedDnsAddressRecord(Date(System.currentTimeMillis() + aaaaRecord.first.timeToLive.toLong() * 1000L), aaaaRecord.second.address)
|
|
||||||
cachedAaaaRecord.replaceOrAdd(newAaaaRecord) { it.address == newAaaaRecord.address }
|
|
||||||
}
|
|
||||||
|
|
||||||
txtRecords.forEach { txtRecord ->
|
|
||||||
_cachedTxtRecords[txtRecord.first.name] = CachedDnsTxtRecord(Date(System.currentTimeMillis() + txtRecord.first.timeToLive.toLong() * 1000L), txtRecord.second.texts)
|
|
||||||
}
|
|
||||||
|
|
||||||
srvRecords.forEach { srvRecord ->
|
|
||||||
_cachedSrvRecords[srvRecord.first.name] = CachedDnsSrvRecord(Date(System.currentTimeMillis() + srvRecord.first.timeToLive.toLong() * 1000L), srvRecord.second)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentServices = getCurrentServices()
|
currentServices = getCurrentServices()
|
||||||
this._currentServices.clear()
|
this._currentServices.clear()
|
||||||
this._currentServices.addAll(currentServices)
|
this._currentServices.addAll(currentServices)
|
||||||
|
@ -12,6 +12,8 @@ import com.futo.platformplayer.activities.MainActivity
|
|||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.receivers.MediaControlReceiver
|
import com.futo.platformplayer.receivers.MediaControlReceiver
|
||||||
import com.futo.platformplayer.timestampRegex
|
import com.futo.platformplayer.timestampRegex
|
||||||
|
import com.futo.platformplayer.views.behavior.NonScrollingTextView
|
||||||
|
import com.futo.platformplayer.views.behavior.NonScrollingTextView.Companion
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
class PlatformLinkMovementMethod : LinkMovementMethod {
|
class PlatformLinkMovementMethod : LinkMovementMethod {
|
||||||
@ -23,6 +25,7 @@ class PlatformLinkMovementMethod : LinkMovementMethod {
|
|||||||
|
|
||||||
override fun onTouchEvent(widget: TextView, buffer: Spannable, event: MotionEvent): Boolean {
|
override fun onTouchEvent(widget: TextView, buffer: Spannable, event: MotionEvent): Boolean {
|
||||||
val action = event.action;
|
val action = event.action;
|
||||||
|
Logger.i(TAG, "onTouchEvent (action = $action)")
|
||||||
if (action == MotionEvent.ACTION_UP) {
|
if (action == MotionEvent.ACTION_UP) {
|
||||||
val x = event.x.toInt() - widget.totalPaddingLeft + widget.scrollX;
|
val x = event.x.toInt() - widget.totalPaddingLeft + widget.scrollX;
|
||||||
val y = event.y.toInt() - widget.totalPaddingTop + widget.scrollY;
|
val y = event.y.toInt() - widget.totalPaddingTop + widget.scrollY;
|
||||||
|
@ -2,6 +2,8 @@ package com.futo.platformplayer.states
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
@ -20,9 +22,13 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import androidx.work.*
|
import androidx.work.*
|
||||||
import com.futo.platformplayer.*
|
import com.futo.platformplayer.*
|
||||||
import com.futo.platformplayer.R
|
import com.futo.platformplayer.R
|
||||||
|
import com.futo.platformplayer.UIDialogs.Action
|
||||||
|
import com.futo.platformplayer.UIDialogs.ActionStyle
|
||||||
|
import com.futo.platformplayer.UIDialogs.Companion.showDialog
|
||||||
import com.futo.platformplayer.activities.CaptchaActivity
|
import com.futo.platformplayer.activities.CaptchaActivity
|
||||||
import com.futo.platformplayer.activities.IWithResultLauncher
|
import com.futo.platformplayer.activities.IWithResultLauncher
|
||||||
import com.futo.platformplayer.activities.MainActivity
|
import com.futo.platformplayer.activities.MainActivity
|
||||||
|
import com.futo.platformplayer.activities.SettingsActivity
|
||||||
import com.futo.platformplayer.api.media.platforms.js.DevJSClient
|
import com.futo.platformplayer.api.media.platforms.js.DevJSClient
|
||||||
import com.futo.platformplayer.api.media.platforms.js.JSClient
|
import com.futo.platformplayer.api.media.platforms.js.JSClient
|
||||||
import com.futo.platformplayer.background.BackgroundWorker
|
import com.futo.platformplayer.background.BackgroundWorker
|
||||||
@ -419,8 +425,17 @@ class StateApp {
|
|||||||
Logger.onLogSubmitted.subscribe {
|
Logger.onLogSubmitted.subscribe {
|
||||||
scopeOrNull?.launch(Dispatchers.Main) {
|
scopeOrNull?.launch(Dispatchers.Main) {
|
||||||
try {
|
try {
|
||||||
if (it != null) {
|
if (!it.isNullOrEmpty()) {
|
||||||
UIDialogs.toast("Uploaded $it", true);
|
(SettingsActivity.getActivity() ?: contextOrNull)?.let { c ->
|
||||||
|
val okButtonAction = Action(c.getString(R.string.ok), {}, ActionStyle.PRIMARY)
|
||||||
|
val copyButtonAction = Action(c.getString(R.string.copy), {
|
||||||
|
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
val clip = ClipData.newPlainText("Log id", it)
|
||||||
|
clipboard.setPrimaryClip(clip)
|
||||||
|
}, ActionStyle.NONE)
|
||||||
|
|
||||||
|
showDialog(c, R.drawable.ic_error, "Uploaded $it", null, null, 0, copyButtonAction, okButtonAction)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
UIDialogs.toast("Failed to upload");
|
UIDialogs.toast("Failed to upload");
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import android.widget.FrameLayout
|
|||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.futo.platformplayer.Settings
|
||||||
|
import com.futo.platformplayer.UIDialogs
|
||||||
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
|
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
|
||||||
import com.futo.platformplayer.constructs.Event1
|
import com.futo.platformplayer.constructs.Event1
|
||||||
import com.futo.platformplayer.constructs.Event2
|
import com.futo.platformplayer.constructs.Event2
|
||||||
@ -53,14 +55,30 @@ class VideoListEditorView : FrameLayout {
|
|||||||
};
|
};
|
||||||
|
|
||||||
adapterVideos.onRemove.subscribe { v ->
|
adapterVideos.onRemove.subscribe { v ->
|
||||||
synchronized(_videos) {
|
val executeDelete = {
|
||||||
val index = _videos.indexOf(v);
|
synchronized(_videos) {
|
||||||
if(index >= 0) {
|
val index = _videos.indexOf(v);
|
||||||
_videos.removeAt(index);
|
if(index >= 0) {
|
||||||
onVideoRemoved.emit(v);
|
_videos.removeAt(index);
|
||||||
|
onVideoRemoved.emit(v);
|
||||||
|
}
|
||||||
|
adapterVideos.notifyItemRemoved(index);
|
||||||
}
|
}
|
||||||
adapterVideos.notifyItemRemoved(index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Settings.instance.other.playlistDeleteConfirmation) {
|
||||||
|
UIDialogs.showConfirmationDialog(context, "Please confirm to delete", action = {
|
||||||
|
executeDelete()
|
||||||
|
}, cancelAction = {
|
||||||
|
|
||||||
|
}, doNotAskAgainAction = {
|
||||||
|
Settings.instance.other.playlistDeleteConfirmation = false
|
||||||
|
Settings.instance.save()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
executeDelete()
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
adapterVideos.onClick.subscribe(onVideoClicked::emit);
|
adapterVideos.onClick.subscribe(onVideoClicked::emit);
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
<string name="yes">Yes</string>
|
<string name="yes">Yes</string>
|
||||||
<string name="no">No</string>
|
<string name="no">No</string>
|
||||||
<string name="confirm">Confirm</string>
|
<string name="confirm">Confirm</string>
|
||||||
|
<string name="do_not_ask_again">Don\'t ask again</string>
|
||||||
<string name="confirm_delete_playlist">Are you sure you want to delete this playlist?</string>
|
<string name="confirm_delete_playlist">Are you sure you want to delete this playlist?</string>
|
||||||
<string name="confirm_delete_subscription">Are you sure you want to delete this subscription?</string>
|
<string name="confirm_delete_subscription">Are you sure you want to delete this subscription?</string>
|
||||||
<string name="confirm_remove_source">Removing this source will result in some of your subscriptions not being resolved.</string>
|
<string name="confirm_remove_source">Removing this source will result in some of your subscriptions not being resolved.</string>
|
||||||
@ -418,6 +419,8 @@
|
|||||||
<string name="payment">Payment</string>
|
<string name="payment">Payment</string>
|
||||||
<string name="payment_status">Payment Status</string>
|
<string name="payment_status">Payment Status</string>
|
||||||
<string name="bypass_rotation_prevention">Bypass Rotation Prevention</string>
|
<string name="bypass_rotation_prevention">Bypass Rotation Prevention</string>
|
||||||
|
<string name="playlist_delete_confirmation">Playlist Delete Confirmation</string>
|
||||||
|
<string name="playlist_delete_confirmation_description">Show confirmation dialog when deleting media from a playlist</string>
|
||||||
<string name="enable_polycentric">Enable Polycentric</string>
|
<string name="enable_polycentric">Enable Polycentric</string>
|
||||||
<string name="can_be_disabled_when_you_are_experiencing_issues">Can be disabled when you are experiencing issues</string>
|
<string name="can_be_disabled_when_you_are_experiencing_issues">Can be disabled when you are experiencing issues</string>
|
||||||
<string name="bypass_rotation_prevention_description">Allows for rotation on non-video views.\nWARNING: Not designed for it</string>
|
<string name="bypass_rotation_prevention_description">Allows for rotation on non-video views.\nWARNING: Not designed for it</string>
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
<data android:host="bitchute.com" />
|
<data android:host="bitchute.com" />
|
||||||
<data android:host="www.bitchute.com" />
|
<data android:host="www.bitchute.com" />
|
||||||
<data android:host="old.bitchute.com" />
|
<data android:host="old.bitchute.com" />
|
||||||
|
<data android:host="open.spotify.com" />
|
||||||
|
<data android:host="music.youtube.com" />
|
||||||
<data android:pathPrefix="/" />
|
<data android:pathPrefix="/" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter android:autoVerify="true">
|
<intent-filter android:autoVerify="true">
|
||||||
@ -67,6 +69,8 @@
|
|||||||
<data android:host="bitchute.com" />
|
<data android:host="bitchute.com" />
|
||||||
<data android:host="www.bitchute.com" />
|
<data android:host="www.bitchute.com" />
|
||||||
<data android:host="old.bitchute.com" />
|
<data android:host="old.bitchute.com" />
|
||||||
|
<data android:host="open.spotify.com" />
|
||||||
|
<data android:host="music.youtube.com" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user