display notification every time users open the app or login

This commit is contained in:
MaysWind
2024-08-05 01:25:26 +08:00
parent c137156c97
commit 05a93667eb
9 changed files with 113 additions and 17 deletions
+15
View File
@@ -187,6 +187,21 @@ avatar_provider = internal
# Set to true to allow users to export their data # Set to true to allow users to export their data
enable_export = true enable_export = true
[notification]
# Set to true to display custom notification in home page every time users login
enable_notification_after_login = false
# The notification content displayed each time users log in, it supports multi-language configuration
# Add an underscore and a language tag after the setting key to configure the notification content in that language, the same below
# For example, after_login_notification_content_zh_hans means the notification content in Simplified Chinese
after_login_notification_content =
# Set to true to display custom notification in home page every time users open the app
enable_notification_after_open = false
# The notification content displayed each time users open the app, it supports multi-language configuration
after_open_notification_content =
[map] [map]
# Map provider, supports the following types: # Map provider, supports the following types:
# "openstreetmap": https://www.openstreetmap.org # "openstreetmap": https://www.openstreetmap.org
+1
View File
@@ -245,5 +245,6 @@ func (a *AuthorizationsApi) getAuthResponse(token string, need2FA bool, user *mo
Token: token, Token: token,
Need2FA: need2FA, Need2FA: need2FA,
User: user.ToUserBasicInfo(), User: user.ToUserBasicInfo(),
NotificationContent: settings.Container.GetAfterLoginNotificationContent(user.Language),
} }
} }
+2
View File
@@ -205,6 +205,7 @@ func (a *TokensApi) TokenRefreshHandler(c *core.Context) (any, *errs.Error) {
refreshResp := &models.TokenRefreshResponse{ refreshResp := &models.TokenRefreshResponse{
User: user.ToUserBasicInfo(), User: user.ToUserBasicInfo(),
NotificationContent: settings.Container.GetAfterOpenNotificationContent(user.Language),
} }
return refreshResp, nil return refreshResp, nil
@@ -233,6 +234,7 @@ func (a *TokensApi) TokenRefreshHandler(c *core.Context) (any, *errs.Error) {
NewToken: token, NewToken: token,
OldTokenId: a.tokens.GenerateTokenId(oldTokenRecord), OldTokenId: a.tokens.GenerateTokenId(oldTokenRecord),
User: user.ToUserBasicInfo(), User: user.ToUserBasicInfo(),
NotificationContent: settings.Container.GetAfterOpenNotificationContent(user.Language),
} }
return refreshResp, nil return refreshResp, nil
+3
View File
@@ -93,6 +93,7 @@ func (a *UsersApi) UserRegisterHandler(c *core.Context) (any, *errs.Error) {
AuthResponse: models.AuthResponse{ AuthResponse: models.AuthResponse{
Need2FA: false, Need2FA: false,
User: user.ToUserBasicInfo(), User: user.ToUserBasicInfo(),
NotificationContent: settings.Container.GetAfterLoginNotificationContent(user.Language),
}, },
NeedVerifyEmail: settings.Container.Current.EnableUserVerifyEmail && settings.Container.Current.EnableUserForceVerifyEmail, NeedVerifyEmail: settings.Container.Current.EnableUserVerifyEmail && settings.Container.Current.EnableUserForceVerifyEmail,
PresetCategoriesSaved: presetCategoriesSaved, PresetCategoriesSaved: presetCategoriesSaved,
@@ -187,6 +188,8 @@ func (a *UsersApi) UserEmailVerifyHandler(c *core.Context) (any, *errs.Error) {
resp.NewToken = token resp.NewToken = token
resp.User = user.ToUserBasicInfo() resp.User = user.ToUserBasicInfo()
resp.NotificationContent = settings.Container.GetAfterLoginNotificationContent(user.Language)
c.SetTextualToken(token) c.SetTextualToken(token)
c.SetTokenClaims(claims) c.SetTokenClaims(claims)
+1
View File
@@ -5,6 +5,7 @@ type AuthResponse struct {
Token string `json:"token"` Token string `json:"token"`
Need2FA bool `json:"need2FA"` Need2FA bool `json:"need2FA"`
User *UserBasicInfo `json:"user"` User *UserBasicInfo `json:"user"`
NotificationContent string `json:"notificationContent,omitempty"`
} }
// RegisterResponse returns a view-object of user register response // RegisterResponse returns a view-object of user register response
+1
View File
@@ -27,6 +27,7 @@ type TokenRefreshResponse struct {
NewToken string `json:"newToken,omitempty"` NewToken string `json:"newToken,omitempty"`
OldTokenId string `json:"oldTokenId,omitempty"` OldTokenId string `json:"oldTokenId,omitempty"`
User *UserBasicInfo `json:"user"` User *UserBasicInfo `json:"user"`
NotificationContent string `json:"notificationContent,omitempty"`
} }
// TokenInfoResponse represents a view-object of token // TokenInfoResponse represents a view-object of token
+1
View File
@@ -166,6 +166,7 @@ type UserVerifyEmailRequest struct {
type UserVerifyEmailResponse struct { type UserVerifyEmailResponse struct {
NewToken string `json:"newToken,omitempty"` NewToken string `json:"newToken,omitempty"`
User *UserBasicInfo `json:"user"` User *UserBasicInfo `json:"user"`
NotificationContent string `json:"notificationContent,omitempty"`
} }
// UserResendVerifyEmailRequest represents all parameters of user resend verify email request // UserResendVerifyEmailRequest represents all parameters of user resend verify email request
+46
View File
@@ -11,6 +11,7 @@ import (
"gopkg.in/ini.v1" "gopkg.in/ini.v1"
"github.com/mayswind/ezbookkeeping/pkg/errs" "github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/locales"
) )
const ( const (
@@ -178,6 +179,13 @@ type MinIOConfig struct {
RootPath string RootPath string
} }
// NotificationConfig represents a notification setting config
type NotificationConfig struct {
Enabled bool
DefaultContent string
MultiLanguageContent map[string]string
}
// Config represents the global setting config // Config represents the global setting config
type Config struct { type Config struct {
// Global // Global
@@ -263,6 +271,10 @@ type Config struct {
// Data // Data
EnableDataExport bool EnableDataExport bool
// Notification
AfterLoginNotification NotificationConfig
AfterOpenNotification NotificationConfig
// Map // Map
MapProvider string MapProvider string
EnableMapDataFetchProxy bool EnableMapDataFetchProxy bool
@@ -371,6 +383,12 @@ func LoadConfiguration(configFilePath string) (*Config, error) {
return nil, err return nil, err
} }
err = loadNotificationConfiguration(config, cfgFile, "notification")
if err != nil {
return nil, err
}
err = loadMapConfiguration(config, cfgFile, "map") err = loadMapConfiguration(config, cfgFile, "map")
if err != nil { if err != nil {
@@ -700,6 +718,13 @@ func loadDataConfiguration(config *Config, configFile *ini.File, sectionName str
return nil return nil
} }
func loadNotificationConfiguration(config *Config, configFile *ini.File, sectionName string) error {
config.AfterLoginNotification = getNotificationConfiguration(configFile, sectionName, "enable_notification_after_login", "after_login_notification_content")
config.AfterOpenNotification = getNotificationConfiguration(configFile, sectionName, "enable_notification_after_open", "after_open_notification_content")
return nil
}
func loadMapConfiguration(config *Config, configFile *ini.File, sectionName string) error { func loadMapConfiguration(config *Config, configFile *ini.File, sectionName string) error {
mapProvider := getConfigItemStringValue(configFile, sectionName, "map_provider") mapProvider := getConfigItemStringValue(configFile, sectionName, "map_provider")
@@ -820,6 +845,27 @@ func getFinalPath(workingPath, p string) (string, error) {
return p, err return p, err
} }
func getNotificationConfiguration(configFile *ini.File, sectionName string, enableKey string, contentKey string) NotificationConfig {
config := NotificationConfig{
Enabled: getConfigItemBoolValue(configFile, sectionName, enableKey, false),
DefaultContent: getConfigItemStringValue(configFile, sectionName, contentKey, ""),
MultiLanguageContent: make(map[string]string),
}
for languageTag := range locales.AllLanguages {
multiLanguageContentKey := strings.ToLower(languageTag)
multiLanguageContentKey = strings.Replace(multiLanguageContentKey, "-", "_", -1)
multiLanguageContentKey = contentKey + "_" + multiLanguageContentKey
content := getConfigItemStringValue(configFile, sectionName, multiLanguageContentKey, "")
if content != "" {
config.MultiLanguageContent[languageTag] = content
}
}
return config
}
func getConfigItemIsSet(configFile *ini.File, sectionName string, itemName string) bool { func getConfigItemIsSet(configFile *ini.File, sectionName string, itemName string) bool {
environmentKey := getEnvironmentKey(sectionName, itemName) environmentKey := getEnvironmentKey(sectionName, itemName)
environmentValue := os.Getenv(environmentKey) environmentValue := os.Getenv(environmentKey)
+26
View File
@@ -16,3 +16,29 @@ var (
func SetCurrentConfig(config *Config) { func SetCurrentConfig(config *Config) {
Container.Current = config Container.Current = config
} }
// GetAfterLoginNotificationContent returns the notification content displayed each time users log in
func (c *ConfigContainer) GetAfterLoginNotificationContent(language string) string {
if !c.Current.AfterLoginNotification.Enabled {
return ""
}
if multiLanguageContent, exists := c.Current.AfterLoginNotification.MultiLanguageContent[language]; exists {
return multiLanguageContent
}
return c.Current.AfterLoginNotification.DefaultContent
}
// GetAfterOpenNotificationContent returns the notification content displayed each time users open the app
func (c *ConfigContainer) GetAfterOpenNotificationContent(language string) string {
if !c.Current.AfterOpenNotification.Enabled {
return ""
}
if multiLanguageContent, exists := c.Current.AfterOpenNotification.MultiLanguageContent[language]; exists {
return multiLanguageContent
}
return c.Current.AfterOpenNotification.DefaultContent
}