From 948f5a2a6d51bfc107f97008a80fb42c5864da01 Mon Sep 17 00:00:00 2001 From: Koen Date: Thu, 30 Nov 2023 09:56:40 +0100 Subject: [PATCH] Added FCast guide and other casting help options. --- app/src/main/AndroidManifest.xml | 4 + .../java/com/futo/platformplayer/UIDialogs.kt | 9 +- .../activities/FCastGuideActivity.kt | 108 ++++++++++++++++ .../dialogs/CastingAddDialog.kt | 7 + .../dialogs/CastingHelpDialog.kt | 63 +++++++++ app/src/main/res/drawable/ic_fcast.xml | 12 ++ .../main/res/layout/activity_fcast_guide.xml | 121 ++++++++++++++++++ .../main/res/layout/dialog_casting_add.xml | 30 ++++- .../main/res/layout/dialog_casting_help.xml | 68 ++++++++++ app/src/main/res/values/strings.xml | 10 ++ 10 files changed, 424 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/com/futo/platformplayer/activities/FCastGuideActivity.kt create mode 100644 app/src/main/java/com/futo/platformplayer/dialogs/CastingHelpDialog.kt create mode 100644 app/src/main/res/drawable/ic_fcast.xml create mode 100644 app/src/main/res/layout/activity_fcast_guide.xml create mode 100644 app/src/main/res/layout/dialog_casting_help.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a659758a..ba3fcc35 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -210,5 +210,9 @@ android:name=".activities.QRCaptureActivity" android:screenOrientation="portrait" android:theme="@style/Theme.FutoVideo.NoActionBar" /> + \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/UIDialogs.kt b/app/src/main/java/com/futo/platformplayer/UIDialogs.kt index 556b7fb5..f9dd9185 100644 --- a/app/src/main/java/com/futo/platformplayer/UIDialogs.kt +++ b/app/src/main/java/com/futo/platformplayer/UIDialogs.kt @@ -5,7 +5,6 @@ import android.content.Context import android.content.Intent import android.graphics.Color import android.net.Uri -import android.util.Log import android.util.TypedValue import android.view.Gravity import android.view.LayoutInflater @@ -18,7 +17,6 @@ import com.futo.platformplayer.casting.StateCasting import com.futo.platformplayer.dialogs.* import com.futo.platformplayer.engine.exceptions.PluginException import com.futo.platformplayer.logging.Logger -import com.futo.platformplayer.states.StateAnnouncement import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StateBackup import com.futo.platformplayer.stores.v2.ManagedStore @@ -344,6 +342,13 @@ class UIDialogs { } } + fun showCastingTutorialDialog(context: Context) { + val dialog = CastingHelpDialog(context); + registerDialogOpened(dialog); + dialog.setOnDismissListener { registerDialogClosed(dialog) }; + dialog.show(); + } + fun showCastingAddDialog(context: Context) { val dialog = CastingAddDialog(context); registerDialogOpened(dialog); diff --git a/app/src/main/java/com/futo/platformplayer/activities/FCastGuideActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/FCastGuideActivity.kt new file mode 100644 index 00000000..691bbb77 --- /dev/null +++ b/app/src/main/java/com/futo/platformplayer/activities/FCastGuideActivity.kt @@ -0,0 +1,108 @@ +package com.futo.platformplayer.activities + +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.text.Html +import android.widget.ImageButton +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import com.futo.platformplayer.R +import com.futo.platformplayer.UIDialogs +import com.futo.platformplayer.dialogs.CastingHelpDialog +import com.futo.platformplayer.logging.Logger +import com.futo.platformplayer.setNavigationBarColorAndIcons +import com.futo.platformplayer.states.StateApp +import com.futo.platformplayer.views.buttons.BigButton + +class FCastGuideActivity : AppCompatActivity() { + override fun attachBaseContext(newBase: Context?) { + super.attachBaseContext(StateApp.instance.getLocaleContext(newBase)) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_fcast_guide); + setNavigationBarColorAndIcons(); + + findViewById(R.id.text_explanation).apply { + val guideText = """ +

1. Install FCast Receiver:

+

- Open Play Store, FireStore, or FCast website on your TV/desktop.
+ - Search for "FCast Receiver", install and open it.

+
+ +

2. Prepare the Grayjay App:

+

- Ensure it's connected to the same network as the FCast Receiver.

+
+ +

3. Initiate Casting from Grayjay:

+

- Click the cast button in Grayjay.

+
+ +

4. Connect to FCast Receiver:

+

- Wait for your device to show in the list or add it manually with its IP address.

+
+ +

5. Confirm Connection:

+

- Click "OK" to confirm your device selection.

+
+ +

6. Start Casting:

+

- Press "start" next to the device you've added.

+
+ +

7. Play Your Video:

+

- Start any video in Grayjay to cast.

+
+ +

Finding Your IP Address:

+

On FCast Receiver (Android): Displayed on the main screen.
+ On Windows: Use 'ipconfig' in Command Prompt.
+ On Linux: Use 'hostname -I' or 'ip addr' in Terminal.
+ On MacOS: System Preferences > Network.

+ """.trimIndent() + + text = Html.fromHtml(guideText, Html.FROM_HTML_MODE_COMPACT) + } + + findViewById(R.id.button_back).setOnClickListener { + UIDialogs.showCastingTutorialDialog(this) + finish() + } + + findViewById(R.id.button_close).onClick.subscribe { + UIDialogs.showCastingTutorialDialog(this) + finish() + } + + findViewById(R.id.button_website).onClick.subscribe { + try { + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://fcast.org/")) + startActivity(browserIntent); + } catch (e: Throwable) { + Logger.i(TAG, "Failed to open browser.", e) + } + } + + findViewById(R.id.button_technical).onClick.subscribe { + try { + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://gitlab.com/futo-org/fcast/-/wikis/Protocol-version-1")) + startActivity(browserIntent); + } catch (e: Throwable) { + Logger.i(TAG, "Failed to open browser.", e) + } + } + } + + override fun onBackPressed() { + UIDialogs.showCastingTutorialDialog(this) + finish() + } + + companion object { + private const val TAG = "FCastGuideActivity"; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/dialogs/CastingAddDialog.kt b/app/src/main/java/com/futo/platformplayer/dialogs/CastingAddDialog.kt index 8abe1ce4..295e191a 100644 --- a/app/src/main/java/com/futo/platformplayer/dialogs/CastingAddDialog.kt +++ b/app/src/main/java/com/futo/platformplayer/dialogs/CastingAddDialog.kt @@ -23,6 +23,7 @@ class CastingAddDialog(context: Context?) : AlertDialog(context) { private lateinit var _textError: TextView; private lateinit var _buttonCancel: Button; private lateinit var _buttonConfirm: LinearLayout; + private lateinit var _buttonTutorial: TextView; override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState); @@ -35,6 +36,7 @@ class CastingAddDialog(context: Context?) : AlertDialog(context) { _textError = findViewById(R.id.text_error); _buttonCancel = findViewById(R.id.button_cancel); _buttonConfirm = findViewById(R.id.button_confirm); + _buttonTutorial = findViewById(R.id.button_tutorial) ArrayAdapter.createFromResource(context, R.array.casting_device_type_array, R.layout.spinner_item_simple).also { adapter -> adapter.setDropDownViewResource(R.layout.spinner_dropdownitem_simple); @@ -102,6 +104,11 @@ class CastingAddDialog(context: Context?) : AlertDialog(context) { StateCasting.instance.addRememberedDevice(castingDeviceInfo); performDismiss(); }; + + _buttonTutorial.setOnClickListener { + UIDialogs.showCastingTutorialDialog(context) + dismiss() + } } override fun show() { diff --git a/app/src/main/java/com/futo/platformplayer/dialogs/CastingHelpDialog.kt b/app/src/main/java/com/futo/platformplayer/dialogs/CastingHelpDialog.kt new file mode 100644 index 00000000..9f305b18 --- /dev/null +++ b/app/src/main/java/com/futo/platformplayer/dialogs/CastingHelpDialog.kt @@ -0,0 +1,63 @@ +package com.futo.platformplayer.dialogs + +import android.app.AlertDialog +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.view.LayoutInflater +import com.futo.platformplayer.R +import com.futo.platformplayer.UIDialogs +import com.futo.platformplayer.activities.FCastGuideActivity +import com.futo.platformplayer.activities.PolycentricWhyActivity +import com.futo.platformplayer.logging.Logger +import com.futo.platformplayer.views.buttons.BigButton + + +class CastingHelpDialog(context: Context?) : AlertDialog(context) { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState); + setContentView(LayoutInflater.from(context).inflate(R.layout.dialog_casting_help, null)); + + findViewById(R.id.button_guide).onClick.subscribe { + context.startActivity(Intent(context, FCastGuideActivity::class.java)) + } + + findViewById(R.id.button_video).onClick.subscribe { + try { + //TODO: Replace the URL with the casting video URL + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://fcast.org/")) + context.startActivity(browserIntent); + } catch (e: Throwable) { + Logger.i(TAG, "Failed to open browser.", e) + } + } + + findViewById(R.id.button_website).onClick.subscribe { + try { + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://fcast.org/")) + context.startActivity(browserIntent); + } catch (e: Throwable) { + Logger.i(TAG, "Failed to open browser.", e) + } + } + + findViewById(R.id.button_technical).onClick.subscribe { + try { + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://gitlab.com/futo-org/fcast/-/wikis/Protocol-version-1")) + context.startActivity(browserIntent); + } catch (e: Throwable) { + Logger.i(TAG, "Failed to open browser.", e) + } + } + + findViewById(R.id.button_close).onClick.subscribe { + dismiss() + UIDialogs.showCastingAddDialog(context) + } + } + + companion object { + private val TAG = "CastingTutorialDialog"; + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_fcast.xml b/app/src/main/res/drawable/ic_fcast.xml new file mode 100644 index 00000000..22ac06f5 --- /dev/null +++ b/app/src/main/res/drawable/ic_fcast.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/layout/activity_fcast_guide.xml b/app/src/main/res/layout/activity_fcast_guide.xml new file mode 100644 index 00000000..4d6a2b89 --- /dev/null +++ b/app/src/main/res/layout/activity_fcast_guide.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_casting_add.xml b/app/src/main/res/layout/dialog_casting_add.xml index b94b44db..a24ac948 100644 --- a/app/src/main/res/layout/dialog_casting_add.xml +++ b/app/src/main/res/layout/dialog_casting_add.xml @@ -8,13 +8,31 @@ android:background="@color/gray_1d" android:padding="20dp"> - + android:orientation="horizontal"> + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5af4d54d..2dd01402 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -688,6 +688,16 @@ Failed to show settings Play store version does not support default URL handling. These are all {commentCount} comments you have made in Grayjay. + Tutorial + Go back to casting add dialog + View a video about how to cast + View the FCast technical documentation + Guide + How to use FCast guide + FCast + Open the FCast website + FCast Website + FCast Technical Documentation Recommendations Subscriptions