diff --git a/app/build.gradle b/app/build.gradle index 6a95bd3..91e8b99 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "oppen.tva" minSdkVersion 21 targetSdkVersion 30 - versionCode 5 - versionName "0.2.0 Beta" + versionCode 6 + versionName "0.3.0 Beta" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/release/app-release.apk b/app/release/app-release.apk deleted file mode 100644 index a038eea..0000000 Binary files a/app/release/app-release.apk and /dev/null differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index e0d4987..48ddc51 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "properties": [], - "versionCode": 5, - "versionName": "0.2.0 Beta", + "versionCode": 6, + "versionName": "0.3.0 Beta", "enabled": true, "outputFile": "app-release.apk" } diff --git a/app/src/main/java/oppen/tva/Tva.kt b/app/src/main/java/oppen/tva/Tva.kt index 8e54276..68e5c0d 100644 --- a/app/src/main/java/oppen/tva/Tva.kt +++ b/app/src/main/java/oppen/tva/Tva.kt @@ -6,6 +6,6 @@ class Tva: Application() { companion object{ const val DEFAULT_HOME_CAPSULE = "gemini://gemini.circumlunar.space/~oppen/tva/index.gmi" - const val GEMINI_USER_SEARCH_BASE = "gemini://gus.guru/search/2?" + const val GEMINI_USER_SEARCH_BASE = "gemini://gus.guru/search?" } } \ No newline at end of file diff --git a/app/src/main/java/oppen/tva/ui/AudioPlayer.kt b/app/src/main/java/oppen/tva/ui/AudioPlayer.kt new file mode 100644 index 0000000..b629557 --- /dev/null +++ b/app/src/main/java/oppen/tva/ui/AudioPlayer.kt @@ -0,0 +1,66 @@ +package oppen.tva.ui + +import android.content.Context +import android.media.MediaMetadataRetriever +import android.media.MediaPlayer +import oppen.tva.R +import oppen.tva.databinding.ActivityTvaBinding +import oppen.tva.io.TvaState +import oppen.visible + +object AudioPlayer { + + fun play(context: Context, binding: ActivityTvaBinding, mediaPlayer: MediaPlayer, state: TvaState.ResponseAudio){ + val metadataRetriever = MediaMetadataRetriever() + metadataRetriever.setDataSource(context, state.cacheUri) + + val artist = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST) + val trackName = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) + + binding.audioTitle.text = "$trackName - $artist" + + mediaPlayer.setDataSource(context, state.cacheUri) + mediaPlayer.prepare() + + binding.audioPlayButton.setImageResource(R.drawable.vector_pause) + + mediaPlayer.setOnCompletionListener { player -> + binding.audioPlayButton.setImageResource(R.drawable.vector_play) + } + + binding.audioPlayButton.setOnClickListener { + if(mediaPlayer.isPlaying){ + binding.audioPlayButton.setImageResource(R.drawable.vector_play) + mediaPlayer.pause() + }else{ + binding.audioPlayButton.setImageResource(R.drawable.vector_pause) + mediaPlayer.start() + } + } + + mediaPlayer.setOnInfoListener { _, what, extra -> + when(what){ + MediaPlayer.MEDIA_INFO_UNKNOWN -> println("MEDIA_INFO_UNKNOWN") + MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING-> println("MEDIA_INFO_VIDEO_TRACK_LAGGING") + MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START-> println("MEDIA_INFO_VIDEO_RENDERING_START") + MediaPlayer.MEDIA_INFO_BUFFERING_START-> println("MEDIA_INFO_BUFFERING_START") + MediaPlayer.MEDIA_INFO_BUFFERING_END-> println("MEDIA_INFO_BUFFERING_END") + MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING-> println("MEDIA_INFO_BAD_INTERLEAVING") + MediaPlayer.MEDIA_INFO_NOT_SEEKABLE-> println("MEDIA_INFO_NOT_SEEKABLE") + MediaPlayer.MEDIA_INFO_METADATA_UPDATE-> println("MEDIA_INFO_METADATA_UPDATE") + MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE-> println("MEDIA_INFO_UNSUPPORTED_SUBTITLE") + MediaPlayer.MEDIA_INFO_SUBTITLE_TIMED_OUT-> println("MEDIA_INFO_SUBTITLE_TIMED_OUT") + } + + true + } + + mediaPlayer.setOnErrorListener{ _, i: Int, i1: Int -> + println("Error Listener.... $i, $i1") + true + } + + binding.audioPlayer.visible(true) + mediaPlayer.start() + } +} \ No newline at end of file diff --git a/app/src/main/java/oppen/tva/ui/TvaActivity.kt b/app/src/main/java/oppen/tva/ui/TvaActivity.kt index 1300358..832782f 100644 --- a/app/src/main/java/oppen/tva/ui/TvaActivity.kt +++ b/app/src/main/java/oppen/tva/ui/TvaActivity.kt @@ -4,12 +4,17 @@ import android.content.ClipData import android.content.ClipboardManager import android.content.Context import android.content.Intent +import android.media.MediaMetadataRetriever +import android.media.MediaPlayer import android.net.Uri import android.os.Bundle +import android.text.SpannableString +import android.text.style.ForegroundColorSpan import android.view.inputmethod.EditorInfo import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import androidx.core.text.set import androidx.databinding.DataBindingUtil import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar @@ -32,8 +37,8 @@ import oppen.tva.ui.modals_menus.overflow.OverflowPopup import oppen.tva.ui.modals_menus.set_home.SetHomeDialog import oppen.tva.ui.modals_menus.tabs.NewTabPopup import oppen.tva.ui.modals_menus.tabs.TabsDialog +import oppen.visible import oppen.visibleRetainingSpace -import java.io.ByteArrayOutputStream import java.io.File import java.io.FileInputStream import java.io.FileOutputStream @@ -46,6 +51,8 @@ class TvaActivity : AppCompatActivity() { private var inSearch = false + private val mediaPlayer = MediaPlayer() + private val model by viewModels() private lateinit var binding: ActivityTvaBinding private lateinit var history: HistoryInterface @@ -204,7 +211,9 @@ class TvaActivity : AppCompatActivity() { private fun renderGemtext(state: TvaState.ResponseGemtext) = runOnUiThread { loadingView(false) - binding.addressEdit.setText(state.uri.toString()) + val addressSpan = SpannableString(state.uri.toString()) + addressSpan.set(0, 9, ForegroundColorSpan(resources.getColor(R.color.protocol_address))) + binding.addressEdit.setText(addressSpan) adapter.render(state.lines) history.add(state.uri.toString()) @@ -218,7 +227,8 @@ class TvaActivity : AppCompatActivity() { var imageState: TvaState.ResponseImage? = null private fun renderAudio(state: TvaState.ResponseAudio) = runOnUiThread { - //todo - display audio player + loadingView(false) + AudioPlayer.play(this, binding, mediaPlayer, state) } private fun renderImage(state: TvaState.ResponseImage) = runOnUiThread{ diff --git a/app/src/main/java/oppen/tva/ui/modals_menus/input/InputDialog.kt b/app/src/main/java/oppen/tva/ui/modals_menus/input/InputDialog.kt index cd0b1b0..1be2b2d 100644 --- a/app/src/main/java/oppen/tva/ui/modals_menus/input/InputDialog.kt +++ b/app/src/main/java/oppen/tva/ui/modals_menus/input/InputDialog.kt @@ -6,6 +6,7 @@ import androidx.appcompat.app.AppCompatDialog import kotlinx.android.synthetic.main.dialog_input_query.view.* import oppen.tva.R import oppen.tva.io.TvaState +import java.net.URLEncoder object InputDialog { @@ -22,7 +23,8 @@ object InputDialog { view.query_text.text = state.header.meta view.query_submit_button.setOnClickListener { - onQuery("${state.uri}?${view.query_input.text.toString()}") + val encoded = URLEncoder.encode(view.query_input.text.toString(), "UTF-8") + onQuery("${state.uri}?$encoded") dialog.dismiss() } diff --git a/app/src/main/res/drawable/drawable_filled_rounded_rect.xml b/app/src/main/res/drawable/drawable_filled_rounded_rect.xml new file mode 100644 index 0000000..89a739d --- /dev/null +++ b/app/src/main/res/drawable/drawable_filled_rounded_rect.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/drawable_rounded_rect.xml b/app/src/main/res/drawable/drawable_rounded_rect.xml deleted file mode 100644 index f303ff7..0000000 --- a/app/src/main/res/drawable/drawable_rounded_rect.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/drawable_stroke_rounded_rect.xml b/app/src/main/res/drawable/drawable_stroke_rounded_rect.xml new file mode 100644 index 0000000..b4a4e62 --- /dev/null +++ b/app/src/main/res/drawable/drawable_stroke_rounded_rect.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/vector_pause.xml b/app/src/main/res/drawable/vector_pause.xml new file mode 100644 index 0000000..13d6d2e --- /dev/null +++ b/app/src/main/res/drawable/vector_pause.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/vector_play.xml b/app/src/main/res/drawable/vector_play.xml new file mode 100644 index 0000000..13c137a --- /dev/null +++ b/app/src/main/res/drawable/vector_play.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/vector_save.xml b/app/src/main/res/drawable/vector_save.xml new file mode 100644 index 0000000..5c30d1c --- /dev/null +++ b/app/src/main/res/drawable/vector_save.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_tva.xml b/app/src/main/res/layout/activity_tva.xml index c5a4020..97715ed 100644 --- a/app/src/main/res/layout/activity_tva.xml +++ b/app/src/main/res/layout/activity_tva.xml @@ -15,6 +15,7 @@ android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="@color/colorPrimaryDark" android:fitsSystemWindows="true"> - + + + android:hint="@string/main_input_hint" /> + android:text="1" /> + + + + + + + + + + + diff --git a/app/src/main/res/layout/grid_cell_tab.xml b/app/src/main/res/layout/grid_cell_tab.xml index 2af76c0..ff7e08d 100644 --- a/app/src/main/res/layout/grid_cell_tab.xml +++ b/app/src/main/res/layout/grid_cell_tab.xml @@ -6,7 +6,7 @@ android:layout_width="match_parent" android:layout_height="150dp" android:layout_margin="@dimen/button_margin" - android:background="@drawable/drawable_rounded_rect" + android:background="@drawable/drawable_stroke_rounded_rect" android:padding="@dimen/default_margin" android:clickable="true" android:focusable="true" diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index a49a04c..c82fd6f 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -1,7 +1,10 @@ #ffffff - #B8B8B8 + #1d1d1d #03DAC5 #000000 + #1d1d1d + #ffdede + #2e2e2e \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index d5a0088..b1e5362 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,7 +1,10 @@ #ffffff - #1d1d1d + #efefef #03DAC5 #efefef + #efefef + #002121 + #dfdfdf \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 01bfd74..83a96f1 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -8,4 +8,6 @@ 28sp 22sp 18sp + 32dp + 50dp \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index ef394a4..66e6180 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -4,7 +4,7 @@ @color/colorPrimaryDark @color/colorAccent false - #1d1d1d + @color/colorPrimaryDark false true