Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

toast notifications #752

Merged
merged 11 commits into from
May 31, 2024
Merged

toast notifications #752

merged 11 commits into from
May 31, 2024

Conversation

codokie
Copy link
Contributor

@codokie codokie commented Apr 24, 2024

This PR adds toast notifications.

In Android 12L and below, there is no need for notification permission (which Heliboard currently does not have), so the toasts will be displayed natively.

For newer Android versions, a "fake" toast will be shown instead. Here's how it would look (inspired by OneUI):
Screenshot from 2024-05-28 01-46-29

It has a 300ms fade in/out animation to make the transition smoother. The view does not prevent pressing the keys it covers.

In Android versions older than 13, a toast notification will now be shown for 2 seconds when content is copied to the clipboard (can be triggered by pressing the copy/cut toolbar keys).
In Android 13+, most devices already show some kind of notification whenever the clipboard is set, so there is no need to display another one.

However, it will be possible to use it for other purposes like indicating an image URI could not be pasted to an input field (#722), or that the clipboard history has been cleared (#679). If you have any other ideas please let me know.

Fixes #545

@Helium314
Copy link
Owner

Not sure whether it works, but having the fake toast in default device style is worth trying. Could you try making a Toast without showing it on Android 13+ and extract the background drawable and text color?
According to https://stackoverflow.com/a/9432923 Toast.getView() should contain a TextView accessible via TextView v = (TextView) toast.getView().findViewById(android.R.id.message);
Then you could get background and text color using v.getBackground() and v.getCurrentTextColor().

@codokie
Copy link
Contributor Author

codokie commented May 2, 2024

Toast.getView() should contain a TextView accessible via TextView v = (TextView) toast.getView().findViewById(android.R.id.message);

I don't think this still works, I tried to get the view and got:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference'

The comment here may be the reason for it

@Uranusek
Copy link

Uranusek commented May 5, 2024

Shouldn't this notification be a little lower? 🤔 Most often I saw them just above the spacebar.

@codokie
Copy link
Contributor Author

codokie commented May 6, 2024

I think you might be right, but there may be a better placement for this notification:

In OneUI 6 (android 14) the toast notification when copying something to the clipboard are actually above the keyboard, right in the middle of the screen:

toast

That makes the toast less intrusive as it does not hide keys on the keyboard

@Uranusek
Copy link

Uranusek commented May 6, 2024

It looks better than on the keyboard, but I think that for some people such a notification in the middle of the screen can be annoying. Maybe it's better to place it just above the keyboard?

@codokie
Copy link
Contributor Author

codokie commented May 6, 2024

Just above the keyboard would probably over input fields because they have a tendency to be just above the keyboard too (and below the center of the screen).
Like here for instance (screenshot taken from Messages app):

messages

@Helium314
Copy link
Owner

I find the position somewhat awkward comparing to normal toast messages, but showing some amount above the keyboard definitely is a good idea, as this is a. not covering the text field (assuming it's a single line), and b. not at a place that might be covered with fingers.

The inability to copy the system toast style is unfortunate. Though maybe we could derive toast colors from the keyboard colors...

@Helium314
Copy link
Owner

@codokie do you plan to move the notification to the place above the input field, or do you consider this PR done?

@codokie
Copy link
Contributor Author

codokie commented May 27, 2024

I think such change would make the toast notifications less obstructive for the user, so it may be worth trying to implement it.

I'm a newbie still when it comes to xml layouts, I tried to change things around in main_keyboard_frame.xml to no avail, perhaps you are aware of another approach that might work?

The idea is to place the toast's TextView directly in the middle of the screen, I don't think it's possible to tell where the input field is actually placed

@Helium314
Copy link
Owner

I think it might work when you do it in input_view.xml.
But this might also end up increasing size of the input view, which would be bad. If that doesn't work out, I'll have a look later.

@codokie
Copy link
Contributor Author

codokie commented May 27, 2024

Thanks, input_view.xml seems to do the trick!

The only thing that may be missing is a mini-sized icon of Heliboard to the left of the icon message, so people would be able to tell the notification is coming from the HeliBoard app, like in a real toast:
Screenshot from 2024-05-27 20-53-13
I believe this should be pretty easy to add, perhaps later today

@Helium314
Copy link
Owner

You could try something like android:drawableLeft="@drawable/ic_launcher_round" in the TextView.

@Helium314
Copy link
Owner

like in a real toast

This is highly dependent on the Android version though, device manufacturers may style the toast, and some custom roms also do this, or let the user tune the toast.
I just want to say that sticking to specific style is not necessary, as it cannot fit with toast style of all devices.

@codokie
Copy link
Contributor Author

codokie commented May 27, 2024

You are right there is no standard toast, it's a shame we can't use the system toast view without the notification permission..
That said, the icon is useful for figuring out where the toast message is coming from, so it's more than a style choice.

With the new changes our "fake" toast looks like this:
Screenshot from 2024-05-28 01-46-29

In my samsung device this style seems natural, I hope it would not look really out of place in other ROMs

@Helium314
Copy link
Owner

Having the message centered may be a (minor) issue in some cases. E.g. in landscape mode it will be on the keyboard, or when height scale is very low it will be far above the keyboard. But handling the window insets is probably too much, at least in scope of this PR.

final PopupMenu uglyWorkaround = new PopupMenu(DialogUtilsKt.getPlatformDialogThemeContext(getContext()), wordView);
uglyWorkaround.getMenu().add(Menu.NONE, 1, Menu.NONE, text);
uglyWorkaround.show();
mListener.showToast(text, true, true);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me, the toast is hidden behind the more suggestions panel. Is it the same for you?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just checked and it is also hidden for me
There should be some way to make the toast view appear on top
Alternatively another 'ugly workaround' would be to dismiss the more suggestions panel just before the toast would get shown
In landscape mode the fake toast isn't shown even when the panel is dismissed, but mFakeToast.bringToFront() seems to solve that

@Helium314
Copy link
Owner

I don't really like the way how some parts of the toast are being handled though.

  1. When showToast is called, it should really show a toast; the fallback thing is out of place. When it should actually not show the toast_msg_clipboard_copy toast, then just don't call showToast (have that logic in copyText)
  2. I don't think showToast should be in LatinIME, KeyboardSwitcher already has a relevant part of that code. Then you could also call it using KeyboardSwitcher.getInstance().showToast

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="300" />
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that reproduce the toast on your system? For me the default toast is much faster than that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean that the animation of the system toast is faster? because in terms of timing I haven't noticed a real difference

@codokie
Copy link
Contributor Author

codokie commented May 28, 2024

  1. I opted for the fallback argument to just so there wouldn't be a need to check the build version in RichInputConnection, but yeah besides that it isn't very useful so it can be removed
  2. Sounds fair, I did not know you could get an instance of KeyboardSwitcher. I'll remove the code from LatinIME

@Helium314 Helium314 merged commit e357f84 into Helium314:main May 31, 2024
1 check passed
@codokie codokie deleted the toast branch June 4, 2024 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a short "text copied" popup when tapping the copy icon shortcut
3 participants