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

New plugin API "RestoreToPreviousCustomStatus" added #20851

Closed
wants to merge 15 commits into from

Conversation

M-ZubairAhmed
Copy link
Member

@M-ZubairAhmed M-ZubairAhmed commented Aug 19, 2022

Summary

The objective of this new plugin API is for the plugins/products to set custom status for a temporary duration of time. For example: When zoom call is started, the user who joined/started the call will have their custom status changed to "In Zoom meeting". When the call is ended their status is reverted back to whatever they had set previously.

This is achieved by a new plugin API "RestoreToPreviousCustomStatus", which plugins can use to restore the previous stored user custom status. The way it does is by adding a new key to user custom status preference category called "setByProject". When a product/plugin sets the custom status by calling "UpdateUserCustomStatus" they need to pass in value for "setByProject" as true, then the "SetCustomStatus" function does not stored the custom status in the recent custom status list.

Ticket Link

n/a

Release Note

RestoreToPreviousCustomStatus method added in plugins api

@mm-cloud-bot
Copy link

@M-ZubairAhmed: Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

I understand the commands that are listed here

@M-ZubairAhmed M-ZubairAhmed force-pushed the user-custom-status-plugin branch from f492b42 to 312c3b4 Compare August 19, 2022 06:13
@M-ZubairAhmed M-ZubairAhmed changed the title implementation added New method "RestoreToPreviousCustomStatus" added in plugins api Aug 19, 2022
@M-ZubairAhmed M-ZubairAhmed added 2: Dev Review Requires review by a developer 3: QA Review Requires review by a QA tester. May occur at the same time as Dev Review labels Aug 19, 2022
@mattermod
Copy link
Contributor

E2E tests not automatically triggered, because PR has no approval yet. Please ask a developer to review and then try again to attach the QA label.

@mm-cloud-bot mm-cloud-bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed do-not-merge/release-note-label-needed labels Aug 19, 2022
@M-ZubairAhmed M-ZubairAhmed marked this pull request as ready for review August 19, 2022 06:26
Update plugin_api_test.go
@M-ZubairAhmed M-ZubairAhmed force-pushed the user-custom-status-plugin branch from 49e2d05 to d4f2dc6 Compare August 19, 2022 07:51
@M-ZubairAhmed M-ZubairAhmed changed the title New method "RestoreToPreviousCustomStatus" added in plugins api New plugin API "RestoreToPreviousCustomStatus" added Aug 19, 2022
Copy link
Member

@isacikgoz isacikgoz left a comment

Choose a reason for hiding this comment

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

Hey @M-ZubairAhmed did my first pass, I have some points that needs to be addressed.

Comment on lines 379 to 381
if cs == nil || !cs.SetByProduct {
return model.NewAppError("RestoreToPreviousCustomStatus", "plugin.api.restore_to_previous_custom_status", nil, "", http.StatusBadRequest)
}
Copy link
Member

Choose a reason for hiding this comment

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

Is this a real error case? Or, we are just ignoring the restoration process? If the latter, I don't think it's necessary to return error.

Copy link
Member Author

Choose a reason for hiding this comment

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

its the latter case. Changed it to return nil

Comment on lines 384 to 386
if err != nil {
return model.NewAppError("RestoreToPreviousCustomStatus", "plugin.api.restore_to_previous_custom_status", nil, "failed to get recent statuses to reset", http.StatusInternalServerError)
}
Copy link
Member

Choose a reason for hiding this comment

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

We are losing the error detail here, I'd suggest using Wrap(error) method for the model.AppError.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added the method to the AppError


if len(rcs) == 0 {
err := api.app.RemoveCustomStatus(api.ctx, userID)
if err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Again, the error is lost.

Copy link
Member Author

Choose a reason for hiding this comment

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

handled with wrap

}

cserr := api.app.SetCustomStatus(api.ctx, userID, rcs[0])
if cserr != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Same as above.

Copy link
Member Author

Choose a reason for hiding this comment

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

handled with wrap

