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
|
||||
// lock instead.
|
||||
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(name string) ([]byte, *model.AppError)
|
||||
// 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)
|
||||
// UpdateChannelScheme saves the new SchemeId of the channel passed.
|
||||
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(session model.Session, activityAt int64)
|
||||
// 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)
|
||||
GetPrevPostIdFromPostList(postList *model.PostList) string
|
||||
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)
|
||||
GetPublicChannelsByIdsForTeam(teamId string, channelIds []string) (*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
|
||||
UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model.AppError)
|
||||
UpdatePreferences(userId string, preferences model.Preferences) *model.AppError
|
||||
UpdateProductNotices() *model.AppError
|
||||
UpdateRole(role *model.Role) (*model.Role, *model.AppError)
|
||||
UpdateScheme(scheme *model.Scheme) (*model.Scheme, *model.AppError)
|
||||
UpdateSessionsIsGuest(userId string, isGuest bool)
|
||||
@@ -990,7 +997,6 @@ type AppIface interface {
|
||||
UpdateUserAuth(userId string, userAuth *model.UserAuth) (*model.UserAuth, *model.AppError)
|
||||
UpdateUserNotifyProps(userId string, props map[string]string) (*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)
|
||||
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)
|
||||
|
||||
@@ -15248,6 +15248,21 @@ func (a *OpenTracingAppLayer) UpdateViewedProductNotices(userId string, noticeId
|
||||
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) {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateWebConnUserActivity")
|
||||
|
||||
@@ -200,6 +200,7 @@ func validateConfigEntry(conf *model.Config, path string, expectedValue interfac
|
||||
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) {
|
||||
isSystemAdmin := a.SessionHasPermissionTo(*a.Session(), model.PERMISSION_MANAGE_SYSTEM)
|
||||
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
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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)
|
||||
@@ -282,6 +284,19 @@ func (a *App) UpdateViewedProductNotices(userId string, noticeIds []string) *mod
|
||||
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 {
|
||||
url := *a.Srv().Config().AnnouncementSettings.NoticesURL
|
||||
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))
|
||||
}
|
||||
|
||||
go a.UpdateViewedProductNoticesForNewUser(ruser.Id)
|
||||
ruser.Sanitize(map[string]bool{})
|
||||
return ruser, nil
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user