MM-29400 Mark all current notices as viewed for newly created users (#15840)
* Added clearing of notices for new users * ci kick
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
25fd59a435
Коммит
f2e5e1562d
@@ -177,6 +177,8 @@ type AppIface interface {
|
|||||||
// To get the plugins environment when the plugins are disabled, manually acquire the plugins
|
// To get the plugins environment when the plugins are disabled, manually acquire the plugins
|
||||||
// lock instead.
|
// lock instead.
|
||||||
GetPluginsEnvironment() *plugin.Environment
|
GetPluginsEnvironment() *plugin.Environment
|
||||||
|
// GetProductNotices is called from the frontend to fetch the product notices that are relevant to the caller
|
||||||
|
GetProductNotices(userId, teamId string, client model.NoticeClientType, clientVersion string, locale string) (model.NoticeMessages, *model.AppError)
|
||||||
// GetPublicKey will return the actual public key saved in the `name` file.
|
// GetPublicKey will return the actual public key saved in the `name` file.
|
||||||
GetPublicKey(name string) ([]byte, *model.AppError)
|
GetPublicKey(name string) ([]byte, *model.AppError)
|
||||||
// GetSanitizedConfig gets the configuration for a system admin without any secrets.
|
// GetSanitizedConfig gets the configuration for a system admin without any secrets.
|
||||||
@@ -314,6 +316,13 @@ type AppIface interface {
|
|||||||
UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError)
|
UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError)
|
||||||
// UpdateChannelScheme saves the new SchemeId of the channel passed.
|
// UpdateChannelScheme saves the new SchemeId of the channel passed.
|
||||||
UpdateChannelScheme(channel *model.Channel) (*model.Channel, *model.AppError)
|
UpdateChannelScheme(channel *model.Channel) (*model.Channel, *model.AppError)
|
||||||
|
// UpdateProductNotices is called periodically from a scheduled worker to fetch new notices and update the cache
|
||||||
|
UpdateProductNotices() *model.AppError
|
||||||
|
// UpdateViewedProductNotices is called from the frontend to mark a set of notices as 'viewed' by user
|
||||||
|
UpdateViewedProductNotices(userId string, noticeIds []string) *model.AppError
|
||||||
|
// UpdateViewedProductNoticesForNewUser is called when new user is created to mark all current notices for this
|
||||||
|
// user as viewed in order to avoid showing them imminently on first login
|
||||||
|
UpdateViewedProductNoticesForNewUser(userId string)
|
||||||
// UpdateWebConnUserActivity sets the LastUserActivityAt of the hub for the given session.
|
// UpdateWebConnUserActivity sets the LastUserActivityAt of the hub for the given session.
|
||||||
UpdateWebConnUserActivity(session model.Session, activityAt int64)
|
UpdateWebConnUserActivity(session model.Session, activityAt int64)
|
||||||
// UploadFile uploads a single file in form of a completely constructed byte array for a channel.
|
// UploadFile uploads a single file in form of a completely constructed byte array for a channel.
|
||||||
@@ -629,7 +638,6 @@ type AppIface interface {
|
|||||||
GetPreferencesForUser(userId string) (model.Preferences, *model.AppError)
|
GetPreferencesForUser(userId string) (model.Preferences, *model.AppError)
|
||||||
GetPrevPostIdFromPostList(postList *model.PostList) string
|
GetPrevPostIdFromPostList(postList *model.PostList) string
|
||||||
GetPrivateChannelsForTeam(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError)
|
GetPrivateChannelsForTeam(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError)
|
||||||
GetProductNotices(userId, teamId string, client model.NoticeClientType, clientVersion string, locale string) (model.NoticeMessages, *model.AppError)
|
|
||||||
GetProfileImage(user *model.User) ([]byte, bool, *model.AppError)
|
GetProfileImage(user *model.User) ([]byte, bool, *model.AppError)
|
||||||
GetPublicChannelsByIdsForTeam(teamId string, channelIds []string) (*model.ChannelList, *model.AppError)
|
GetPublicChannelsByIdsForTeam(teamId string, channelIds []string) (*model.ChannelList, *model.AppError)
|
||||||
GetPublicChannelsForTeam(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError)
|
GetPublicChannelsForTeam(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError)
|
||||||
@@ -973,7 +981,6 @@ type AppIface interface {
|
|||||||
UpdatePasswordSendEmail(user *model.User, newPassword, method string) *model.AppError
|
UpdatePasswordSendEmail(user *model.User, newPassword, method string) *model.AppError
|
||||||
UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model.AppError)
|
UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model.AppError)
|
||||||
UpdatePreferences(userId string, preferences model.Preferences) *model.AppError
|
UpdatePreferences(userId string, preferences model.Preferences) *model.AppError
|
||||||
UpdateProductNotices() *model.AppError
|
|
||||||
UpdateRole(role *model.Role) (*model.Role, *model.AppError)
|
UpdateRole(role *model.Role) (*model.Role, *model.AppError)
|
||||||
UpdateScheme(scheme *model.Scheme) (*model.Scheme, *model.AppError)
|
UpdateScheme(scheme *model.Scheme) (*model.Scheme, *model.AppError)
|
||||||
UpdateSessionsIsGuest(userId string, isGuest bool)
|
UpdateSessionsIsGuest(userId string, isGuest bool)
|
||||||
@@ -990,7 +997,6 @@ type AppIface interface {
|
|||||||
UpdateUserAuth(userId string, userAuth *model.UserAuth) (*model.UserAuth, *model.AppError)
|
UpdateUserAuth(userId string, userAuth *model.UserAuth) (*model.UserAuth, *model.AppError)
|
||||||
UpdateUserNotifyProps(userId string, props map[string]string) (*model.User, *model.AppError)
|
UpdateUserNotifyProps(userId string, props map[string]string) (*model.User, *model.AppError)
|
||||||
UpdateUserRoles(userId string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError)
|
UpdateUserRoles(userId string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError)
|
||||||
UpdateViewedProductNotices(userId string, noticeIds []string) *model.AppError
|
|
||||||
UploadData(us *model.UploadSession, rd io.Reader) (*model.FileInfo, *model.AppError)
|
UploadData(us *model.UploadSession, rd io.Reader) (*model.FileInfo, *model.AppError)
|
||||||
UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError
|
UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError
|
||||||
UploadMultipartFiles(teamId string, channelId string, userId string, fileHeaders []*multipart.FileHeader, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError)
|
UploadMultipartFiles(teamId string, channelId string, userId string, fileHeaders []*multipart.FileHeader, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError)
|
||||||
|
|||||||
@@ -15248,6 +15248,21 @@ func (a *OpenTracingAppLayer) UpdateViewedProductNotices(userId string, noticeId
|
|||||||
return resultVar0
|
return resultVar0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *OpenTracingAppLayer) UpdateViewedProductNoticesForNewUser(userId string) {
|
||||||
|
origCtx := a.ctx
|
||||||
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateViewedProductNoticesForNewUser")
|
||||||
|
|
||||||
|
a.ctx = newCtx
|
||||||
|
a.app.Srv().Store.SetContext(newCtx)
|
||||||
|
defer func() {
|
||||||
|
a.app.Srv().Store.SetContext(origCtx)
|
||||||
|
a.ctx = origCtx
|
||||||
|
}()
|
||||||
|
|
||||||
|
defer span.Finish()
|
||||||
|
a.app.UpdateViewedProductNoticesForNewUser(userId)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *OpenTracingAppLayer) UpdateWebConnUserActivity(session model.Session, activityAt int64) {
|
func (a *OpenTracingAppLayer) UpdateWebConnUserActivity(session model.Session, activityAt int64) {
|
||||||
origCtx := a.ctx
|
origCtx := a.ctx
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateWebConnUserActivity")
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateWebConnUserActivity")
|
||||||
|
|||||||
@@ -200,6 +200,7 @@ func validateConfigEntry(conf *model.Config, path string, expectedValue interfac
|
|||||||
return val == expectedValue
|
return val == expectedValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetProductNotices is called from the frontend to fetch the product notices that are relevant to the caller
|
||||||
func (a *App) GetProductNotices(userId, teamId string, client model.NoticeClientType, clientVersion string, locale string) (model.NoticeMessages, *model.AppError) {
|
func (a *App) GetProductNotices(userId, teamId string, client model.NoticeClientType, clientVersion string, locale string) (model.NoticeMessages, *model.AppError) {
|
||||||
isSystemAdmin := a.SessionHasPermissionTo(*a.Session(), model.PERMISSION_MANAGE_SYSTEM)
|
isSystemAdmin := a.SessionHasPermissionTo(*a.Session(), model.PERMISSION_MANAGE_SYSTEM)
|
||||||
isTeamAdmin := a.SessionHasPermissionToTeam(*a.Session(), teamId, model.PERMISSION_MANAGE_TEAM)
|
isTeamAdmin := a.SessionHasPermissionToTeam(*a.Session(), teamId, model.PERMISSION_MANAGE_TEAM)
|
||||||
@@ -275,6 +276,7 @@ func (a *App) GetProductNotices(userId, teamId string, client model.NoticeClient
|
|||||||
return filteredNotices, nil
|
return filteredNotices, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateViewedProductNotices is called from the frontend to mark a set of notices as 'viewed' by user
|
||||||
func (a *App) UpdateViewedProductNotices(userId string, noticeIds []string) *model.AppError {
|
func (a *App) UpdateViewedProductNotices(userId string, noticeIds []string) *model.AppError {
|
||||||
if err := a.Srv().Store.ProductNotices().View(userId, noticeIds); err != nil {
|
if err := a.Srv().Store.ProductNotices().View(userId, noticeIds); err != nil {
|
||||||
return model.NewAppError("UpdateViewedProductNotices", "api.system.update_viewed_notices.failed", nil, err.Error(), http.StatusBadRequest)
|
return model.NewAppError("UpdateViewedProductNotices", "api.system.update_viewed_notices.failed", nil, err.Error(), http.StatusBadRequest)
|
||||||
@@ -282,6 +284,19 @@ func (a *App) UpdateViewedProductNotices(userId string, noticeIds []string) *mod
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateViewedProductNoticesForNewUser is called when new user is created to mark all current notices for this
|
||||||
|
// user as viewed in order to avoid showing them imminently on first login
|
||||||
|
func (a *App) UpdateViewedProductNoticesForNewUser(userId string) {
|
||||||
|
var noticeIds []string
|
||||||
|
for _, notice := range cachedNotices {
|
||||||
|
noticeIds = append(noticeIds, notice.ID)
|
||||||
|
}
|
||||||
|
if err := a.Srv().Store.ProductNotices().View(userId, noticeIds); err != nil {
|
||||||
|
mlog.Error("Cannot update product notices viewed state for user", mlog.String("userId", userId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateProductNotices is called periodically from a scheduled worker to fetch new notices and update the cache
|
||||||
func (a *App) UpdateProductNotices() *model.AppError {
|
func (a *App) UpdateProductNotices() *model.AppError {
|
||||||
url := *a.Srv().Config().AnnouncementSettings.NoticesURL
|
url := *a.Srv().Config().AnnouncementSettings.NoticesURL
|
||||||
skip := *a.Srv().Config().AnnouncementSettings.NoticesSkipCache
|
skip := *a.Srv().Config().AnnouncementSettings.NoticesSkipCache
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ func (a *App) createUser(user *model.User) (*model.User, *model.AppError) {
|
|||||||
mlog.Error("Encountered error saving tutorial preference", mlog.Err(err))
|
mlog.Error("Encountered error saving tutorial preference", mlog.Err(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
go a.UpdateViewedProductNoticesForNewUser(ruser.Id)
|
||||||
ruser.Sanitize(map[string]bool{})
|
ruser.Sanitize(map[string]bool{})
|
||||||
return ruser, nil
|
return ruser, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user