func (a *App) GetRecentCustomStatuses(userID string) ([]*model.CustomStatus, error) {
pref, err := a.GetPreferenceByCategoryAndNameForUser(userID, model.PreferenceCategoryCustomStatus, model.PreferenceNameRecentCustomStatuses)

var existingRCS []*model.CustomStatus
Copy link
Member

Choose a reason for hiding this comment

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

Why we are ignoring the error here? I mean the err variable from the L:460

Copy link
Member Author

Choose a reason for hiding this comment

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

Handled and returned the err

@agarciamontoro
Copy link
Member

I've been postponing this until today, but I had an unexpected super long meeting, so I didn't have time to go through it. I'll be off next week, back on Tuesday September 6, so if you want to change reviewers, please feel free to do so.

@M-ZubairAhmed M-ZubairAhmed requested review from BenCookie95 and removed request for agarciamontoro August 30, 2022 07:41
@M-ZubairAhmed
Copy link
Member Author

/update-branch

@M-ZubairAhmed M-ZubairAhmed requested review from levb and removed request for BenCookie95 September 2, 2022 12:36
Copy link
Member

@isacikgoz isacikgoz left a comment

Choose a reason for hiding this comment

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

Looks good, we should also run a e2e test for these to be sure. Just a single thing that needs to be changed. Otherwise looks good.

app/status.go Outdated
Comment on lines 470 to 472
if err != nil {
return nil, err
}
Copy link
Member

Choose a reason for hiding this comment

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

We need to remove this, it's already handled in L:461

Copy link
Member Author

Choose a reason for hiding this comment

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

removed

Copy link
Contributor

@mickmister mickmister left a comment

Choose a reason for hiding this comment

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

Awesome work @M-ZubairAhmed! This greatly improves the power of this feature.

The PR mostly looks good 👍 I mainly have some requests in regards to the unit test added here

app/plugin_api_test.go Outdated Show resolved Hide resolved
app/plugin_api_test.go Show resolved Hide resolved
app/plugin_api_test.go Show resolved Hide resolved
app/plugin_api_test.go Show resolved Hide resolved
app/plugin_api_test.go Outdated Show resolved Hide resolved
app/status.go Show resolved Hide resolved
app/status.go Outdated Show resolved Hide resolved
Comment on lines +289 to +290
// Minimum server version: 7.2
RestoreToPreviousCustomStatus(userID string) *model.AppError
Copy link
Contributor

Choose a reason for hiding this comment

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

Note that this will need to be updated if this PR is not merged with 7.2 (I think that's obvious though)

app/plugin_api.go Show resolved Hide resolved
return nil
}

cserr := api.app.SetCustomStatus(api.ctx, userID, rcs[0])
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's say I have recent custom statuses, but my last choice as a user was to remove my custom status. With the logic here, will this function set my status back to my last recent one, rather than setting it back to my proper previous state of "no custom status"?

Copy link
Member Author

@M-ZubairAhmed M-ZubairAhmed Oct 14, 2022

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

I read this code you're linking to, but I figured in my scenario described above, len(rcs) would not be zero. Under what conditions does GetRecentCustomStatuses return an empty slice?

If a user clears their status, wouldn't their "recent custom statuses" preference still contain values, thus making it so len is greater than zero?

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mind writing a unit test for this block? The steps I'm thinking:

  • User sets custom status
  • User clears custom status
  • Plugin sets custom status
  • Call restore status
  • Assert that user has no status, rather than the initial one they had on

Copy link
Member Author

Choose a reason for hiding this comment

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

@mickmister yes the more i think about it , you are right even if user clears custom status the recent ones are still there. No restoring but actually take up the first of them and set it up. What do you think we can do here?

Copy link
Member Author

Choose a reason for hiding this comment

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

gentle ping on this one @mickmister

Copy link
Contributor

Choose a reason for hiding this comment

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

@M-ZubairAhmed I'm thinking the recent statuses field should resemble "the most recent statuses set by the user", and shouldn't be something where we remove from that list. I don't think it should be used as a state variable for logic like this snippet we're commenting on.

Maybe we can add two fields to custom status:

  • One that means "last status user manually chose", and clear this value when they clear their status
  • One that means "last status set by a product", and clear this value when:
    • Product wants to clear it
    • and when User sets or clears their status manually

The product status field would always take precedence for what is shown in the UI, but it always gets cleared whenever the user sets or clears their custom status. What do you think @M-ZubairAhmed?

@M-ZubairAhmed
Copy link
Member Author

/update-branch

@catalintomai catalintomai requested review from javaguirre and removed request for catalintomai October 14, 2022 15:57
Copy link
Contributor

@mickmister mickmister left a comment

Choose a reason for hiding this comment

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

Just one request to make sure the case of #20851 (comment) is unit tested. Otherwise LGTM 👍

Copy link
Contributor

@javaguirre javaguirre left a comment

Choose a reason for hiding this comment

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

Just a couple of details to discuss

Text string `json:"text"`
Duration string `json:"duration"`
ExpiresAt time.Time `json:"expires_at"`
SetByProduct bool `json:"set_by_product,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if SetByProduct is descriptive, maybe focusing more on the behavior rather than in "who" set it? like IsSetAutomatically or something like this? also changing the name to reference it's a boolean (that's why I added Is at the beginning).

ExpiresAt time.Time `json:"expires_at"`
Emoji string `json:"emoji"`
Text string `json:"text"`
Duration string `json:"duration"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is Duration a string? wouldn't it be better a Duration from time?

@isacikgoz
Copy link
Member

Hey @M-ZubairAhmed it seems like there is an extra file included as output to the PR. Was it by mistake?

@M-ZubairAhmed
Copy link
Member Author

Hey @M-ZubairAhmed it seems like there is an extra file included as output to the PR. Was it by mistake?

Yes, i removed this.

@isacikgoz
Copy link
Member

/update-branch

@M-ZubairAhmed
Copy link
Member Author

Closing for now, will get back to this when time permits again

@mickmister
Copy link
Contributor

@M-ZubairAhmed Do you have interest in continuing this PR? Asking to know if we should reassign this to implement mattermost/mattermost-plugin-mscalendar#228

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2: Dev Review Requires review by a developer 3: QA Review Requires review by a QA tester. May occur at the same time as Dev Review release-note Denotes a PR that will be considered when it comes time to generate release notes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants