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

Improve Android notification threading, categorisation, and profile images #19613

Merged
merged 32 commits into from
Jun 27, 2023

Conversation

Julesssss
Copy link
Contributor

@Julesssss Julesssss commented May 25, 2023

Details

Introduces conversation styel notifications. iOS and Android notifications now show a bigger avatar of the message sender. On Android, we also include much better notification threading, with mini conversations displayed within the notification along with mini avatars for each user.

Improvements to Android notification threads:

  • Improved notification TYPING (room, group, DM)
  • Only attempt to apply custom notification logic if the onyxPayload exists
  • Alternate logic for the first DM, to ensure correct type and styling
  • Removed the 'Chat With' notification title prefix
  • Cache the profile image instead of re-retrieving and creating it for each notification
  • Show profile icons in collapsed threads
  • Show large profile image for some notifications

Minor improvements

  • Fixed reportID using int instead of long
  • Add fallback notification icon
  • Improved const naming and logging
  • Correctly formatting the AndroidManifest file

DM me if you want a pre-compiled release APK to test on an Android device or emulator!

Fixed Issues

$ https://github.com/Expensify/Expensify/issues/260137

Tests

1) Test Direct message notifications

  • Be signed into the Android app
  • As a different user, send a direct message
  • The Android user should see a notification containing (senders name, senders profile image, and the message)
  • The title should be the senders name
  • The title should not be prefixed with Chat With:
  • The notification should be expandable
  • Hari Seldon
  • [lots of emojis]
  • Do NOT swipe away the notification
  • Send a second message
  • Both messages should be visible when expanding the notification
  • Clear the notifications by wiping them away
First DM Second DM
Screenshot_20230623-102448 Screenshot_20230623-102512

2) Test Group chat noifications

  • Create or locate a group with multiple users
  • Be signed in on an Android device
  • As a non-android user, send a message to the room
  • The Android user should see a notification containing (senders name, senders profile image, message, and a list of the group participants)
  • The notification should be expandable
  • jules, Jules, Hari, Salvor - now
  • Hari Seldon: Lets all go out for lunch today?
  • The senders name should be bold
  • Do NOT swipe away the notification
  • Send a second message to the room from a different user
  • The notification should expand to show both messages
  • Both user avatars should be visible when expanded
  • Clear the notifications by wiping them away
First message Second message both messages
Screenshot_20230623-103207 Screenshot_20230623-103221 Screenshot_20230623-103225

3) Test room notificatons

  • Create or locate a room with multiple users
  • As a user signed in on Android, navigate to room settings
  • Select 'Notify me about new messages': Immediately
  • As a different user, send a message to the room
  • The Android user should see a notification containing (senders name, senders profile image, message, and the room name)
  • The notification should be expandable
  • New Expensify - #announce - now
  • Hari Seldon
  • Welcome new employees!
  • The senders name should be bold
  • Do NOT swipe away the notification
  • Send a second message to the room from a different user
  • The notification should expand to show both messages
  • Both user avatars should be visible when expanded
  • Clear the notifications by wiping them away
Notification collapsed Notification Expanded
Screenshot_20230623-102826 Screenshot_20230623-102830
1st message 2nd message both messages
Screenshot_20230623-102850 Screenshot_20230623-102914 Screenshot_20230623-102921
  1. Test multiple concurrent notification threads
  • Send notifications to the Android user from multiple different accounts or types (dm, group chat, room)
  • Each notification should appear as it's own swipeable notification
  • After locking the device screen, you should be able to expand/collapse each thread individually
Multiple threads Unexpanded Multiple threads Expanded
Screenshot_20230623-103111 Screenshot_20230623-103117

[x] Verify that no errors appear in the JS console

Offline tests

Not applicable, as you must be online in order to receive notifications!

QA Steps

Run the same tests as above!

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android / native
    • Android / Chrome
    • iOS / native
    • iOS / Safari
    • MacOS / Chrome / Safari
    • MacOS / Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that the left part of a conditional rendering a React component is a boolean and NOT a string, e.g. myBool && <MyComponent />.
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
      • If any non-english text was added/modified, I verified the translation was requested/reviewed in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is approved by marketing by adding the Waiting for Copy label for a copy review on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG))
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR author checklist, including those that don't apply to this PR.

