diff --git a/db/init.sql b/db/init.sql index f9630a0f..25434fc3 100644 --- a/db/init.sql +++ b/db/init.sql @@ -24,6 +24,8 @@ create table if not exists users primary key ("userId") ); +alter table users add column if not exists "sendNotifications" bool default true; + create index if not exists users_geog_idx on users using gist(geog); create table if not exists posts diff --git a/locales/all/en.po b/locales/all/en.po index 6dfca27c..08a9a9cf 100644 --- a/locales/all/en.po +++ b/locales/all/en.po @@ -103,3 +103,9 @@ msgstr "🚫 At least 5 lines please (you have %d)" msgid "main.welcome_link" msgstr "https://telegra.ph/LibreTaxi-20---you-will-love-it-02-02" + +msgid "mute_menu.ok" +msgstr "👌 Okay, I won't send you any more notifications. You can turn notifications back on at any time with the /unmute command" + +msgid "unmute_menu.ok" +msgstr "👌 Now I will send new notifications. To stop receiving notifications, enter the command /mute" diff --git a/locales/all/es.po b/locales/all/es.po index eb995c9b..c610066e 100644 --- a/locales/all/es.po +++ b/locales/all/es.po @@ -100,3 +100,9 @@ msgstr "🚫 Al menos 5 líneas por favor (tienes %d)" msgid "main.welcome_link" msgstr "https://telegra.ph/LibreTaxi-20---te-va-a-enamorar-02-09" + +msgid "mute_menu.ok" +msgstr "👌 Vale, no enviaré ninguna notificación nueva. Puedes volver a activar las notificaciones en cualquier momento usando el comando /unmute" + +msgid "unmute_menu.ok" +msgstr "👌 Ahora enviaré nuevas notificaciones. Para dejar de recibir notificaciones, escriba /mute" diff --git a/locales/all/fa.po b/locales/all/fa.po index a8492908..5cc2e5c1 100644 --- a/locales/all/fa.po +++ b/locales/all/fa.po @@ -100,3 +100,9 @@ msgstr "🚫 At least 5 lines please (you have %d)" msgid "main.welcome_link" msgstr "https://telegra.ph/LibreTaxi-20---you-will-love-it-02-02" + +msgid "mute_menu.ok" +msgstr "👌 Okay, I won't send you any more notifications. You can turn notifications back on at any time with the /unmute command" + +msgid "unmute_menu.ok" +msgstr "👌 Now I will send new notifications. To stop receiving notifications, enter the command /mute" diff --git a/locales/all/pt-br.po b/locales/all/pt-br.po index 43d9eba1..b4691d44 100644 --- a/locales/all/pt-br.po +++ b/locales/all/pt-br.po @@ -100,3 +100,9 @@ msgstr "🚫 Minimo 5 linhas por favor (tem %d)" msgid "main.welcome_link" msgstr "https://telegra.ph/LibreTaxi-20---Vai-o-amar-02-12" + +msgid "mute_menu.ok" +msgstr "👌 Ok, não enviarei novas notificações. Você pode reativar as notificações a qualquer momento usando o comando /unmute" + +msgid "unmute_menu.ok" +msgstr "👌 Agora enviarei novas notificações. Para parar de receber notificações, digite /mute" diff --git a/locales/all/pt-pt.po b/locales/all/pt-pt.po index f8b67f03..11ba8a47 100644 --- a/locales/all/pt-pt.po +++ b/locales/all/pt-pt.po @@ -100,3 +100,9 @@ msgstr "🚫 Minimo 5 linhas por favor (tem %d)" msgid "main.welcome_link" msgstr "https://telegra.ph/LibreTaxi-20---Vai-o-amar-02-12" + +msgid "mute_menu.ok" +msgstr "👌 Ok, não vou enviar novas notificações. Pode reativar as notificações a qualquer momento, utilizando o comando /unmute" + +msgid "unmute_menu.ok" +msgstr "👌 Agora enviarei novas notificações. Para deixar de receber notificações, digite /mute" diff --git a/locales/all/ru.po b/locales/all/ru.po index 961b7c14..75cfd037 100644 --- a/locales/all/ru.po +++ b/locales/all/ru.po @@ -103,3 +103,9 @@ msgstr "🚫 Надо хотя бы пять строк (у вас %d)" msgid "main.welcome_link" msgstr "https://telegra.ph/Novaya-versiya-Libre-taksi-vam-ponravitsya-02-08" + +msgid "mute_menu.ok" +msgstr "👌 Хорошо, я не буду присылать новые уведомления. Вы в любой момент можете обратно включить уведомления командой /unmute" + +msgid "unmute_menu.ok" +msgstr "👌 Теперь я буду присылать новые уведомления. Чтобы не получать уведомления, введите команду /mute" diff --git a/menu/menu.go b/menu/menu.go index 7cdc6aa4..bf5bfe4a 100644 --- a/menu/menu.go +++ b/menu/menu.go @@ -43,15 +43,15 @@ func HandleMessage(context *context.Context, userId int64, message *tgbotapi.Mes // Init user if it's not present if user == nil { user = &objects.User{ - UserId: userId, - MenuId: objects.Menu_Init, - ReportCnt: 0, + UserId: userId, + MenuId: objects.Menu_Init, + ReportCnt: 0, ShadowBanned: false, } } // Save recent user information - if message.From != nil { + if message.From != nil { user.Username = message.From.UserName user.FirstName = message.From.FirstName @@ -77,6 +77,18 @@ func HandleMessage(context *context.Context, userId int64, message *tgbotapi.Mes context.Repo.SaveUser(user) } + if message.Text == "/mute" { + user.MenuId = objects.Menu_Mute + message.Text = "" + context.Repo.SaveUser(user) + } + + if message.Text == "/unmute" { + user.MenuId = objects.Menu_Unmute + message.Text = "" + context.Repo.SaveUser(user) + } + fmt.Println(user.LanguageCode) previousState = user.MenuId @@ -91,6 +103,10 @@ func HandleMessage(context *context.Context, userId int64, message *tgbotapi.Mes handler = NewFeedMenu() case objects.Menu_Post: handler = NewPostMenu() + case objects.Menu_Mute: + handler = NewMuteMenu() + case objects.Menu_Unmute: + handler = NewUnmuteMenu() default: handler = nil } @@ -105,4 +121,4 @@ func HandleMessage(context *context.Context, userId int64, message *tgbotapi.Mes // Otherwise it can go into infinite loop. message = &tgbotapi.Message{} } -} \ No newline at end of file +} diff --git a/menu/mute_menu.go b/menu/mute_menu.go new file mode 100644 index 00000000..b6a7d50b --- /dev/null +++ b/menu/mute_menu.go @@ -0,0 +1,23 @@ +package menu + +import ( + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" + "libretaxi/context" + "libretaxi/objects" +) + +type MuteMenuHandler struct { +} + +func (handler *MuteMenuHandler) Handle(user *objects.User, context *context.Context, message *tgbotapi.Message) { + user.SendNotifications = false + context.Repo.SaveUser(user) + + msg := tgbotapi.NewMessage(message.Chat.ID, user.Locale().Get("mute_menu.ok")) + context.Send(msg) +} + +func NewMuteMenu() *MuteMenuHandler { + handler := &MuteMenuHandler{} + return handler +} diff --git a/menu/unmute_menu.go b/menu/unmute_menu.go new file mode 100644 index 00000000..56d31d44 --- /dev/null +++ b/menu/unmute_menu.go @@ -0,0 +1,23 @@ +package menu + +import ( + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" + "libretaxi/context" + "libretaxi/objects" +) + +type UnmuteMenuHandler struct { +} + +func (handler *UnmuteMenuHandler) Handle(user *objects.User, context *context.Context, message *tgbotapi.Message) { + user.SendNotifications = true + context.Repo.SaveUser(user) + + msg := tgbotapi.NewMessage(message.Chat.ID, user.Locale().Get("unmute_menu.ok")) + context.Send(msg) +} + +func NewUnmuteMenu() *UnmuteMenuHandler { + handler := &UnmuteMenuHandler{} + return handler +} diff --git a/objects/user.go b/objects/user.go index a1cdb0bc..4ff33669 100644 --- a/objects/user.go +++ b/objects/user.go @@ -9,21 +9,24 @@ const ( Menu_AskLocation MenuId = 200 Menu_Feed MenuId = 300 Menu_Post MenuId = 400 - Menu_Ban MenuId = 999999 + Menu_Mute MenuId = 500 + Menu_Unmute MenuId = 600 + Menu_Ban MenuId = 999999 ) type User struct { - UserId int64 - MenuId MenuId - Username string - FirstName string - LastName string - Lon float64 - Lat float64 - LanguageCode string - ReportCnt int - ShadowBanned bool - locale *gotext.Locale + UserId int64 + MenuId MenuId + Username string + FirstName string + LastName string + Lon float64 + Lat float64 + LanguageCode string + ReportCnt int + ShadowBanned bool + locale *gotext.Locale + SendNotifications bool } func (u *User) Locale() *gotext.Locale { @@ -38,4 +41,4 @@ func (u *User) Locale() *gotext.Locale { } } return u.locale -} \ No newline at end of file +} diff --git a/repository/repository.go b/repository/repository.go index f8726428..ed1d816f 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -13,8 +13,8 @@ type Repository struct { func (repo *Repository) FindUser(userId int64) *objects.User { user := &objects.User{} - err := repo.db.QueryRow(`select "userId", "menuId", "username", "firstName", "lastName", "lon", "lat", "languageCode", "reportCnt", "shadowBanned" from users where "userId" = $1 limit 1`, - userId).Scan(&user.UserId, &user.MenuId, &user.Username, &user.FirstName, &user.LastName, &user.Lon, &user.Lat, &user.LanguageCode, &user.ReportCnt, &user.ShadowBanned) + err := repo.db.QueryRow(`select "userId", "menuId", "username", "firstName", "lastName", "lon", "lat", "languageCode", "reportCnt", "shadowBanned", "sendNotifications" from users where "userId" = $1 limit 1`, + userId).Scan(&user.UserId, &user.MenuId, &user.Username, &user.FirstName, &user.LastName, &user.Lon, &user.Lat, &user.LanguageCode, &user.ReportCnt, &user.ShadowBanned, &user.SendNotifications) if err != nil { log.Println(err) @@ -27,8 +27,8 @@ func (repo *Repository) FindUser(userId int64) *objects.User { func (repo *Repository) SaveUser(user *objects.User) { // Upsert syntax: https://stackoverflow.com/questions/1109061/insert-on-duplicate-update-in-postgresql // Geo populate syntax: https://gis.stackexchange.com/questions/145007/creating-geometry-from-lat-lon-in-table-using-postgis/145009 - result, err := repo.db.Query(`INSERT INTO users ("userId", "menuId", "username", "firstName", "lastName", "lon", "lat", "geog", "languageCode", "reportCnt", "shadowBanned") - VALUES ($1, $2, $3, $4, $5, $6, $7, ST_SetSRID(ST_MakePoint($7, $6), 4326), $8, $9, $10) + result, err := repo.db.Query(`INSERT INTO users ("userId", "menuId", "username", "firstName", "lastName", "lon", "lat", "geog", "languageCode", "reportCnt", "shadowBanned", "sendNotifications") + VALUES ($1, $2, $3, $4, $5, $6, $7, ST_SetSRID(ST_MakePoint($7, $6), 4326), $8, $9, $10, $11) ON CONFLICT ("userId") DO UPDATE SET "menuId" = $2, "username" = $3, @@ -39,8 +39,9 @@ func (repo *Repository) SaveUser(user *objects.User) { "languageCode" = $8, "reportCnt" = $9, "shadowBanned" = $10, - "geog" = ST_SetSRID(ST_MakePoint($6, $7), 4326) - `, user.UserId, user.MenuId, user.Username, user.FirstName, user.LastName, user.Lon, user.Lat, user.LanguageCode, user.ReportCnt, user.ShadowBanned) + "geog" = ST_SetSRID(ST_MakePoint($6, $7), 4326), + "sendNotifications" = $11 + `, user.UserId, user.MenuId, user.Username, user.FirstName, user.LastName, user.Lon, user.Lat, user.LanguageCode, user.ReportCnt, user.ShadowBanned, user.SendNotifications) defer result.Close() if err != nil { @@ -86,7 +87,7 @@ func (repo *Repository) SavePost(post *objects.Post) { func (repo *Repository) UserIdsAround(lon float64, lat float64) (userIds []int64) { // select "userId", ST_Distance(c.x, "geog") AS distance from users, (SELECT ST_MakePoint(-122.415561, 37.633141)::geography) as c(x) where ST_DWithin(c.x, "geog", 25000) - result, err := repo.db.Query(`select "userId" from users, (SELECT ST_MakePoint($1, $2)::geography) as c(x) where ST_DWithin(c.x, "geog", 25000)`, + result, err := repo.db.Query(`select "userId" from users, (SELECT ST_MakePoint($1, $2)::geography) as c(x) where ST_DWithin(c.x, "geog", 25000) and "sendNotifications" = true`, lon, lat) defer result.Close() @@ -127,7 +128,7 @@ func (repo *Repository) ShowCallout(userId int64, featureName string) bool { } func (repo *Repository) DismissCallout(userId int64, featureName string) { - _, err := repo.db.Exec(`insert into dismissed_feature_callouts ("userId", "featureName") values ($1, $2) on conflict ("userId", "featureName") do nothing`, userId, featureName); + _, err := repo.db.Exec(`insert into dismissed_feature_callouts ("userId", "featureName") values ($1, $2) on conflict ("userId", "featureName") do nothing`, userId, featureName) if err != nil { log.Printf("Error while dismissing feature callout %s for user %d: %s", featureName, userId) log.Println(err) @@ -137,4 +138,4 @@ func (repo *Repository) DismissCallout(userId int64, featureName string) { func NewRepository(db *sql.DB) *Repository { repo := &Repository{db: db} return repo -} \ No newline at end of file +}