feat: add PiP error notifications
This commit is contained in:
@@ -2,7 +2,9 @@ package com.edde746.plezy
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.app.AppOpsManager
|
||||
import android.app.PictureInPictureParams
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.util.Rational
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
@@ -34,13 +36,41 @@ class MainActivity : FlutterActivity() {
|
||||
result.success(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
}
|
||||
"enter" -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
result.success(mapOf("success" to false, "errorCode" to "android_version"))
|
||||
return@setMethodCallHandler
|
||||
}
|
||||
|
||||
// Check if PiP permission is granted via AppOpsManager
|
||||
val appOpsManager = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
|
||||
val pipAllowed = appOpsManager.checkOpNoThrow(
|
||||
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
|
||||
applicationInfo.uid,
|
||||
packageName
|
||||
) == AppOpsManager.MODE_ALLOWED
|
||||
|
||||
if (!pipAllowed) {
|
||||
result.success(mapOf("success" to false, "errorCode" to "permission_disabled"))
|
||||
return@setMethodCallHandler
|
||||
}
|
||||
|
||||
try {
|
||||
val width = call.argument<Int>("width") ?: 16
|
||||
val height = call.argument<Int>("height") ?: 9
|
||||
val params = PictureInPictureParams.Builder().setAspectRatio(Rational(width, height)).build()
|
||||
enterPictureInPictureMode(params)
|
||||
val params = PictureInPictureParams.Builder()
|
||||
.setAspectRatio(Rational(width, height))
|
||||
.build()
|
||||
val success = enterPictureInPictureMode(params)
|
||||
if (success) {
|
||||
result.success(mapOf("success" to true))
|
||||
} else {
|
||||
result.success(mapOf("success" to false, "errorCode" to "failed"))
|
||||
}
|
||||
} catch (e: IllegalStateException) {
|
||||
result.success(mapOf("success" to false, "errorCode" to "not_supported"))
|
||||
} catch (e: Exception) {
|
||||
result.success(mapOf("success" to false, "errorCode" to "unknown", "errorMessage" to (e.message ?: "Unknown error")))
|
||||
}
|
||||
result.success(null)
|
||||
} else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,7 +290,15 @@
|
||||
"rotationLockButton": "Drehsperre",
|
||||
"timelineSlider": "Video-Zeitleiste",
|
||||
"volumeSlider": "Lautstärkepegel",
|
||||
"backButton": "Zurück"
|
||||
"backButton": "Zurück",
|
||||
"pipFailed": "Bild-in-Bild konnte nicht gestartet werden",
|
||||
"pipErrors": {
|
||||
"androidVersion": "Erfordert Android 8.0 oder neuer",
|
||||
"permissionDisabled": "Bild-in-Bild-Berechtigung ist deaktiviert. Aktiviere sie unter Einstellungen > Apps > Plezy > Bild-in-Bild",
|
||||
"notSupported": "Dieses Gerät unterstützt den Bild-in-Bild-Modus nicht",
|
||||
"failed": "Bild-in-Bild konnte nicht gestartet werden",
|
||||
"unknown": "Ein Fehler ist aufgetreten: ${error}"
|
||||
}
|
||||
},
|
||||
"userStatus": {
|
||||
"admin": "Eigentümer",
|
||||
|
||||
@@ -289,7 +289,15 @@
|
||||
"rotationLockButton": "Rotation lock",
|
||||
"timelineSlider": "Video timeline",
|
||||
"volumeSlider": "Volume level",
|
||||
"backButton": "Back"
|
||||
"backButton": "Back",
|
||||
"pipFailed": "Picture-in-picture failed to start",
|
||||
"pipErrors": {
|
||||
"androidVersion": "Requires Android 8.0 or newer",
|
||||
"permissionDisabled": "Picture-in-picture permission is disabled. Enable it in Settings > Apps > Plezy > Picture-in-picture",
|
||||
"notSupported": "Device doesn't support picture-in-picture mode",
|
||||
"failed": "Picture-in-picture failed to start",
|
||||
"unknown": "An error occurred: ${error}"
|
||||
}
|
||||
},
|
||||
"userStatus": {
|
||||
"admin": "Admin",
|
||||
|
||||
@@ -289,7 +289,15 @@
|
||||
"rotationLockButton": "Verrouillage de rotation",
|
||||
"timelineSlider": "Timeline vidéo",
|
||||
"volumeSlider": "Niveau sonore",
|
||||
"backButton": "Retour"
|
||||
"backButton": "Retour",
|
||||
"pipFailed": "Échec du démarrage du mode image dans l'image",
|
||||
"pipErrors": {
|
||||
"androidVersion": "Nécessite Android 8.0 ou plus récent",
|
||||
"permissionDisabled": "L'autorisation Image dans l'image est désactivée. Activez-la dans Paramètres > Applications > Plezy > Image dans l'image",
|
||||
"notSupported": "Cet appareil ne prend pas en charge le mode image dans l'image",
|
||||
"failed": "Échec du démarrage du mode image dans l'image",
|
||||
"unknown": "Une erreur s'est produite : ${error}"
|
||||
}
|
||||
},
|
||||
"userStatus": {
|
||||
"admin": "Admin",
|
||||
|
||||
@@ -290,7 +290,15 @@
|
||||
"rotationLockButton": "Blocco rotazione",
|
||||
"timelineSlider": "Timeline video",
|
||||
"volumeSlider": "Livello volume",
|
||||
"backButton": "Indietro"
|
||||
"backButton": "Indietro",
|
||||
"pipFailed": "Impossibile avviare la modalità Picture-in-Picture",
|
||||
"pipErrors": {
|
||||
"androidVersion": "Richiede Android 8.0 o versioni successive",
|
||||
"permissionDisabled": "L'autorizzazione Picture-in-Picture è disabilitata. Abilitala in Impostazioni > App > Plezy > Picture-in-Picture",
|
||||
"notSupported": "Questo dispositivo non supporta la modalità Picture-in-Picture",
|
||||
"failed": "Impossibile avviare la modalità Picture-in-Picture",
|
||||
"unknown": "Si è verificato un errore: ${error}"
|
||||
}
|
||||
},
|
||||
"userStatus": {
|
||||
"admin": "Admin",
|
||||
|
||||
@@ -290,7 +290,15 @@
|
||||
"rotationLockButton": "회전 잠금",
|
||||
"timelineSlider": "타임라인",
|
||||
"volumeSlider": "볼륨 조절",
|
||||
"backButton": "뒤로 가기"
|
||||
"backButton": "뒤로 가기",
|
||||
"pipFailed": "화면 속 화면 모드를 시작할 수 없습니다",
|
||||
"pipErrors": {
|
||||
"androidVersion": "Android 8.0 이상이 필요합니다",
|
||||
"permissionDisabled": "화면 속 화면 권한이 비활성화되어 있습니다. 설정 > 앱 > Plezy > 화면 속 화면에서 활성화하세요",
|
||||
"notSupported": "이 기기는 화면 속 화면 모드를 지원하지 않습니다",
|
||||
"failed": "화면 속 화면 모드를 시작할 수 없습니다",
|
||||
"unknown": "오류가 발생했습니다: ${error}"
|
||||
}
|
||||
},
|
||||
"userStatus": {
|
||||
"admin": "관리자",
|
||||
|
||||
@@ -290,7 +290,15 @@
|
||||
"rotationLockButton": "Rotatievergrendeling",
|
||||
"timelineSlider": "Videotijdlijn",
|
||||
"volumeSlider": "Volumeniveau",
|
||||
"backButton": "Terug"
|
||||
"backButton": "Terug",
|
||||
"pipFailed": "Beeld-in-beeld kon niet worden gestart",
|
||||
"pipErrors": {
|
||||
"androidVersion": "Vereist Android 8.0 of nieuwer",
|
||||
"permissionDisabled": "Beeld-in-beeld toestemming is uitgeschakeld. Schakel deze in via Instellingen > Apps > Plezy > Beeld-in-beeld",
|
||||
"notSupported": "Dit apparaat ondersteunt geen beeld-in-beeld modus",
|
||||
"failed": "Beeld-in-beeld kon niet worden gestart",
|
||||
"unknown": "Er is een fout opgetreden: ${error}"
|
||||
}
|
||||
},
|
||||
"userStatus": {
|
||||
"admin": "Beheerder",
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 8
|
||||
/// Strings: 4324 (540 per locale)
|
||||
/// Strings: 4372 (546 per locale)
|
||||
///
|
||||
/// Built on 2026-01-20 at 15:18 UTC
|
||||
/// Built on 2026-01-21 at 22:57 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint, unused_import
|
||||
|
||||
@@ -442,6 +442,8 @@ class _TranslationsVideoControlsDe implements TranslationsVideoControlsEn {
|
||||
@override String get timelineSlider => 'Video-Zeitleiste';
|
||||
@override String get volumeSlider => 'Lautstärkepegel';
|
||||
@override String get backButton => 'Zurück';
|
||||
@override String get pipFailed => 'Bild-in-Bild konnte nicht gestartet werden';
|
||||
@override late final _TranslationsVideoControlsPipErrorsDe pipErrors = _TranslationsVideoControlsPipErrorsDe._(_root);
|
||||
}
|
||||
|
||||
// Path: userStatus
|
||||
@@ -902,6 +904,20 @@ class _TranslationsHotkeysActionsDe implements TranslationsHotkeysActionsEn {
|
||||
@override String get subSeekPrev => 'Zum vorherigen Untertitel springen';
|
||||
}
|
||||
|
||||
// Path: videoControls.pipErrors
|
||||
class _TranslationsVideoControlsPipErrorsDe implements TranslationsVideoControlsPipErrorsEn {
|
||||
_TranslationsVideoControlsPipErrorsDe._(this._root);
|
||||
|
||||
final TranslationsDe _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get androidVersion => 'Erfordert Android 8.0 oder neuer';
|
||||
@override String get permissionDisabled => 'Bild-in-Bild-Berechtigung ist deaktiviert. Aktiviere sie unter Einstellungen > Apps > Plezy > Bild-in-Bild';
|
||||
@override String get notSupported => 'Dieses Gerät unterstützt den Bild-in-Bild-Modus nicht';
|
||||
@override String get failed => 'Bild-in-Bild konnte nicht gestartet werden';
|
||||
@override String unknown({required Object error}) => 'Ein Fehler ist aufgetreten: ${error}';
|
||||
}
|
||||
|
||||
// Path: libraries.tabs
|
||||
class _TranslationsLibrariesTabsDe implements TranslationsLibrariesTabsEn {
|
||||
_TranslationsLibrariesTabsDe._(this._root);
|
||||
@@ -1201,6 +1217,12 @@ extension on TranslationsDe {
|
||||
'videoControls.timelineSlider' => 'Video-Zeitleiste',
|
||||
'videoControls.volumeSlider' => 'Lautstärkepegel',
|
||||
'videoControls.backButton' => 'Zurück',
|
||||
'videoControls.pipFailed' => 'Bild-in-Bild konnte nicht gestartet werden',
|
||||
'videoControls.pipErrors.androidVersion' => 'Erfordert Android 8.0 oder neuer',
|
||||
'videoControls.pipErrors.permissionDisabled' => 'Bild-in-Bild-Berechtigung ist deaktiviert. Aktiviere sie unter Einstellungen > Apps > Plezy > Bild-in-Bild',
|
||||
'videoControls.pipErrors.notSupported' => 'Dieses Gerät unterstützt den Bild-in-Bild-Modus nicht',
|
||||
'videoControls.pipErrors.failed' => 'Bild-in-Bild konnte nicht gestartet werden',
|
||||
'videoControls.pipErrors.unknown' => ({required Object error}) => 'Ein Fehler ist aufgetreten: ${error}',
|
||||
'userStatus.admin' => 'Eigentümer',
|
||||
'userStatus.restricted' => 'Eingeschränkt',
|
||||
'userStatus.protected' => 'Geschützt',
|
||||
@@ -1444,14 +1466,14 @@ extension on TranslationsDe {
|
||||
'watchTogether.joining' => 'Beitreten...',
|
||||
'watchTogether.controlMode' => 'Steuerungsmodus',
|
||||
'watchTogether.controlModeQuestion' => 'Wer kann die Wiedergabe steuern?',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.hostOnly' => 'Nur Host',
|
||||
'watchTogether.anyone' => 'Alle',
|
||||
'watchTogether.hostingSession' => 'Sitzung Hosten',
|
||||
'watchTogether.inSession' => 'In Sitzung',
|
||||
'watchTogether.sessionCode' => 'Sitzungscode',
|
||||
'watchTogether.hostControlsPlayback' => 'Host steuert die Wiedergabe',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.anyoneCanControl' => 'Alle können die Wiedergabe steuern',
|
||||
'watchTogether.hostControls' => 'Host steuert',
|
||||
'watchTogether.anyoneControls' => 'Alle steuern',
|
||||
|
||||
@@ -935,6 +935,11 @@ class TranslationsVideoControlsEn {
|
||||
|
||||
/// en: 'Back'
|
||||
String get backButton => 'Back';
|
||||
|
||||
/// en: 'Picture-in-picture failed to start'
|
||||
String get pipFailed => 'Picture-in-picture failed to start';
|
||||
|
||||
late final TranslationsVideoControlsPipErrorsEn pipErrors = TranslationsVideoControlsPipErrorsEn._(_root);
|
||||
}
|
||||
|
||||
// Path: userStatus
|
||||
@@ -1963,6 +1968,30 @@ class TranslationsHotkeysActionsEn {
|
||||
String get subSeekPrev => 'Seek to Previous Subtitle';
|
||||
}
|
||||
|
||||
// Path: videoControls.pipErrors
|
||||
class TranslationsVideoControlsPipErrorsEn {
|
||||
TranslationsVideoControlsPipErrorsEn._(this._root);
|
||||
|
||||
final Translations _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
|
||||
/// en: 'Requires Android 8.0 or newer'
|
||||
String get androidVersion => 'Requires Android 8.0 or newer';
|
||||
|
||||
/// en: 'Picture-in-picture permission is disabled. Enable it in Settings > Apps > Plezy > Picture-in-picture'
|
||||
String get permissionDisabled => 'Picture-in-picture permission is disabled. Enable it in Settings > Apps > Plezy > Picture-in-picture';
|
||||
|
||||
/// en: 'Device doesn't support picture-in-picture mode'
|
||||
String get notSupported => 'Device doesn\'t support picture-in-picture mode';
|
||||
|
||||
/// en: 'Picture-in-picture failed to start'
|
||||
String get failed => 'Picture-in-picture failed to start';
|
||||
|
||||
/// en: 'An error occurred: ${error}'
|
||||
String unknown({required Object error}) => 'An error occurred: ${error}';
|
||||
}
|
||||
|
||||
// Path: libraries.tabs
|
||||
class TranslationsLibrariesTabsEn {
|
||||
TranslationsLibrariesTabsEn._(this._root);
|
||||
@@ -2281,6 +2310,12 @@ extension on Translations {
|
||||
'videoControls.timelineSlider' => 'Video timeline',
|
||||
'videoControls.volumeSlider' => 'Volume level',
|
||||
'videoControls.backButton' => 'Back',
|
||||
'videoControls.pipFailed' => 'Picture-in-picture failed to start',
|
||||
'videoControls.pipErrors.androidVersion' => 'Requires Android 8.0 or newer',
|
||||
'videoControls.pipErrors.permissionDisabled' => 'Picture-in-picture permission is disabled. Enable it in Settings > Apps > Plezy > Picture-in-picture',
|
||||
'videoControls.pipErrors.notSupported' => 'Device doesn\'t support picture-in-picture mode',
|
||||
'videoControls.pipErrors.failed' => 'Picture-in-picture failed to start',
|
||||
'videoControls.pipErrors.unknown' => ({required Object error}) => 'An error occurred: ${error}',
|
||||
'userStatus.admin' => 'Admin',
|
||||
'userStatus.restricted' => 'Restricted',
|
||||
'userStatus.protected' => 'Protected',
|
||||
@@ -2525,14 +2560,14 @@ extension on Translations {
|
||||
'watchTogether.watchingWithOthers' => 'Watching with others',
|
||||
'watchTogether.endSession' => 'End Session',
|
||||
'watchTogether.leaveSession' => 'Leave Session',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.endSessionQuestion' => 'End Session?',
|
||||
'watchTogether.leaveSessionQuestion' => 'Leave Session?',
|
||||
'watchTogether.endSessionConfirm' => 'This will end the session for all participants.',
|
||||
'watchTogether.leaveSessionConfirm' => 'You will be removed from the session.',
|
||||
'watchTogether.endSessionConfirmOverlay' => 'This will end the watch session for all participants.',
|
||||
'watchTogether.leaveSessionConfirmOverlay' => 'You will be disconnected from the watch session.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.end' => 'End',
|
||||
'watchTogether.leave' => 'Leave',
|
||||
'watchTogether.syncing' => 'Syncing...',
|
||||
|
||||
@@ -441,6 +441,8 @@ class _TranslationsVideoControlsFr implements TranslationsVideoControlsEn {
|
||||
@override String get timelineSlider => 'Timeline vidéo';
|
||||
@override String get volumeSlider => 'Niveau sonore';
|
||||
@override String get backButton => 'Retour';
|
||||
@override String get pipFailed => 'Échec du démarrage du mode image dans l\'image';
|
||||
@override late final _TranslationsVideoControlsPipErrorsFr pipErrors = _TranslationsVideoControlsPipErrorsFr._(_root);
|
||||
}
|
||||
|
||||
// Path: userStatus
|
||||
@@ -900,6 +902,20 @@ class _TranslationsHotkeysActionsFr implements TranslationsHotkeysActionsEn {
|
||||
@override String get subSeekPrev => 'Rechercher le sous-titre précédent';
|
||||
}
|
||||
|
||||
// Path: videoControls.pipErrors
|
||||
class _TranslationsVideoControlsPipErrorsFr implements TranslationsVideoControlsPipErrorsEn {
|
||||
_TranslationsVideoControlsPipErrorsFr._(this._root);
|
||||
|
||||
final TranslationsFr _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get androidVersion => 'Nécessite Android 8.0 ou plus récent';
|
||||
@override String get permissionDisabled => 'L\'autorisation Image dans l\'image est désactivée. Activez-la dans Paramètres > Applications > Plezy > Image dans l\'image';
|
||||
@override String get notSupported => 'Cet appareil ne prend pas en charge le mode image dans l\'image';
|
||||
@override String get failed => 'Échec du démarrage du mode image dans l\'image';
|
||||
@override String unknown({required Object error}) => 'Une erreur s\'est produite : ${error}';
|
||||
}
|
||||
|
||||
// Path: libraries.tabs
|
||||
class _TranslationsLibrariesTabsFr implements TranslationsLibrariesTabsEn {
|
||||
_TranslationsLibrariesTabsFr._(this._root);
|
||||
@@ -1198,6 +1214,12 @@ extension on TranslationsFr {
|
||||
'videoControls.timelineSlider' => 'Timeline vidéo',
|
||||
'videoControls.volumeSlider' => 'Niveau sonore',
|
||||
'videoControls.backButton' => 'Retour',
|
||||
'videoControls.pipFailed' => 'Échec du démarrage du mode image dans l\'image',
|
||||
'videoControls.pipErrors.androidVersion' => 'Nécessite Android 8.0 ou plus récent',
|
||||
'videoControls.pipErrors.permissionDisabled' => 'L\'autorisation Image dans l\'image est désactivée. Activez-la dans Paramètres > Applications > Plezy > Image dans l\'image',
|
||||
'videoControls.pipErrors.notSupported' => 'Cet appareil ne prend pas en charge le mode image dans l\'image',
|
||||
'videoControls.pipErrors.failed' => 'Échec du démarrage du mode image dans l\'image',
|
||||
'videoControls.pipErrors.unknown' => ({required Object error}) => 'Une erreur s\'est produite : ${error}',
|
||||
'userStatus.admin' => 'Admin',
|
||||
'userStatus.restricted' => 'Restreint',
|
||||
'userStatus.protected' => 'Protégé',
|
||||
@@ -1442,14 +1464,14 @@ extension on TranslationsFr {
|
||||
'watchTogether.watchingWithOthers' => 'Regarder avec d\'autres personnes',
|
||||
'watchTogether.endSession' => 'Fin de session',
|
||||
'watchTogether.leaveSession' => 'Quitter la session',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.endSessionQuestion' => 'Terminer la session ?',
|
||||
'watchTogether.leaveSessionQuestion' => 'Quitter la session ?',
|
||||
'watchTogether.endSessionConfirm' => 'Cela mettra fin à la session pour tous les participants.',
|
||||
'watchTogether.leaveSessionConfirm' => 'Vous allez être déconnecté de la session.',
|
||||
'watchTogether.endSessionConfirmOverlay' => 'Cela mettra fin à la session de visionnage pour tous les participants.',
|
||||
'watchTogether.leaveSessionConfirmOverlay' => 'Vous serez déconnecté de la session de visionnage.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.end' => 'Terminer',
|
||||
'watchTogether.leave' => 'Fin',
|
||||
'watchTogether.syncing' => 'Synchronisation...',
|
||||
|
||||
@@ -442,6 +442,8 @@ class _TranslationsVideoControlsIt implements TranslationsVideoControlsEn {
|
||||
@override String get timelineSlider => 'Timeline video';
|
||||
@override String get volumeSlider => 'Livello volume';
|
||||
@override String get backButton => 'Indietro';
|
||||
@override String get pipFailed => 'Impossibile avviare la modalità Picture-in-Picture';
|
||||
@override late final _TranslationsVideoControlsPipErrorsIt pipErrors = _TranslationsVideoControlsPipErrorsIt._(_root);
|
||||
}
|
||||
|
||||
// Path: userStatus
|
||||
@@ -902,6 +904,20 @@ class _TranslationsHotkeysActionsIt implements TranslationsHotkeysActionsEn {
|
||||
@override String get subSeekPrev => 'Vai al sottotitolo precedente';
|
||||
}
|
||||
|
||||
// Path: videoControls.pipErrors
|
||||
class _TranslationsVideoControlsPipErrorsIt implements TranslationsVideoControlsPipErrorsEn {
|
||||
_TranslationsVideoControlsPipErrorsIt._(this._root);
|
||||
|
||||
final TranslationsIt _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get androidVersion => 'Richiede Android 8.0 o versioni successive';
|
||||
@override String get permissionDisabled => 'L\'autorizzazione Picture-in-Picture è disabilitata. Abilitala in Impostazioni > App > Plezy > Picture-in-Picture';
|
||||
@override String get notSupported => 'Questo dispositivo non supporta la modalità Picture-in-Picture';
|
||||
@override String get failed => 'Impossibile avviare la modalità Picture-in-Picture';
|
||||
@override String unknown({required Object error}) => 'Si è verificato un errore: ${error}';
|
||||
}
|
||||
|
||||
// Path: libraries.tabs
|
||||
class _TranslationsLibrariesTabsIt implements TranslationsLibrariesTabsEn {
|
||||
_TranslationsLibrariesTabsIt._(this._root);
|
||||
@@ -1201,6 +1217,12 @@ extension on TranslationsIt {
|
||||
'videoControls.timelineSlider' => 'Timeline video',
|
||||
'videoControls.volumeSlider' => 'Livello volume',
|
||||
'videoControls.backButton' => 'Indietro',
|
||||
'videoControls.pipFailed' => 'Impossibile avviare la modalità Picture-in-Picture',
|
||||
'videoControls.pipErrors.androidVersion' => 'Richiede Android 8.0 o versioni successive',
|
||||
'videoControls.pipErrors.permissionDisabled' => 'L\'autorizzazione Picture-in-Picture è disabilitata. Abilitala in Impostazioni > App > Plezy > Picture-in-Picture',
|
||||
'videoControls.pipErrors.notSupported' => 'Questo dispositivo non supporta la modalità Picture-in-Picture',
|
||||
'videoControls.pipErrors.failed' => 'Impossibile avviare la modalità Picture-in-Picture',
|
||||
'videoControls.pipErrors.unknown' => ({required Object error}) => 'Si è verificato un errore: ${error}',
|
||||
'userStatus.admin' => 'Admin',
|
||||
'userStatus.restricted' => 'Limitato',
|
||||
'userStatus.protected' => 'Protetto',
|
||||
@@ -1444,14 +1466,14 @@ extension on TranslationsIt {
|
||||
'watchTogether.joining' => 'Connessione...',
|
||||
'watchTogether.controlMode' => 'Modalità di Controllo',
|
||||
'watchTogether.controlModeQuestion' => 'Chi può controllare la riproduzione?',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.hostOnly' => 'Solo Host',
|
||||
'watchTogether.anyone' => 'Tutti',
|
||||
'watchTogether.hostingSession' => 'Hosting Sessione',
|
||||
'watchTogether.inSession' => 'In Sessione',
|
||||
'watchTogether.sessionCode' => 'Codice Sessione',
|
||||
'watchTogether.hostControlsPlayback' => 'L\'host controlla la riproduzione',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.anyoneCanControl' => 'Tutti possono controllare la riproduzione',
|
||||
'watchTogether.hostControls' => 'Controllo host',
|
||||
'watchTogether.anyoneControls' => 'Controllo di tutti',
|
||||
|
||||
@@ -442,6 +442,8 @@ class _TranslationsVideoControlsKo implements TranslationsVideoControlsEn {
|
||||
@override String get timelineSlider => '타임라인';
|
||||
@override String get volumeSlider => '볼륨 조절';
|
||||
@override String get backButton => '뒤로 가기';
|
||||
@override String get pipFailed => '화면 속 화면 모드를 시작할 수 없습니다';
|
||||
@override late final _TranslationsVideoControlsPipErrorsKo pipErrors = _TranslationsVideoControlsPipErrorsKo._(_root);
|
||||
}
|
||||
|
||||
// Path: userStatus
|
||||
@@ -902,6 +904,20 @@ class _TranslationsHotkeysActionsKo implements TranslationsHotkeysActionsEn {
|
||||
@override String get subSeekPrev => '이전 자막으로 이동';
|
||||
}
|
||||
|
||||
// Path: videoControls.pipErrors
|
||||
class _TranslationsVideoControlsPipErrorsKo implements TranslationsVideoControlsPipErrorsEn {
|
||||
_TranslationsVideoControlsPipErrorsKo._(this._root);
|
||||
|
||||
final TranslationsKo _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get androidVersion => 'Android 8.0 이상이 필요합니다';
|
||||
@override String get permissionDisabled => '화면 속 화면 권한이 비활성화되어 있습니다. 설정 > 앱 > Plezy > 화면 속 화면에서 활성화하세요';
|
||||
@override String get notSupported => '이 기기는 화면 속 화면 모드를 지원하지 않습니다';
|
||||
@override String get failed => '화면 속 화면 모드를 시작할 수 없습니다';
|
||||
@override String unknown({required Object error}) => '오류가 발생했습니다: ${error}';
|
||||
}
|
||||
|
||||
// Path: libraries.tabs
|
||||
class _TranslationsLibrariesTabsKo implements TranslationsLibrariesTabsEn {
|
||||
_TranslationsLibrariesTabsKo._(this._root);
|
||||
@@ -1201,6 +1217,12 @@ extension on TranslationsKo {
|
||||
'videoControls.timelineSlider' => '타임라인',
|
||||
'videoControls.volumeSlider' => '볼륨 조절',
|
||||
'videoControls.backButton' => '뒤로 가기',
|
||||
'videoControls.pipFailed' => '화면 속 화면 모드를 시작할 수 없습니다',
|
||||
'videoControls.pipErrors.androidVersion' => 'Android 8.0 이상이 필요합니다',
|
||||
'videoControls.pipErrors.permissionDisabled' => '화면 속 화면 권한이 비활성화되어 있습니다. 설정 > 앱 > Plezy > 화면 속 화면에서 활성화하세요',
|
||||
'videoControls.pipErrors.notSupported' => '이 기기는 화면 속 화면 모드를 지원하지 않습니다',
|
||||
'videoControls.pipErrors.failed' => '화면 속 화면 모드를 시작할 수 없습니다',
|
||||
'videoControls.pipErrors.unknown' => ({required Object error}) => '오류가 발생했습니다: ${error}',
|
||||
'userStatus.admin' => '관리자',
|
||||
'userStatus.restricted' => '제한됨',
|
||||
'userStatus.protected' => '보호됨',
|
||||
@@ -1444,14 +1466,14 @@ extension on TranslationsKo {
|
||||
'watchTogether.hostBadge' => '호스트',
|
||||
'watchTogether.youAreHost' => '당신은 호스트 입니다',
|
||||
'watchTogether.watchingWithOthers' => '다른 사람과 함께 시청 중',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.endSession' => '세션 종료',
|
||||
'watchTogether.leaveSession' => '세션 탈퇴',
|
||||
'watchTogether.endSessionQuestion' => '세션을 종료 하시겠습니까?',
|
||||
'watchTogether.leaveSessionQuestion' => '세션을 탈퇴 하시겠습니까?',
|
||||
'watchTogether.endSessionConfirm' => '이 작업은 모든 참가자의 세션을 종료합니다.',
|
||||
'watchTogether.leaveSessionConfirm' => '당신은 세션에서 제거됩니다.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.endSessionConfirmOverlay' => '이것은 모든 참가자의 시청 세션을 종료합니다.',
|
||||
'watchTogether.leaveSessionConfirmOverlay' => '시청 세션 연결이 끊어집니다.',
|
||||
'watchTogether.end' => '종료',
|
||||
|
||||
@@ -442,6 +442,8 @@ class _TranslationsVideoControlsNl implements TranslationsVideoControlsEn {
|
||||
@override String get timelineSlider => 'Videotijdlijn';
|
||||
@override String get volumeSlider => 'Volumeniveau';
|
||||
@override String get backButton => 'Terug';
|
||||
@override String get pipFailed => 'Beeld-in-beeld kon niet worden gestart';
|
||||
@override late final _TranslationsVideoControlsPipErrorsNl pipErrors = _TranslationsVideoControlsPipErrorsNl._(_root);
|
||||
}
|
||||
|
||||
// Path: userStatus
|
||||
@@ -902,6 +904,20 @@ class _TranslationsHotkeysActionsNl implements TranslationsHotkeysActionsEn {
|
||||
@override String get subSeekPrev => 'Naar vorige ondertitel';
|
||||
}
|
||||
|
||||
// Path: videoControls.pipErrors
|
||||
class _TranslationsVideoControlsPipErrorsNl implements TranslationsVideoControlsPipErrorsEn {
|
||||
_TranslationsVideoControlsPipErrorsNl._(this._root);
|
||||
|
||||
final TranslationsNl _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get androidVersion => 'Vereist Android 8.0 of nieuwer';
|
||||
@override String get permissionDisabled => 'Beeld-in-beeld toestemming is uitgeschakeld. Schakel deze in via Instellingen > Apps > Plezy > Beeld-in-beeld';
|
||||
@override String get notSupported => 'Dit apparaat ondersteunt geen beeld-in-beeld modus';
|
||||
@override String get failed => 'Beeld-in-beeld kon niet worden gestart';
|
||||
@override String unknown({required Object error}) => 'Er is een fout opgetreden: ${error}';
|
||||
}
|
||||
|
||||
// Path: libraries.tabs
|
||||
class _TranslationsLibrariesTabsNl implements TranslationsLibrariesTabsEn {
|
||||
_TranslationsLibrariesTabsNl._(this._root);
|
||||
@@ -1201,6 +1217,12 @@ extension on TranslationsNl {
|
||||
'videoControls.timelineSlider' => 'Videotijdlijn',
|
||||
'videoControls.volumeSlider' => 'Volumeniveau',
|
||||
'videoControls.backButton' => 'Terug',
|
||||
'videoControls.pipFailed' => 'Beeld-in-beeld kon niet worden gestart',
|
||||
'videoControls.pipErrors.androidVersion' => 'Vereist Android 8.0 of nieuwer',
|
||||
'videoControls.pipErrors.permissionDisabled' => 'Beeld-in-beeld toestemming is uitgeschakeld. Schakel deze in via Instellingen > Apps > Plezy > Beeld-in-beeld',
|
||||
'videoControls.pipErrors.notSupported' => 'Dit apparaat ondersteunt geen beeld-in-beeld modus',
|
||||
'videoControls.pipErrors.failed' => 'Beeld-in-beeld kon niet worden gestart',
|
||||
'videoControls.pipErrors.unknown' => ({required Object error}) => 'Er is een fout opgetreden: ${error}',
|
||||
'userStatus.admin' => 'Beheerder',
|
||||
'userStatus.restricted' => 'Beperkt',
|
||||
'userStatus.protected' => 'Beschermd',
|
||||
@@ -1444,14 +1466,14 @@ extension on TranslationsNl {
|
||||
'watchTogether.joining' => 'Deelnemen...',
|
||||
'watchTogether.controlMode' => 'Controlemodus',
|
||||
'watchTogether.controlModeQuestion' => 'Wie kan het afspelen bedienen?',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.hostOnly' => 'Alleen Host',
|
||||
'watchTogether.anyone' => 'Iedereen',
|
||||
'watchTogether.hostingSession' => 'Sessie Hosten',
|
||||
'watchTogether.inSession' => 'In Sessie',
|
||||
'watchTogether.sessionCode' => 'Sessiecode',
|
||||
'watchTogether.hostControlsPlayback' => 'Host bedient het afspelen',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.anyoneCanControl' => 'Iedereen kan het afspelen bedienen',
|
||||
'watchTogether.hostControls' => 'Host bedient',
|
||||
'watchTogether.anyoneControls' => 'Iedereen bedient',
|
||||
|
||||
@@ -442,6 +442,8 @@ class _TranslationsVideoControlsSv implements TranslationsVideoControlsEn {
|
||||
@override String get timelineSlider => 'Videotidslinje';
|
||||
@override String get volumeSlider => 'Volymnivå';
|
||||
@override String get backButton => 'Tillbaka';
|
||||
@override String get pipFailed => 'Bild-i-bild kunde inte starta';
|
||||
@override late final _TranslationsVideoControlsPipErrorsSv pipErrors = _TranslationsVideoControlsPipErrorsSv._(_root);
|
||||
}
|
||||
|
||||
// Path: userStatus
|
||||
@@ -902,6 +904,20 @@ class _TranslationsHotkeysActionsSv implements TranslationsHotkeysActionsEn {
|
||||
@override String get subSeekPrev => 'Hoppa till föregående undertext';
|
||||
}
|
||||
|
||||
// Path: videoControls.pipErrors
|
||||
class _TranslationsVideoControlsPipErrorsSv implements TranslationsVideoControlsPipErrorsEn {
|
||||
_TranslationsVideoControlsPipErrorsSv._(this._root);
|
||||
|
||||
final TranslationsSv _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get androidVersion => 'Kräver Android 8.0 eller nyare';
|
||||
@override String get permissionDisabled => 'Bild-i-bild-behörighet är inaktiverad. Aktivera den i Inställningar > Appar > Plezy > Bild-i-bild';
|
||||
@override String get notSupported => 'Denna enhet stöder inte bild-i-bild-läge';
|
||||
@override String get failed => 'Bild-i-bild kunde inte starta';
|
||||
@override String unknown({required Object error}) => 'Ett fel uppstod: ${error}';
|
||||
}
|
||||
|
||||
// Path: libraries.tabs
|
||||
class _TranslationsLibrariesTabsSv implements TranslationsLibrariesTabsEn {
|
||||
_TranslationsLibrariesTabsSv._(this._root);
|
||||
@@ -1201,6 +1217,12 @@ extension on TranslationsSv {
|
||||
'videoControls.timelineSlider' => 'Videotidslinje',
|
||||
'videoControls.volumeSlider' => 'Volymnivå',
|
||||
'videoControls.backButton' => 'Tillbaka',
|
||||
'videoControls.pipFailed' => 'Bild-i-bild kunde inte starta',
|
||||
'videoControls.pipErrors.androidVersion' => 'Kräver Android 8.0 eller nyare',
|
||||
'videoControls.pipErrors.permissionDisabled' => 'Bild-i-bild-behörighet är inaktiverad. Aktivera den i Inställningar > Appar > Plezy > Bild-i-bild',
|
||||
'videoControls.pipErrors.notSupported' => 'Denna enhet stöder inte bild-i-bild-läge',
|
||||
'videoControls.pipErrors.failed' => 'Bild-i-bild kunde inte starta',
|
||||
'videoControls.pipErrors.unknown' => ({required Object error}) => 'Ett fel uppstod: ${error}',
|
||||
'userStatus.admin' => 'Admin',
|
||||
'userStatus.restricted' => 'Begränsad',
|
||||
'userStatus.protected' => 'Skyddad',
|
||||
@@ -1444,14 +1466,14 @@ extension on TranslationsSv {
|
||||
'watchTogether.joining' => 'Ansluter...',
|
||||
'watchTogether.controlMode' => 'Kontrollläge',
|
||||
'watchTogether.controlModeQuestion' => 'Vem kan styra uppspelningen?',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.hostOnly' => 'Endast Värd',
|
||||
'watchTogether.anyone' => 'Alla',
|
||||
'watchTogether.hostingSession' => 'Värd för Session',
|
||||
'watchTogether.inSession' => 'I Session',
|
||||
'watchTogether.sessionCode' => 'Sessionskod',
|
||||
'watchTogether.hostControlsPlayback' => 'Värden styr uppspelningen',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.anyoneCanControl' => 'Alla kan styra uppspelningen',
|
||||
'watchTogether.hostControls' => 'Värd styr',
|
||||
'watchTogether.anyoneControls' => 'Alla styr',
|
||||
|
||||
@@ -442,6 +442,8 @@ class _TranslationsVideoControlsZh implements TranslationsVideoControlsEn {
|
||||
@override String get timelineSlider => '视频时间轴';
|
||||
@override String get volumeSlider => '音量调节';
|
||||
@override String get backButton => '返回';
|
||||
@override String get pipFailed => '画中画启动失败';
|
||||
@override late final _TranslationsVideoControlsPipErrorsZh pipErrors = _TranslationsVideoControlsPipErrorsZh._(_root);
|
||||
}
|
||||
|
||||
// Path: userStatus
|
||||
@@ -902,6 +904,20 @@ class _TranslationsHotkeysActionsZh implements TranslationsHotkeysActionsEn {
|
||||
@override String get subSeekPrev => '跳转到上一字幕';
|
||||
}
|
||||
|
||||
// Path: videoControls.pipErrors
|
||||
class _TranslationsVideoControlsPipErrorsZh implements TranslationsVideoControlsPipErrorsEn {
|
||||
_TranslationsVideoControlsPipErrorsZh._(this._root);
|
||||
|
||||
final TranslationsZh _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get androidVersion => '需要 Android 8.0 或更高版本';
|
||||
@override String get permissionDisabled => '画中画权限已禁用。请在设置 > 应用 > Plezy > 画中画中启用';
|
||||
@override String get notSupported => '此设备不支持画中画模式';
|
||||
@override String get failed => '画中画启动失败';
|
||||
@override String unknown({required Object error}) => '发生错误:${error}';
|
||||
}
|
||||
|
||||
// Path: libraries.tabs
|
||||
class _TranslationsLibrariesTabsZh implements TranslationsLibrariesTabsEn {
|
||||
_TranslationsLibrariesTabsZh._(this._root);
|
||||
@@ -1201,6 +1217,12 @@ extension on TranslationsZh {
|
||||
'videoControls.timelineSlider' => '视频时间轴',
|
||||
'videoControls.volumeSlider' => '音量调节',
|
||||
'videoControls.backButton' => '返回',
|
||||
'videoControls.pipFailed' => '画中画启动失败',
|
||||
'videoControls.pipErrors.androidVersion' => '需要 Android 8.0 或更高版本',
|
||||
'videoControls.pipErrors.permissionDisabled' => '画中画权限已禁用。请在设置 > 应用 > Plezy > 画中画中启用',
|
||||
'videoControls.pipErrors.notSupported' => '此设备不支持画中画模式',
|
||||
'videoControls.pipErrors.failed' => '画中画启动失败',
|
||||
'videoControls.pipErrors.unknown' => ({required Object error}) => '发生错误:${error}',
|
||||
'userStatus.admin' => '管理员',
|
||||
'userStatus.restricted' => '受限',
|
||||
'userStatus.protected' => '受保护',
|
||||
@@ -1444,14 +1466,14 @@ extension on TranslationsZh {
|
||||
'watchTogether.joining' => '加入中...',
|
||||
'watchTogether.controlMode' => '控制模式',
|
||||
'watchTogether.controlModeQuestion' => '谁可以控制播放?',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.hostOnly' => '仅主持人',
|
||||
'watchTogether.anyone' => '任何人',
|
||||
'watchTogether.hostingSession' => '主持会话',
|
||||
'watchTogether.inSession' => '在会话中',
|
||||
'watchTogether.sessionCode' => '会话代码',
|
||||
'watchTogether.hostControlsPlayback' => '主持人控制播放',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'watchTogether.anyoneCanControl' => '任何人都可以控制播放',
|
||||
'watchTogether.hostControls' => '主持人控制',
|
||||
'watchTogether.anyoneControls' => '任何人控制',
|
||||
|
||||
@@ -290,7 +290,15 @@
|
||||
"rotationLockButton": "Rotationslås",
|
||||
"timelineSlider": "Videotidslinje",
|
||||
"volumeSlider": "Volymnivå",
|
||||
"backButton": "Tillbaka"
|
||||
"backButton": "Tillbaka",
|
||||
"pipFailed": "Bild-i-bild kunde inte starta",
|
||||
"pipErrors": {
|
||||
"androidVersion": "Kräver Android 8.0 eller nyare",
|
||||
"permissionDisabled": "Bild-i-bild-behörighet är inaktiverad. Aktivera den i Inställningar > Appar > Plezy > Bild-i-bild",
|
||||
"notSupported": "Denna enhet stöder inte bild-i-bild-läge",
|
||||
"failed": "Bild-i-bild kunde inte starta",
|
||||
"unknown": "Ett fel uppstod: ${error}"
|
||||
}
|
||||
},
|
||||
"userStatus": {
|
||||
"admin": "Admin",
|
||||
|
||||
@@ -290,7 +290,15 @@
|
||||
"rotationLockButton": "旋转锁定",
|
||||
"timelineSlider": "视频时间轴",
|
||||
"volumeSlider": "音量调节",
|
||||
"backButton": "返回"
|
||||
"backButton": "返回",
|
||||
"pipFailed": "画中画启动失败",
|
||||
"pipErrors": {
|
||||
"androidVersion": "需要 Android 8.0 或更高版本",
|
||||
"permissionDisabled": "画中画权限已禁用。请在设置 > 应用 > Plezy > 画中画中启用",
|
||||
"notSupported": "此设备不支持画中画模式",
|
||||
"failed": "画中画启动失败",
|
||||
"unknown": "发生错误:${error}"
|
||||
}
|
||||
},
|
||||
"userStatus": {
|
||||
"admin": "管理员",
|
||||
|
||||
@@ -858,10 +858,11 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
);
|
||||
}
|
||||
|
||||
void _togglePIPMode() {
|
||||
setState(() {
|
||||
_videoPIPManager?.togglePIP();
|
||||
});
|
||||
Future<void> _togglePIPMode() async {
|
||||
final result = await _videoPIPManager?.togglePIP();
|
||||
if (result != null && !result.$1 && mounted) {
|
||||
showErrorSnackBar(context, result.$2 ?? t.videoControls.pipFailed);
|
||||
}
|
||||
}
|
||||
|
||||
/// Cycle through BoxFit modes: contain → cover → fill → contain (for button)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:plezy/i18n/strings.g.dart';
|
||||
|
||||
class PipService {
|
||||
static const MethodChannel _channel = MethodChannel('app.plezy/pip');
|
||||
@@ -29,7 +30,25 @@ class PipService {
|
||||
return await _channel.invokeMethod<bool>('isSupported') ?? false;
|
||||
}
|
||||
|
||||
static Future<void> enter({int? width, int? height}) async {
|
||||
await _channel.invokeMethod('enter', {'width': width, 'height': height});
|
||||
static Future<(bool success, String? error)> enter({int? width, int? height}) async {
|
||||
final result = await _channel.invokeMethod<Map>('enter', {'width': width, 'height': height});
|
||||
if (result == null) {
|
||||
return (false, t.videoControls.pipErrors.unknown(error: 'No response'));
|
||||
}
|
||||
final success = result['success'] as bool? ?? false;
|
||||
final errorCode = result['errorCode'] as String?;
|
||||
final errorMessage = result['errorMessage'] as String?;
|
||||
final error = errorCode != null ? _getLocalizedError(errorCode, errorMessage) : null;
|
||||
return (success, error);
|
||||
}
|
||||
|
||||
static String _getLocalizedError(String errorCode, String? errorMessage) {
|
||||
return switch (errorCode) {
|
||||
'android_version' => t.videoControls.pipErrors.androidVersion,
|
||||
'permission_disabled' => t.videoControls.pipErrors.permissionDisabled,
|
||||
'not_supported' => t.videoControls.pipErrors.notSupported,
|
||||
'failed' => t.videoControls.pipErrors.failed,
|
||||
_ => t.videoControls.pipErrors.unknown(error: errorMessage ?? 'Unknown error'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../mpv/mpv.dart';
|
||||
import '../services/pip_service.dart';
|
||||
@@ -16,9 +15,10 @@ class VideoPIPManager {
|
||||
ValueNotifier<bool> get isPipActive => PipService().isPipActive;
|
||||
|
||||
/// Toggle native PiP
|
||||
Future<void> togglePIP() async {
|
||||
/// Returns a tuple of (success, error message) for error handling
|
||||
Future<(bool success, String? error)> togglePIP() async {
|
||||
final supported = await PipService.isSupported();
|
||||
if (!supported) return;
|
||||
if (!supported) return (false, 'PiP not supported on this device');
|
||||
|
||||
// Try to get actual video dimensions from MPV
|
||||
int? width;
|
||||
@@ -39,6 +39,6 @@ class VideoPIPManager {
|
||||
width ??= _playerSize?.width.toInt();
|
||||
height ??= _playerSize?.height.toInt();
|
||||
|
||||
await PipService.enter(width: width, height: height);
|
||||
return await PipService.enter(width: width, height: height);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user