Screenshots/Videos

Only Android was modified!

Many screenshots are shown against the test cases.

@Julesssss Julesssss self-assigned this May 25, 2023
@Julesssss Julesssss changed the title Notification payload improvements [name TBD] Notification payload improvements Jun 1, 2023
@Julesssss Julesssss changed the title Notification payload improvements Testing notification payload fix Jun 1, 2023
Comment on lines 1 to -25
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.expensify.chat">
xmlns:tools="http://schemas.android.com/tools"
package="com.expensify.chat">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<!-- android:hardwareAccelerated is essential for Android performance: https://developer.android.com/topic/performance/hardware-accel -->
<application
android:supportsRtl="false"
android:hardwareAccelerated="true"
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:resizeableActivity="false"
android:theme="@style/AppTheme"
tools:replace="android:supportsRtl">

<activity
android:name=".MainActivity"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Most of the manifest changes are fixing bad formatting. I will comment to point out the actual changes.

Comment on lines +145 to +147
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_launcher" />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a new addition. It sets a default notification icon

Comment on lines +149 to +151
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/bootsplash_background" />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is another addition, it sets the default notification background color.

@melvin-bot
Copy link

melvin-bot bot commented Jun 26, 2023

🎯 @eVoloshchak, thanks for reviewing and testing this PR! 🎉

An E/App issue has been created to issue payment here: #21554.

@Julesssss Julesssss requested a review from a team June 26, 2023 11:15
@melvin-bot melvin-bot bot requested review from allroundexperts and removed request for a team June 26, 2023 11:15
@Expensify Expensify deleted a comment from melvin-bot bot Jun 26, 2023
@Julesssss Julesssss removed the request for review from allroundexperts June 26, 2023 11:16
@Julesssss
Copy link
Contributor Author

The automation is clearly broken...I'm going to create a new issue and then use that to manually assign a randomly assigned internal engineer.

@fedirjh
Copy link
Contributor

fedirjh commented Jun 26, 2023

@Julesssss I think we should post this:

🎀 👀 🎀 C+ reviewed

Edit: it didn’t trigger the automation as well 😕

@Julesssss
Copy link
Contributor Author

I'll try pullerbear again.

@Julesssss Julesssss requested a review from a team June 26, 2023 12:40
@melvin-bot melvin-bot bot requested review from rushatgabhane and removed request for a team June 26, 2023 12:40
@melvin-bot

This comment was marked as outdated.

@Julesssss Julesssss removed the request for review from rushatgabhane June 26, 2023 12:41
@Julesssss
Copy link
Contributor Author

Sorry everyone who is being tagged, I'm trying to figure out how the new automation works.

@Julesssss Julesssss requested a review from bondydaa June 26, 2023 15:08
@Julesssss
Copy link
Contributor Author

Okay, @bondydaa won the prize of being the internal reviewer for this PR.

Let me know if you need any help testing, but it should be pretty straightforward if you use the Android build here. You can test using the staging/prod environment 👍

Copy link
Contributor

@bondydaa bondydaa left a comment

Choose a reason for hiding this comment

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

nothing seems glaring wrong but I also am def not an Android expert here either.

Maybe @cristipaval might want to double check this too, I think you have some more native experience?

@Julesssss Julesssss merged commit e5f00f8 into main Jun 27, 2023
@Julesssss Julesssss deleted the jules-notificationPayload branch June 27, 2023 07:43
@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by https://github.com/Julesssss in version: 1.3.34-0 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@Julesssss
Copy link
Contributor Author

Testing well on staging:

Screenshot_20230629-093325
Screenshot_20230629-093438

@OSBotify
Copy link
Contributor

🚀 Deployed to production by https://github.com/thienlnam in version: 1.3.34-1 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@Julesssss Julesssss restored the jules-notificationPayload branch July 12, 2023 15:31
@Julesssss Julesssss deleted the jules-notificationPayload branch August 11, 2023 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
InternalQA This pull request required internal QA Ready To Build
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants