MM-56082 Add PreferencesHaveChanged plugin hook (#25659)

* Add interface for PreferencesHaveChanged hook

* Add context to preference-related methods of App

* Implement PreferencesHaveChanged

* Re-add missing "fmt" import

* Update minimum server version for the new hook

* Remove pointers to be consistent with other preference APIs
This commit is contained in:
Harrison Healey
2024-01-03 12:25:53 -05:00
committed by GitHub
parent 18f0d8d88f
commit 502cd6ef7d
19 changed files with 226 additions and 64 deletions

View File

@@ -1018,6 +1018,40 @@ func (s *hooksRPCServer) OnSharedChannelsPing(args *Z_OnSharedChannelsPingArgs,
return nil
}
func init() {
hookNameToId["PreferencesHaveChanged"] = PreferencesHaveChangedID
}
type Z_PreferencesHaveChangedArgs struct {
A *Context
B []model.Preference
}
type Z_PreferencesHaveChangedReturns struct {
}
func (g *hooksRPCClient) PreferencesHaveChanged(c *Context, preferences []model.Preference) {
_args := &Z_PreferencesHaveChangedArgs{c, preferences}
_returns := &Z_PreferencesHaveChangedReturns{}
if g.implemented[PreferencesHaveChangedID] {
if err := g.client.Call("Plugin.PreferencesHaveChanged", _args, _returns); err != nil {
g.log.Error("RPC call PreferencesHaveChanged to plugin failed.", mlog.Err(err))
}
}
}
func (s *hooksRPCServer) PreferencesHaveChanged(args *Z_PreferencesHaveChangedArgs, returns *Z_PreferencesHaveChangedReturns) error {
if hook, ok := s.impl.(interface {
PreferencesHaveChanged(c *Context, preferences []model.Preference)
}); ok {
hook.PreferencesHaveChanged(args.A, args.B)
} else {
return encodableError(fmt.Errorf("Hook PreferencesHaveChanged called but not implemented."))
}
return nil
}
type Z_RegisterCommandArgs struct {
A *model.Command
}

View File

@@ -57,6 +57,7 @@ const (
ServeMetricsID = 39
OnSharedChannelsSyncMsgID = 40
OnSharedChannelsPingID = 41
PreferencesHaveChangedID = 42
TotalHooksID = iota
)
@@ -354,4 +355,11 @@ type Hooks interface {
//
// Minimum server version: 9.5
OnSharedChannelsPing(rc *model.RemoteCluster) bool
// PreferencesHaveChanged is invoked after one or more of a user's preferences have changed.
// Note that this method will be called for preferences changed by plugins, including the plugin that changed
// the preferences.
//
// Minimum server version: 9.5
PreferencesHaveChanged(c *Context, preferences []model.Preference)
}

View File

@@ -264,3 +264,9 @@ func (hooks *hooksTimerLayer) OnSharedChannelsPing(rc *model.RemoteCluster) bool
hooks.recordTime(startTime, "OnSharedChannelsPing", true)
return _returnsA
}
func (hooks *hooksTimerLayer) PreferencesHaveChanged(c *Context, preferences []model.Preference) {
startTime := timePkg.Now()
hooks.hooksImpl.PreferencesHaveChanged(c, preferences)
hooks.recordTime(startTime, "PreferencesHaveChanged", true)
}

View File

@@ -359,6 +359,11 @@ func (_m *Hooks) OnWebSocketDisconnect(webConnID string, userID string) {
_m.Called(webConnID, userID)
}
// PreferencesHaveChanged provides a mock function with given fields: c, preferences
func (_m *Hooks) PreferencesHaveChanged(c *plugin.Context, preferences []model.Preference) {
_m.Called(c, preferences)
}
// ReactionHasBeenAdded provides a mock function with given fields: c, reaction
func (_m *Hooks) ReactionHasBeenAdded(c *plugin.Context, reaction *model.Reaction) {
_m.Called(c, reaction)

View File

@@ -147,6 +147,10 @@ type OnSharedChannelsPingIFace interface {
OnSharedChannelsPing(rc *model.RemoteCluster) bool
}
type PreferencesHaveChangedIFace interface {
PreferencesHaveChanged(c *Context, preferences []model.Preference)
}
type HooksAdapter struct {
implemented map[int]struct{}
productHooks any
@@ -457,6 +461,15 @@ func NewAdapter(productHooks any) (*HooksAdapter, error) {
return nil, errors.New("hook has OnSharedChannelsPing method but does not implement plugin.OnSharedChannelsPing interface")
}
// Assessing the type of the productHooks if it individually implements PreferencesHaveChanged interface.
tt = reflect.TypeOf((*PreferencesHaveChangedIFace)(nil)).Elem()
if ft.Implements(tt) {
a.implemented[PreferencesHaveChangedID] = struct{}{}
} else if _, ok := ft.MethodByName("PreferencesHaveChanged"); ok {
return nil, errors.New("hook has PreferencesHaveChanged method but does not implement plugin.PreferencesHaveChanged interface")
}
return a, nil
}
@@ -756,3 +769,12 @@ func (a *HooksAdapter) OnSharedChannelsPing(rc *model.RemoteCluster) bool {
return a.productHooks.(OnSharedChannelsPingIFace).OnSharedChannelsPing(rc)
}
func (a *HooksAdapter) PreferencesHaveChanged(c *Context, preferences []model.Preference) {
if _, ok := a.implemented[PreferencesHaveChangedID]; !ok {
panic("product hooks must implement PreferencesHaveChanged")
}
a.productHooks.(PreferencesHaveChangedIFace).PreferencesHaveChanged(c, preferences)
}