From a102b8b145ab9131f3ee97400c99d7e2a2431278 Mon Sep 17 00:00:00 2001 From: Sacha Froment Date: Thu, 10 Jan 2019 16:25:50 +0100 Subject: [PATCH] feat(notification): add i18n on local go notification Signed-off-by: Sacha Froment --- core/cmd/berty/daemon.go | 2 +- core/manager/account/account.go | 5 +++-- core/node/event_handlers.go | 21 ++++++++++++------- core/packrd/packed-packr.go | 10 ++++----- core/pkg/errorcodes/code.go | 2 +- core/pkg/i18n/i18n.go | 9 ++++---- core/pkg/i18n/locales/active.en.yaml | 30 +++++++++++++++++++++++++++ core/pkg/i18n/locales/active.fr.yaml | 30 +++++++++++++++++++++++++++ core/pkg/notification/notification.go | 20 ++++++++++++++++-- 9 files changed, 106 insertions(+), 23 deletions(-) diff --git a/core/cmd/berty/daemon.go b/core/cmd/berty/daemon.go index 61bf5404cc..e6972cd88c 100644 --- a/core/cmd/berty/daemon.go +++ b/core/cmd/berty/daemon.go @@ -46,7 +46,7 @@ type daemonOptions struct { func daemonSetupFlags(flags *pflag.FlagSet, opts *daemonOptions) { flags.StringVar(&opts.nickname, "nickname", "berty-daemon", "set account nickname") flags.BoolVar(&opts.dropDatabase, "drop-database", false, "drop database to force a reinitialization") - flags.BoolVar(&opts.notification, "notification", false, "enable local notification") + flags.BoolVar(&opts.notification, "notification", true, "enable local notification") flags.BoolVar(&opts.hideBanner, "hide-banner", false, "hide banner") flags.BoolVar(&opts.initOnly, "init-only", false, "stop after node initialization (useful for integration tests") flags.BoolVar(&opts.noP2P, "no-p2p", false, "Disable p2p Driver") diff --git a/core/manager/account/account.go b/core/manager/account/account.go index 058961c024..32d001173a 100644 --- a/core/manager/account/account.go +++ b/core/manager/account/account.go @@ -29,6 +29,7 @@ import ( "berty.tech/core/network/netutil" "berty.tech/core/node" "berty.tech/core/pkg/errorcodes" + "berty.tech/core/pkg/i18n" "berty.tech/core/pkg/notification" "berty.tech/core/pkg/tracing" "berty.tech/core/pkg/zapring" @@ -499,8 +500,8 @@ func (a *Account) initNode(ctx context.Context) error { } a.node.DisplayNotification(notification.Payload{ - Title: "Node started", - Body: "Berty daemon is now up and running", + Title: i18n.T("DaemonStartTitle", nil), + Body: i18n.T("DaemonStartBody", nil), }) return nil } diff --git a/core/node/event_handlers.go b/core/node/event_handlers.go index 3545f568ef..4bb4a9e32b 100644 --- a/core/node/event_handlers.go +++ b/core/node/event_handlers.go @@ -8,6 +8,7 @@ import ( "berty.tech/core/api/p2p" "berty.tech/core/entity" "berty.tech/core/pkg/errorcodes" + "berty.tech/core/pkg/i18n" "berty.tech/core/pkg/notification" bsql "berty.tech/core/sql" "github.com/gofrs/uuid" @@ -48,8 +49,10 @@ func (n *Node) handleContactRequest(ctx context.Context, input *p2p.Event) error } n.DisplayNotification(notification.Payload{ - Title: "Contact request", - Body: attrs.Me.DisplayName + " wants to add you", + Title: i18n.T("ContactRequestTitle", nil), + Body: i18n.T("ContactRequestBody", map[string]interface{}{ + "Name": attrs.Me.DisplayName, + }), }) // nothing more to do, now we wait for the UI to accept the request return nil @@ -79,8 +82,10 @@ func (n *Node) handleContactRequestAccepted(ctx context.Context, input *p2p.Even } n.DisplayNotification(notification.Payload{ - Title: "Contact request accepted", - Body: contact.DisplayName + " accepted your request", + Title: i18n.T("ContactRequestAccpetedTitle", nil), + Body: i18n.T("ContactRequestAccpetedBody", map[string]interface{}{ + "Name": contact.DisplayName, + }), }) return nil } @@ -139,8 +144,8 @@ func (n *Node) handleConversationInvite(ctx context.Context, input *p2p.Event) e } n.DisplayNotification(notification.Payload{ - Title: "Conversation invite", - Body: "You have been invited to a new conversation", + Title: i18n.T("ConversationInviteTitle", nil), + Body: i18n.T("ConversationInviteBody", nil), }) return nil @@ -156,8 +161,8 @@ func (n *Node) handleConversationNewMessage(ctx context.Context, input *p2p.Even n.sql(ctx).Save(&entity.Conversation{ID: input.ConversationID, ReadAt: time.Time{}}) n.DisplayNotification(notification.Payload{ - Title: "New message", - Body: "You have a new message", + Title: i18n.T("NewMessageTitle", nil), + Body: i18n.T("NewMessageBody", nil), }) return nil } diff --git a/core/packrd/packed-packr.go b/core/packrd/packed-packr.go index 1ac6829c8e..166107c012 100644 --- a/core/packrd/packed-packr.go +++ b/core/packrd/packed-packr.go @@ -10,11 +10,11 @@ import ( ) var _ = func() error { - const gk = "dac2a54d96ec9a9a5bde3120d135c01a" + const gk = "069371a4ebb37cba0d01696156bbe2bd" g := packr.New(gk, "") hgr, err := resolver.NewHexGzip(map[string]string{ - "4fabd44d8b4475a89b60143e4a4c012f": "1f8b08000000000000ff6c8fb14a03411086fb7b8a9f34363e413a095788a411152cc7dd893b64995d676763eeede53c4888673930ffc7f78d66af1af920ca713b0040f1c4b6c5e641d195cf958373049b154309a19b71dc0cc368f6465922b9147dd4dafd76fe9218add79a85234e943b431ab4f87c48bc47cd4c8d11128723a6d20d325316f4aea853f067fe7ae2692fad897edef277a4770e8a1184b07ce35b3c95ee20d4fe9125e0c8d33fbcb5e8f57d9614fd55fcbb1ccfd27ce5f15e3a281b539c90e8c4f024ed6224baa46569abb2fdd4381fd6b470299ba7f30fa85d2b37c34f000000ffff67e63b7db4010000", - "a15704113954281d03d30b26ef0bdd8c": "1f8b08000000000000ff6ccf316e02311085e17e4ff144932627a08d28504213097a63cf2683cc7899f1ac02a749cb39f662d10a44044b6f7fef9f85ea5a12b52c94e60d0094fa4d3ac76c2d04522557b0c422e204b20a73ed499c664db350dd84cc29542eb294ceeb3df111d0873c0a6d7115be00a3a64ab1d22bfae1acdc329dd097aa040b6c7ca5df8ad410eb271ddee9b8623396af7b7fb9ef8a196f3321bd845df14a0a17c4cb4f5810bb4e2b1221e6e18cceb799e3938949fbfff3833fa63ffe5ffcb0d549e0a6b821f474421acebbe117916e71698cbb5c9dd9a6e2ea6894db279e10bae223da85511827aeb7c7b2dfdf1666cd5f000000ffff3e7c7ecddd010000", + "64facd2c8ee83068e407b13a9eec94c9": "1f8b08000000000000ff8c933172db3010457b9e62474d9a4c0ee02e89557812a94862f710f0e540432ee85d80b1ecf1297201b73c0727f7ca8062a4a1c8685c73ffdbf701702972cb0e5bcf7057051151883f2157b4b865104490843cdbc09c40d0489aa401272c8a622972674aef4cf4816fb84e718cf86aa83165266c4312f60740a689c046bca7a66bc56f3d9ea80951406abcfa01fd397034367ec3c317ec575ed5f3fd987f53d541d56f4a907b677621450825267b48921ad661b59003d9b26ba94e9bd2db991513f7d3f8433a573fcf2f1fbdc689e05d484aa6c113b9aedd75af6471947359eed0baf43a25aef68a723bc363501d5286d62613f28aa1bb0d5575dcb0288a6b832af0f768247e0aeebc21c8f5df690389fbbea0eb5a0d5219af14eaae95fe6619e598f5c3c71263d8facfefe472bc32225dbb288a5393049d8b5ca332ecd05fccd1789c9a4a3f3f7f589b0a2f2fd4203d8edb77afa4e6709897a01fadad11e1dea444c65ad471a6d13fcc2547738c0f37edfed3b981e8f017353e6246adffd08f0ce163649630b53abdc5aecd423ecf756d3eb55df0ec049478425ee3d70aaae67ece699d9fa149541d2646e3970412139f47ff060000fffff8ac133089040000", + "da3f3b56ddd0a1aa93d06b4627710f81": "1f8b08000000000000ff8492b16edb4010447b7ec5404d9a201fe0ce765c048154244e8094ebbbb1b83075c7dced89260cff7b40d1a24093704a8233b36f6ef72ea55fc1f35103fd550500d16aa62b6cae034ae0734b67f4604a31213a5752a2df54d55d4abfa5512fa6317c0b6db1b9fdbe267269db46e97194a6109a11a20d1fea3fa36d28997035dd13fa5812744819a36f633071f6837fbfb3df6ace1af6f3fc5b099f0ce23d046e54a353ab633108daf2d0a8c313fb95bc25e8453e406a3821be77de3d6bb605c79f58204da2f81eb51c09ab354f441ac66a8de645b36d9fd93c2ed3dcd46cb00e1a48beb4dc54d557e121869f26c96ea27fd7e786c97af893647cf20ea585048f5442d0b09f27dcab359c47eca227f2f0f3b4ea0b72615ed3bf099046c5c2b2847c79f9b293035f5fd149b00c8be7c20bf3b5732d8dfeff7321ceb15d633e677c0472368f0b9b553932e5b73b3faa719d64120df7a3c655eb1260d8f8e96e1ec8b3d59fde0381ddb0f4296253553b765be62cfb35881d3b1cc6bf33e90743c72193e95f000000ffffbae1f35a0e040000", }) if err != nil { panic(err) @@ -23,8 +23,8 @@ var _ = func() error { func() { b := packr.New("Locales", "./locales") - b.SetResolver("active.en.yaml", packr.Pointer{ForwardBox: gk, ForwardPath: "4fabd44d8b4475a89b60143e4a4c012f"}) - b.SetResolver("active.fr.yaml", packr.Pointer{ForwardBox: gk, ForwardPath: "a15704113954281d03d30b26ef0bdd8c"}) + b.SetResolver("active.en.yaml", packr.Pointer{ForwardBox: gk, ForwardPath: "da3f3b56ddd0a1aa93d06b4627710f81"}) + b.SetResolver("active.fr.yaml", packr.Pointer{ForwardBox: gk, ForwardPath: "64facd2c8ee83068e407b13a9eec94c9"}) }() return nil diff --git a/core/pkg/errorcodes/code.go b/core/pkg/errorcodes/code.go index eb0eff2278..ed530b1668 100644 --- a/core/pkg/errorcodes/code.go +++ b/core/pkg/errorcodes/code.go @@ -55,7 +55,7 @@ func (c Code) newError(placeholders map[string]string, stack *stack, cause error if !ok { grpcCode = codes.Unknown } - localized := i18n.T(codeName) // FIXME: support placeholders + localized := i18n.T(codeName, nil) // FIXME: support placeholders e := convert( errors.New(localized), grpcCode, diff --git a/core/pkg/i18n/i18n.go b/core/pkg/i18n/i18n.go index 7996a510ff..ac76f8d4cd 100644 --- a/core/pkg/i18n/i18n.go +++ b/core/pkg/i18n/i18n.go @@ -9,7 +9,7 @@ import ( "github.com/gobuffalo/packr/v2" goI18n "github.com/nicksnyder/go-i18n/v2/i18n" "golang.org/x/text/language" - "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v2" ) type singleton struct { @@ -58,11 +58,11 @@ func SetLanguage(tag *language.Tag) { i18n().language = tag } -func T(messageID string, templateData ...string) string { - return TCount(messageID, 1, templateData...) +func T(messageID string, templateData interface{}) string { + return TCount(messageID, 1, templateData) } -func TCount(messageID string, count int, templateData ...string) string { +func TCount(messageID string, count int, templateData interface{}) string { i18nInstance := i18n() localizer := goI18n.NewLocalizer(i18nInstance.bundle, i18nInstance.language.String()) @@ -71,6 +71,7 @@ func TCount(messageID string, count int, templateData ...string) string { DefaultMessage: &goI18n.Message{ ID: messageID, }, + TemplateData: templateData, }) if err != nil { diff --git a/core/pkg/i18n/locales/active.en.yaml b/core/pkg/i18n/locales/active.en.yaml index e4747791b0..7478728449 100644 --- a/core/pkg/i18n/locales/active.en.yaml +++ b/core/pkg/i18n/locales/active.en.yaml @@ -15,3 +15,33 @@ ErrContactReqExisting: ErrContactReqMyself: other: "You can't add yourself as a contact" + +DaemonStartBody: + other: "Berty daemon is now up and running" + +DaemonStartTitle: + other: "Node started" + +ContactRequestTitle: + other: "Contact request" + +ContactRequestBody: + other: "{{.Name}} wants to add you" + +ContactRequestAccpetedTitle: + other: "Contact request accepted" + +ContactRequestAccpetedBody: + other: "{{.Name}} accepted your request" + +ConversationInviteTitle: + other: "Conversation invite" + +ConversationInviteBody: + other: "You have been invited to a new conversation" + +NewMessageTitle: + other: "New message" + +NewMessageBody: + other: "You have a new message" diff --git a/core/pkg/i18n/locales/active.fr.yaml b/core/pkg/i18n/locales/active.fr.yaml index 956af70ae2..c1325e46ce 100644 --- a/core/pkg/i18n/locales/active.fr.yaml +++ b/core/pkg/i18n/locales/active.fr.yaml @@ -15,3 +15,33 @@ ErrContactReqExisting: ErrContactReqMyself: other: "Vous ne pouvez pas vous ajouter comme contact" + +DaemonStartBody: + other: "Le daemon berty est désormais opérationnel" + +DaemonStartTitle: + other: "Nœud démarré" + +ContactRequestTitle: + other: "Demande de contact" + +ContactRequestBody: + other: "{{.Name}} veut vous ajouter à sa liste de contact" + +ContactRequestAccpetedTitle: + other: "Demande de contact acceptée" + +ContactRequestAccpetedBody: + other: "{{.Name}} a accepté votre demande de contact" + +ConversationInviteTitle: + other: "Invitation de conversation" + +ConversationInviteBody: + other: "Vous avez été invité à joindre une conversation" + +NewMessageTitle: + other: "Nouveau message" + +NewMessageBody: + other: "Vous avez un nouveau message" diff --git a/core/pkg/notification/notification.go b/core/pkg/notification/notification.go index 93ec38fc8c..58d6c67e09 100644 --- a/core/pkg/notification/notification.go +++ b/core/pkg/notification/notification.go @@ -3,7 +3,12 @@ package notification import ( - "github.com/gen2brain/beeep" + "path" + "runtime" + "sync" + + "github.com/0xAX/notificator" + "go.uber.org/zap" ) @@ -55,6 +60,8 @@ func (n *NoopNotification) ReceivePushID(pushID, pushIDType string) { // NoopNotification is a Driver var _ Driver = (*DesktopNotification)(nil) +var notify *notificator.Notificator +var once sync.Once func NewDesktopNotification() Driver { return &DesktopNotification{} @@ -63,7 +70,16 @@ func NewDesktopNotification() Driver { type DesktopNotification struct{} func (n *DesktopNotification) DisplayNotification(p Payload) error { - return beeep.Notify(p.Title, p.Body, p.Icon) + once.Do(func() { + _, filename, _, _ := runtime.Caller(0) + iconPath := path.Dir(filename) + "/../../../client/react-native/common/static/img/logo.png" + notify = notificator.New(notificator.Options{ + DefaultIcon: iconPath, + AppName: "Berty", + }) + }) + + return notify.Push(p.Title, p.Body, p.Icon, notificator.UR_NORMAL) } func (n *DesktopNotification) ReceiveNotification(data string) {}