diff --git a/README.md b/README.md index 2919a9f..450d6f1 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Buran is a simple Gemini protocol browser for Android. - [ ] Keystore generator and catalog - [ ] Option to require password or biometric authentication - [ ] Color palette interface for picking background and accent colors -- [X] Option to render links as buttons +- [ ] Option to render links as buttons - [X] Inline rendering of images - [ ] Page navigation feature - [ ] Update notifier diff --git a/app/src/main/java/corewala/buran/ui/GemActivity.kt b/app/src/main/java/corewala/buran/ui/GemActivity.kt index 1ee8be6..cad302d 100644 --- a/app/src/main/java/corewala/buran/ui/GemActivity.kt +++ b/app/src/main/java/corewala/buran/ui/GemActivity.kt @@ -274,19 +274,18 @@ class GemActivity : AppCompatActivity() { else -> hideClientCertShield() } + val hideCodeBlocks = prefs.getBoolean( + "collapse_code_blocks", + false + ) + adapter.hideCodeBlocks(hideCodeBlocks) + val showInlineIcons = prefs.getBoolean( "show_inline_icons", true ) adapter.inlineIcons(showInlineIcons) - - val showLinkButtons = prefs.getBoolean( - "show_link_buttons", - true - ) - adapter.linkButtons(showLinkButtons) - val showInlineImages = prefs.getBoolean( "show_inline_images", true diff --git a/app/src/main/java/corewala/buran/ui/gemtext_adapter/AbstractGemtextAdapter.kt b/app/src/main/java/corewala/buran/ui/gemtext_adapter/AbstractGemtextAdapter.kt index b099678..c2de203 100644 --- a/app/src/main/java/corewala/buran/ui/gemtext_adapter/AbstractGemtextAdapter.kt +++ b/app/src/main/java/corewala/buran/ui/gemtext_adapter/AbstractGemtextAdapter.kt @@ -10,14 +10,14 @@ abstract class AbstractGemtextAdapter( ): RecyclerView.Adapter() { var showInlineIcons: Boolean = false - var showLinkButtons: Boolean = false + var hideCodeBlocks: Boolean = false var showInlineImages: Boolean = false abstract fun render(lines: List) abstract fun loadImage(position: Int, cacheUri: Uri) abstract fun inlineIcons(visible: Boolean) abstract fun inlineImages(visible: Boolean) - abstract fun linkButtons(visible: Boolean) + abstract fun hideCodeBlocks(hideCodeBlocks: Boolean) abstract fun inferTitle(): String? diff --git a/app/src/main/java/corewala/buran/ui/gemtext_adapter/GemtextAdapter.kt b/app/src/main/java/corewala/buran/ui/gemtext_adapter/GemtextAdapter.kt index a7cab5b..e7bef51 100644 --- a/app/src/main/java/corewala/buran/ui/gemtext_adapter/GemtextAdapter.kt +++ b/app/src/main/java/corewala/buran/ui/gemtext_adapter/GemtextAdapter.kt @@ -8,13 +8,11 @@ import android.view.ViewGroup import androidx.core.view.isVisible import kotlinx.android.synthetic.main.gemtext_code_block.view.* import kotlinx.android.synthetic.main.gemtext_image_link.view.* +import kotlinx.android.synthetic.main.gemtext_link.view.gemtext_text_link import kotlinx.android.synthetic.main.gemtext_text.view.* import corewala.buran.R import corewala.endsWithImage import corewala.visible -import kotlinx.android.synthetic.main.gemtext_image_link.view.gemtext_link_button -import kotlinx.android.synthetic.main.gemtext_link.view.* -import kotlinx.android.synthetic.main.gemtext_link.view.gemtext_text_link import java.net.URI class GemtextAdapter( @@ -95,6 +93,27 @@ class GemtextAdapter( }else{ holder.itemView.gemtext_text_monospace_textview.text = line.substring(3) } + + if(hideCodeBlocks){ + holder.itemView.show_code_block.setText(R.string.show_code)//reset for recycling + altText?.let{ + holder.itemView.show_code_block.append(": $altText") + } + holder.itemView.show_code_block.visible(true) + holder.itemView.show_code_block.paint.isUnderlineText = true + holder.itemView.show_code_block.setOnClickListener { + setupCodeBlockToggle(holder, altText) + } + holder.itemView.gemtext_text_monospace_textview.visible(false) + + when { + showInlineIcons -> holder.itemView.show_code_block.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.vector_code, 0) + else -> holder.itemView.show_code_block.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) + } + }else{ + holder.itemView.show_code_block.visible(false) + holder.itemView.gemtext_text_monospace_textview.visible(true) + } } is GmiViewHolder.Quote -> holder.itemView.gemtext_text_monospace_textview.text = line.substring(1).trim() is GmiViewHolder.H1 -> { @@ -123,35 +142,19 @@ class GemtextAdapter( if(linkParts.size > 1) linkName = linkParts[1] val displayText = linkName + holder.itemView.gemtext_text_link.text = displayText + holder.itemView.gemtext_text_link.paint.isUnderlineText = true when { - showLinkButtons -> { - holder.itemView.gemtext_text_link.visible(false) - holder.itemView.gemtext_link_button.visible(true) - holder.itemView.gemtext_link_button.text = displayText - } else -> { - holder.itemView.gemtext_link_button.visible(false) - holder.itemView.gemtext_text_link.visible(true) - holder.itemView.gemtext_text_link.text = displayText - holder.itemView.gemtext_text_link.paint.isUnderlineText = true - } - } - - when { - showInlineIcons && linkParts.first().startsWith("http") -> { - holder.itemView.gemtext_text_link.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.vector_open_browser, 0) - holder.itemView.gemtext_link_button.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.vector_open_browser, 0) - } - else -> { - holder.itemView.gemtext_text_link.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) - holder.itemView.gemtext_link_button.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) - } + showInlineIcons && linkParts.first().startsWith("http") -> holder.itemView.gemtext_text_link.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.vector_open_browser, 0) + else -> holder.itemView.gemtext_text_link.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0) } holder.itemView.gemtext_text_link.setOnClickListener { val uri = getUri(lines[holder.adapterPosition]) println("User clicked link: $uri") onLink(uri, false, holder.adapterPosition) + } holder.itemView.gemtext_text_link.setOnLongClickListener { val uri = getUri(lines[holder.adapterPosition]) @@ -159,17 +162,6 @@ class GemtextAdapter( onLink(uri, true, holder.adapterPosition) true } - holder.itemView.gemtext_link_button.setOnClickListener { - val uri = getUri(lines[holder.adapterPosition]) - println("User clicked link: $uri") - onLink(uri, false, holder.adapterPosition) - } - holder.itemView.gemtext_link_button.setOnLongClickListener { - val uri = getUri(lines[holder.adapterPosition]) - println("User long-clicked link: $uri") - onLink(uri, true, holder.adapterPosition) - true - } } is GmiViewHolder.ImageLink -> { @@ -179,20 +171,8 @@ class GemtextAdapter( if(linkParts.size > 1) linkName = linkParts[1] val displayText = linkName - - when { - showLinkButtons -> { - holder.itemView.gemtext_text_link.visible(false) - holder.itemView.gemtext_link_button.visible(true) - holder.itemView.gemtext_link_button.text = displayText - } else -> { - holder.itemView.gemtext_link_button.visible(false) - holder.itemView.gemtext_text_link.visible(true) - holder.itemView.gemtext_text_link.text = displayText - holder.itemView.gemtext_text_link.paint.isUnderlineText = true - } - } - + holder.itemView.gemtext_text_link.text = displayText + holder.itemView.gemtext_text_link.paint.isUnderlineText = true holder.itemView.gemtext_text_link.setOnClickListener { val uri = getUri(lines[holder.adapterPosition]) println("User clicked link: $uri") @@ -204,17 +184,6 @@ class GemtextAdapter( onLink(uri, true, holder.adapterPosition) true } - holder.itemView.gemtext_link_button.setOnClickListener { - val uri = getUri(lines[holder.adapterPosition]) - println("User clicked link: $uri") - onLink(uri, false, holder.adapterPosition) - } - holder.itemView.gemtext_link_button.setOnLongClickListener { - val uri = getUri(lines[holder.adapterPosition]) - println("User long-clicked link: $uri") - onLink(uri, true, holder.adapterPosition) - true - } holder.itemView.gemtext_inline_image.setOnClickListener { val uri = getUri(lines[holder.adapterPosition]) println("User clicked image: $uri") @@ -246,14 +215,28 @@ class GemtextAdapter( } when { - showInlineIcons -> { - holder.itemView.gemtext_text_link.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.vector_photo, 0) - holder.itemView.gemtext_link_button.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.vector_photo, 0) - } - else -> { - holder.itemView.gemtext_text_link.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) - holder.itemView.gemtext_link_button.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) - } + showInlineIcons -> holder.itemView.gemtext_text_link.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.vector_photo, 0) + else -> holder.itemView.gemtext_text_link.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) + } + } + } + } + + private fun setupCodeBlockToggle(holder: GmiViewHolder.Code, altText: String?) { + //val adapterPosition = holder.adapterPosition + when { + holder.itemView.gemtext_text_monospace_textview.isVisible -> { + holder.itemView.show_code_block.setText(R.string.show_code) + holder.itemView.gemtext_text_monospace_textview.visible(false) + altText?.let{ + holder.itemView.show_code_block.append(": $altText") + } + } + else -> { + holder.itemView.show_code_block.setText(R.string.hide_code) + holder.itemView.gemtext_text_monospace_textview.visible(true) + altText?.let{ + holder.itemView.show_code_block.append(": $altText") } } } @@ -287,13 +270,13 @@ class GemtextAdapter( notifyDataSetChanged() } - override fun linkButtons(visible: Boolean){ - this.showLinkButtons = visible - notifyDataSetChanged() - } - override fun inlineImages(visible: Boolean){ this.showInlineImages = visible notifyDataSetChanged() } + + override fun hideCodeBlocks(hideCodeBlocks: Boolean) { + this.hideCodeBlocks = hideCodeBlocks + notifyDataSetChanged() + } } \ No newline at end of file diff --git a/app/src/main/java/corewala/buran/ui/settings/SettingsFragment.kt b/app/src/main/java/corewala/buran/ui/settings/SettingsFragment.kt index e4e6a57..6341479 100644 --- a/app/src/main/java/corewala/buran/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/corewala/buran/ui/settings/SettingsFragment.kt @@ -179,19 +179,24 @@ class SettingsFragment: PreferenceFragmentCompat(), Preference.OnPreferenceChang accessibilityCategory.title = getString(R.string.accessibility) screen.addPreference(accessibilityCategory) + //Accessibility - code blocks + val aboutCodeBlocksPref = Preference(context) + aboutCodeBlocksPref.summary = getString(R.string.collapse_code_blocks_about) + aboutCodeBlocksPref.isPersistent = false + aboutCodeBlocksPref.isSelectable = false + accessibilityCategory.addPreference(aboutCodeBlocksPref) + + val collapseCodeBlocksPreference = SwitchPreferenceCompat(context) + collapseCodeBlocksPreference.key = "collapse_code_blocks" + collapseCodeBlocksPreference.title = getString(R.string.collapse_code_blocks) + accessibilityCategory.addPreference(collapseCodeBlocksPreference) + //Accessibility - inline icons val showInlineIconsPreference = SwitchPreferenceCompat(context) showInlineIconsPreference.setDefaultValue(true) showInlineIconsPreference.key = "show_inline_icons" showInlineIconsPreference.title = getString(R.string.show_inline_icons) accessibilityCategory.addPreference(showInlineIconsPreference) - - //Accessibility - full-width buttons - val showLinkButtonsPreference = SwitchPreferenceCompat(context) - showLinkButtonsPreference.setDefaultValue(false) - showLinkButtonsPreference.key = "show_link_buttons" - showLinkButtonsPreference.title = getString(R.string.show_link_buttons) - accessibilityCategory.addPreference(showLinkButtonsPreference) } private fun buildClientCertificateSection(context: Context?, appCategory: PreferenceCategory) { diff --git a/app/src/main/res/layout/gemtext_code_block.xml b/app/src/main/res/layout/gemtext_code_block.xml index 187b46d..6897f61 100644 --- a/app/src/main/res/layout/gemtext_code_block.xml +++ b/app/src/main/res/layout/gemtext_code_block.xml @@ -9,12 +9,27 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> + + + android:layout_marginBottom="@dimen/def_quarter" + android:layout_below="@id/show_code_block"> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/gemtext_image_link.xml b/app/src/main/res/layout/gemtext_image_link.xml index 207e374..9b005f3 100644 --- a/app/src/main/res/layout/gemtext_image_link.xml +++ b/app/src/main/res/layout/gemtext_image_link.xml @@ -1,24 +1,24 @@ + android:layout_width="wrap_content" + android:layout_height="wrap_content" + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto"> - + - - \ No newline at end of file diff --git a/app/src/main/res/layout/gemtext_link.xml b/app/src/main/res/layout/gemtext_link.xml index 775941c..ae90351 100644 --- a/app/src/main/res/layout/gemtext_link.xml +++ b/app/src/main/res/layout/gemtext_link.xml @@ -1,45 +1,23 @@ - + - - + android:id="@+id/gemtext_text_link" + android:textColor="@color/stroke" + android:layout_marginLeft="@dimen/screen_margin" + android:layout_marginRight="@dimen/screen_margin" + android:layout_marginTop="@dimen/default_margin_small" + android:layout_marginBottom="@dimen/default_margin_small" + android:textSize="@dimen/default_text_size" + android:clickable="true" + android:focusable="true" + android:background="?android:attr/selectableItemBackground" + android:drawablePadding="4dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> \ No newline at end of file diff --git a/app/src/main/res/layout/gemtext_link_button.xml b/app/src/main/res/layout/gemtext_link_button.xml new file mode 100644 index 0000000..9a37798 --- /dev/null +++ b/app/src/main/res/layout/gemtext_link_button.xml @@ -0,0 +1,29 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 11ebf42..4b1bc40 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -68,11 +68,14 @@ Historique vidé Cache d\'exécution vidé Icônes de lien en ligne - Afficher boutons de liens Vous n\'avez encore aucun marque-pages Importer des marque-pages Exporter des marque-pages Accessibilité + Cacher les rectangles pleins + Montrer le code + Cacher le code + Les capsules Gemini utilisent malheureusement souvent des en-têtes en ascii-art rendus avec des rectangles pleins à largeur fixe. Quand les rectangles pleins sont cachés, ils nécessitent un clic pour être affichés, ce qui améliore l\'ergonomie en cas d\'utilisation d\'un lecteur d\'écran. Utiliser une couleur d\'arrière-plan personnalisée Couleur d\'arrière-plan Couleur d\'arrière-plan diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ba5c61e..dc8de4f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -68,11 +68,14 @@ History cleared Runtime cache cleared Inline link icons - Show link buttons You don\'t have any bookmarks yet Import bookmarks Export bookmarks Accessibility + Hide code blocks + Show code + Hide code + Gemini capsules unfortunately often use ascii-art headers rendered in monospaced code blocks. When code blocks are hidden they require a tap to expand which improves usability when using a screen reader. Use custom page background colour Page Background Colour Page Background Colour