-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
Conversation
@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 |
f492b42
to
312c3b4
Compare
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. |
Update plugin_api_test.go
49e2d05
to
d4f2dc6
Compare
There was a problem hiding this 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.
app/plugin_api.go
Outdated
if cs == nil || !cs.SetByProduct { | ||
return model.NewAppError("RestoreToPreviousCustomStatus", "plugin.api.restore_to_previous_custom_status", nil, "", http.StatusBadRequest) | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
app/plugin_api.go
Outdated
if err != nil { | ||
return model.NewAppError("RestoreToPreviousCustomStatus", "plugin.api.restore_to_previous_custom_status", nil, "failed to get recent statuses to reset", http.StatusInternalServerError) | ||
} |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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
app/plugin_api.go
Outdated
|
||
if len(rcs) == 0 { | ||
err := api.app.RemoveCustomStatus(api.ctx, userID) | ||
if err != nil { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handled with wrap
app/plugin_api.go
Outdated
} | ||
|
||
cserr := api.app.SetCustomStatus(api.ctx, userID, rcs[0]) | ||
if cserr != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
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. |
/update-branch |
There was a problem hiding this 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
if err != nil { | ||
return nil, err | ||
} |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
There was a problem hiding this 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
// Minimum server version: 7.2 | ||
RestoreToPreviousCustomStatus(userID string) *model.AppError |
There was a problem hiding this comment.
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
Outdated
return nil | ||
} | ||
|
||
cserr := api.app.SetCustomStatus(api.ctx, userID, rcs[0]) |
There was a problem hiding this comment.
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"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
/update-branch |
…termost-server into user-custom-status-plugin
There was a problem hiding this 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 👍
There was a problem hiding this 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"` |
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
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?
Hey @M-ZubairAhmed it seems like there is an extra file included as |
Yes, i removed this. |
/update-branch |
Closing for now, will get back to this when time permits again |
@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 |
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