Drop the "ask an assistant" entry from the selection menu
With no local server configured it opened the same chooser Share does, only with a prompt in front of the text. Two entries for one chooser makes the reader choose twice, and the third entry pushed Look up into the overflow; both now fit in the bar. Asking moves to the lookup screen's top bar, where it keeps the part that was actually distinct: a configured server answers in place, and without one the question still goes out with "translate this and explain what it means" already written. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
90b527522b
commit
d320137063
@ -33,9 +33,9 @@
|
|||||||
one. Three aliases rather than a single Ganjoor entry: the menu is a place for verbs, and
|
one. Three aliases rather than a single Ganjoor entry: the menu is a place for verbs, and
|
||||||
a reader who means "look this up" should not have to pick the app first.
|
a reader who means "look this up" should not have to pick the app first.
|
||||||
|
|
||||||
"Ask an assistant" cannot be an entry per assistant — only Claude or Gemini can put their
|
There is no "ask an assistant" entry: with no local server configured it would open the
|
||||||
own name in this menu. It opens the share chooser instead, which lists whichever of them
|
same chooser Share does, and two entries for one chooser makes the reader choose twice.
|
||||||
is installed, with the question already written.
|
Asking lives on the lookup screen instead, where it can use a configured server.
|
||||||
-->
|
-->
|
||||||
<activity
|
<activity
|
||||||
android:name=".ProcessTextActivity"
|
android:name=".ProcessTextActivity"
|
||||||
@ -55,19 +55,6 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity-alias>
|
</activity-alias>
|
||||||
|
|
||||||
<activity-alias
|
|
||||||
android:name=".AskAssistantText"
|
|
||||||
android:icon="@drawable/ic_ask"
|
|
||||||
android:targetActivity=".ProcessTextActivity"
|
|
||||||
android:exported="true"
|
|
||||||
android:label="@string/assistant_ask">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.PROCESS_TEXT" />
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<data android:mimeType="text/plain" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity-alias>
|
|
||||||
|
|
||||||
<activity-alias
|
<activity-alias
|
||||||
android:name=".ShareText"
|
android:name=".ShareText"
|
||||||
android:icon="@drawable/ic_share"
|
android:icon="@drawable/ic_share"
|
||||||
|
|||||||
@ -39,7 +39,7 @@ import androidx.core.graphics.drawable.toDrawable
|
|||||||
import com.ganjoor.android.data.AssistantSettings
|
import com.ganjoor.android.data.AssistantSettings
|
||||||
import com.ganjoor.android.data.Dictionary
|
import com.ganjoor.android.data.Dictionary
|
||||||
import com.ganjoor.android.data.LocalAssistant
|
import com.ganjoor.android.data.LocalAssistant
|
||||||
import com.ganjoor.android.ui.AssistantAnswer
|
import com.ganjoor.android.ui.AssistantResultSheet
|
||||||
import com.ganjoor.android.ui.LocalSettings
|
import com.ganjoor.android.ui.LocalSettings
|
||||||
import com.ganjoor.android.ui.Settings
|
import com.ganjoor.android.ui.Settings
|
||||||
import com.ganjoor.android.ui.WordLookup
|
import com.ganjoor.android.ui.WordLookup
|
||||||
@ -88,11 +88,7 @@ class ProcessTextActivity : ComponentActivity() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val action = when (intent.component?.className?.substringAfterLast('.')) {
|
val sharing = intent.component?.className?.endsWith("ShareText") == true
|
||||||
"AskAssistantText" -> SelectionAction.Ask
|
|
||||||
"ShareText" -> SelectionAction.Share
|
|
||||||
else -> SelectionAction.LookUp
|
|
||||||
}
|
|
||||||
|
|
||||||
val settings = Settings(applicationContext)
|
val settings = Settings(applicationContext)
|
||||||
val systemInDark = resources.configuration.uiMode and
|
val systemInDark = resources.configuration.uiMode and
|
||||||
@ -110,48 +106,34 @@ class ProcessTextActivity : ComponentActivity() {
|
|||||||
LocalLayoutDirection provides LayoutDirection.Rtl,
|
LocalLayoutDirection provides LayoutDirection.Rtl,
|
||||||
) {
|
) {
|
||||||
GanjoorTheme(settings.value.theme, settings.value.language, settings.value.oled) {
|
GanjoorTheme(settings.value.theme, settings.value.language, settings.value.oled) {
|
||||||
SelectionScreen(selected, action, onClose = ::finish)
|
SelectionScreen(selected, sharing, onClose = ::finish)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Which verb the reader picked in the selection menu. */
|
|
||||||
enum class SelectionAction { LookUp, Ask, Share }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each alias goes straight to its action. Share finishes immediately — the system chooser is the
|
* Share goes straight to the system chooser and finishes, so this screen is only ever seen for a
|
||||||
* whole interface — so this screen is only ever seen for a lookup or an answer.
|
* lookup. Asking an assistant is a button here rather than an entry of its own in the selection
|
||||||
|
* menu: with no server configured it opens the same chooser Share does, and two menu entries for
|
||||||
|
* one chooser is a menu that makes the reader choose twice.
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun SelectionScreen(selected: String, action: SelectionAction, onClose: () -> Unit) {
|
private fun SelectionScreen(selected: String, sharing: Boolean, onClose: () -> Unit) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val assistant = LocalAssistant.current
|
val assistant = LocalAssistant.current
|
||||||
val prefs = LocalSettings.current.value
|
|
||||||
|
|
||||||
// Without a server configured there is nothing to ask, so the question goes to whichever
|
|
||||||
// assistant the reader has installed. That hand-off is also what keeps this F-Droid-clean:
|
|
||||||
// no vendor SDK, no API key, nothing but an intent the reader confirms.
|
|
||||||
val askLocally = action == SelectionAction.Ask && assistant.serverReady
|
|
||||||
val prompt = stringResource(R.string.assistant_ask_prompt)
|
val prompt = stringResource(R.string.assistant_ask_prompt)
|
||||||
|
var asking by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
LaunchedEffect(action) {
|
LaunchedEffect(sharing) {
|
||||||
when {
|
if (sharing) {
|
||||||
action == SelectionAction.Share -> {
|
|
||||||
context.shareText(selected)
|
context.shareText(selected)
|
||||||
onClose()
|
onClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
action == SelectionAction.Ask && !askLocally -> {
|
|
||||||
context.shareText("$prompt\n\n$selected")
|
|
||||||
onClose()
|
|
||||||
}
|
}
|
||||||
}
|
if (sharing) return
|
||||||
}
|
|
||||||
|
|
||||||
if (action == SelectionAction.Share || (action == SelectionAction.Ask && !askLocally)) return
|
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
@ -163,9 +145,18 @@ private fun SelectionScreen(selected: String, action: SelectionAction, onClose:
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
// The dictionary knows single words; a whole line is better asked about.
|
// The dictionary knows single words; a whole line is better asked about. Your
|
||||||
IconButton(onClick = { context.shareText("$prompt\n\n$selected") }) {
|
// own server answers here; without one the question goes to whichever
|
||||||
Icon(painterResource(R.drawable.ic_ask), stringResource(R.string.assistant_ask))
|
// assistant is installed, which is what keeps this F-Droid-clean — no vendor
|
||||||
|
// SDK, no key, nothing but an intent you confirm.
|
||||||
|
IconButton(onClick = {
|
||||||
|
if (assistant.serverReady) asking = true
|
||||||
|
else context.shareText("$prompt\n\n$selected")
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.ic_ask),
|
||||||
|
contentDescription = stringResource(R.string.assistant_ask),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
IconButton(onClick = { context.shareText(selected) }) {
|
IconButton(onClick = { context.shareText(selected) }) {
|
||||||
Icon(Icons.Default.Share, stringResource(R.string.share))
|
Icon(Icons.Default.Share, stringResource(R.string.share))
|
||||||
@ -175,7 +166,15 @@ private fun SelectionScreen(selected: String, action: SelectionAction, onClose:
|
|||||||
},
|
},
|
||||||
) { insets ->
|
) { insets ->
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(insets)) {
|
Column(modifier = Modifier.fillMaxSize().padding(insets)) {
|
||||||
if (askLocally) AssistantAnswer(selected) else WordLookup(selected)
|
WordLookup(selected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (asking) {
|
||||||
|
AssistantResultSheet(
|
||||||
|
prompt = "explain",
|
||||||
|
text = selected,
|
||||||
|
onDismiss = { asking = false },
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user