Commit 1a4346c2 authored by Christophe Henry's avatar Christophe Henry

Solves #39: better accessibility for the article-related actions

parent 966c53f5
......@@ -3,6 +3,7 @@
## Features
* Implements [#54](https://git.feneas.org/christophehenry/freshrss-android/issues/54): Add fast scroller bar with section display ([!17](https://git.feneas.org/christophehenry/freshrss-android/merge_requests/17))
* Implements [#39](https://git.feneas.org/christophehenry/freshrss-android/issues/39): Better accessibility for the article-related actions ([!19](https://git.feneas.org/christophehenry/freshrss-android/merge_requests/19))
## Bug fixes
......
......@@ -86,7 +86,7 @@ dependencies {
// AndroidX layout
implementation "androidx.appcompat:appcompat:1.1.0-alpha03"
implementation "androidx.core:core-ktx:1.1.0-alpha05"
implementation "com.google.android.material:material:1.1.0-alpha04"
implementation "com.google.android.material:material:1.1.0-alpha05"
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.recyclerview:recyclerview:1.0.0"
......
......@@ -44,6 +44,11 @@
<activity
android:name=".activities.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
</application>
......
body {
padding: 0 0.5rem;
padding: 0 0.5rem 15vh 0.5rem;
font-size: 14pt;
}
......
......@@ -7,10 +7,10 @@ import android.webkit.WebView
import android.widget.Toast
import android.widget.Toast.LENGTH_SHORT
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.ShareActionProvider
import androidx.core.view.MenuItemCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import fr.chenry.android.freshrss.FreshRSSApplication
import fr.chenry.android.freshrss.R
import fr.chenry.android.freshrss.components.subscriptionarticles.webviewutils.FRSSWebViewClient
import fr.chenry.android.freshrss.components.subscriptionarticles.webviewutils.ShareIntent
......@@ -23,6 +23,7 @@ import fr.chenry.android.freshrss.utils.e
import nl.komponents.kovenant.ui.alwaysUi
import nl.komponents.kovenant.ui.failUi
class SubscriptionArticlesDetailFragment: Fragment() {
private lateinit var articleId: String
private val model: SubscriptionArticleVM by lazy {
......@@ -71,16 +72,15 @@ class SubscriptionArticlesDetailFragment: Fragment() {
}
}
setupShareAction(view)
setupOpenInBrowser(view)
return view
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.article_actionbar, menu)
setUpReadStatusButton(menu)
setupOpenInBrowser(menu)
setupShareAction(menu)
super.onCreateOptionsMenu(menu, inflater)
}
......@@ -94,20 +94,20 @@ class SubscriptionArticlesDetailFragment: Fragment() {
super.onDestroyView()
}
private fun setupShareAction(menu: Menu) {
menu.findItem(R.id.action_share)
.let {MenuItemCompat.getActionProvider(it) as ShareActionProvider}
.setShareIntent(ShareIntent(getTemplateAttributes()))
private fun setupShareAction(view: View) {
view.findViewById<ExtendedFloatingActionButton>(R.id.fab_share)
.setOnClickListener {
val chooserTitle = FreshRSSApplication.getStringR(R.string.share_article, subscription.title)
startActivity(Intent.createChooser(ShareIntent.create(getTemplateAttributes()), chooserTitle))
}
}
private fun setupOpenInBrowser(menu: Menu) {
if(article.url != null) {
val actionOrigin = menu.findItem(R.id.action_origin)
actionOrigin?.isVisible = true
actionOrigin?.setOnMenuItemClickListener {
private fun setupOpenInBrowser(view: View) {
view.findViewById<ExtendedFloatingActionButton>(R.id.fab_open_browser).let {
it.visibility = if(article.url != null) View.VISIBLE else View.GONE
it.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW).apply {data = article.url}
startActivity(intent)
true
}
}
}
......
......@@ -2,31 +2,35 @@ package fr.chenry.android.freshrss.components.subscriptionarticles.webviewutils
import android.content.Intent
import com.x5.template.Theme
import fr.chenry.android.freshrss.FreshRSSApplication
import fr.chenry.android.freshrss.R
import fr.chenry.android.freshrss.R.string
import fr.chenry.android.freshrss.components.subscriptionarticles.webviewutils.chunkfilters.SentenceCapFilter
import fr.chenry.android.freshrss.components.subscriptionarticles.webviewutils.chunkfilters.StripFragmentFilter
import fr.chenry.android.freshrss.utils.nullIfBlank
class ShareIntent(attributes: Map<String, String>): Intent(Intent.ACTION_SEND) {
init {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, format(attributes))
}
companion object {
private val defaultTemplate = """
object ShareIntent: Intent(Intent.ACTION_SEND) {
private val defaultTemplate = """
|{${'$'}title|strip_fragment(subscription)|sentence_cap} — {${'$'}subscription|capitalize}
|{${'$'}href}
""".trimMargin("|")
private val template = Theme().let {
it.registerFilter(SentenceCapFilter())
it.registerFilter(StripFragmentFilter())
it.makeChunk().apply {append(defaultTemplate)}
}
private val template = Theme().let {
it.registerFilter(SentenceCapFilter())
it.registerFilter(StripFragmentFilter())
it.makeChunk().apply {append(defaultTemplate)}
}
private fun format(attributes: Map<String, String>) = template.apply {
attributes.entries.forEach {(t, u) -> set(t, u)}
}.toString()
fun format(attributes: Map<String, String>) = template.apply {
attributes.entries.forEach {(t, u) -> set(t, u)}
}.toString()
fun create(attributes: Map<String, String>) = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
ShareIntent.putExtra(EXTRA_TEXT, format(attributes))
val feedName = attributes["subscription"]?.nullIfBlank() ?: FreshRSSApplication.getStringR(R.string.this_feed)
ShareIntent.putExtra(EXTRA_SUBJECT, FreshRSSApplication.getStringR(string.share_article, feedName))
}
}
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFF"
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".components.subscriptionarticles.SubscriptionArticlesDetailFragment"
android:orientation="vertical">
android:layout_height="match_parent">
<fr.chenry.android.freshrss.utils.LollipopFixedWebView
android:id="@+id/fragment_subscription_article_detail_web_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
\ No newline at end of file
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="bottom|center_horizontal">
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/fab_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/share"
android:layout_margin="16dp"
app:icon="?attr/actionModeShareDrawable" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/fab_open_browser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="@string/original_page"
app:icon="@drawable/ic_web_black_24dp" />
</LinearLayout>
</FrameLayout>
\ No newline at end of file
......@@ -4,11 +4,11 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/subscription_section_header_title"
android:text="A"
android:background="@color/colorAccent"
android:background="@color/color_accent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="@color/design_default_color_surface"
android:textColor="@color/design_default_color_on_primary"
android:textStyle="bold"
android:paddingTop="@dimen/subscription_section_v_padding"
android:paddingBottom="@dimen/subscription_section_v_padding"
......
......@@ -16,7 +16,7 @@
android:layout_marginStart="@dimen/badge_margin_start"
android:layout_marginBottom="@dimen/badge_margin_bottom"
android:textStyle="bold"
android:textColor="@color/alert_text"
android:textColor="@color/design_default_color_on_primary"
android:visibility="visible"
tools:ignore="HardcodedText" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_mark_read_status"
android:orderInCategory="1"
app:showAsAction="always"
android:visible="false" />
<item
android:id="@+id/action_share"
android:orderInCategory="2"
android:icon="@drawable/ic_share_black_24dp"
android:title="@string/share"
app:showAsAction="ifRoom"
app:actionProviderClass="androidx.appcompat.widget.ShareActionProvider" />
<item
android:id="@+id/action_origin"
android:orderInCategory="100"
android:icon="@drawable/ic_web_black_24dp"
android:title="@string/original_page"
app:showAsAction="collapseActionView"
android:visible="false" />
android:visible="false"
tools:ignore="AlwaysShowAction" />
</menu>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">@color/colorPrimaryDark</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#008577</color>
<!-- Base colors -->
<color name="color_primary">#00574B</color>
<color name="color_accent">#008577</color>
<color name="black">#000</color>
<color name="grey">#666666</color>
<color name="error">#A00</color>
<color name="alert">#A00</color>
<color name="alert_text">#FFF</color>
<color name="alert_inactive">@color/grey</color>
<color name="light_grey">#9E9E9E</color>
<color name="logo_obsidian">#41444f</color>
<color name="logo_grey">#c5c6ca</color>
<!-- Overrides -->
<color name="fast_scroller_bar">@color/grey</color>
<color name="fast_scroller_handle_idle">@color/colorAccent</color>
<color name="fast_scroller_handle_idle">@color/color_accent</color>
<color name="color_primary_dark">@color/color_primary</color>
<color name="alert_inactive">@color/grey</color>
<color name="alert">@color/error</color>
</resources>
......@@ -10,6 +10,7 @@
<dimen name="fab_margin">16dp</dimen>
<dimen name="badge_inactive_text_size">12sp</dimen>
<dimen name="badge_active_text_size">14sp</dimen>
<dimen name="small_text_size">10sp</dimen>
<dimen name="badge_height">@dimen/badge_active_text_size</dimen>
<dimen name="badge_width">22sp</dimen>
<dimen name="badge_radius">@dimen/badge_width</dimen>
......
......@@ -38,7 +38,7 @@
<string name="title">Title</string>
<string name="next">Next</string>
<string name="error_invalid_password">This password is too short</string>
<string name="original_page">Open in browser</string>
<string name="original_page">Open</string>
<string name="refresh">Refresh</string>
<string name="mark_read">Mark read</string>
<string name="mark_unread">Mark unread</string>
......@@ -72,4 +72,6 @@
<string name="good_evening_user">Good evening%s</string>
<string name="splash_screen">Splash screen</string>
<string name="subscription_categories">Categories</string>
<string name="share_article">Share article of %s</string>
<string name="this_feed">this feed</string>
</resources>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="colorPrimary">@color/color_primary</item>
<item name="colorPrimaryDark">@color/color_primary_dark</item>
<item name="colorAccent">@color/color_accent</item>
<item name="extendedFloatingActionButtonStyle">@style/AppTheme.ExtendedFloatingActionButton</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.MaterialComponents.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.MaterialComponents.Light" />
<style name="AppTheme.ExtendedFloatingActionButton" parent="Widget.MaterialComponents.ExtendedFloatingActionButton">
<item name="backgroundTint">@color/color_primary</item>
<item name="android:textColor">@color/design_default_color_on_primary</item>
<item name="iconTint">@color/design_default_color_on_primary</item>
</style>
</resources>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment