chore: build
This commit is contained in:
@@ -9,6 +9,18 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// sendTelegramNotif envoie via le bot principal, puis lbtelegram (BOT1/BOT2) en fallback.
|
||||||
|
func sendTelegramNotif(chatID int64, text string) {
|
||||||
|
if err := services.TelegramBot.SendMessage(chatID, text); err != nil {
|
||||||
|
log.Printf("⚠️ [NOTIF] bot principal échoué: %v — fallback lbtelegram", err)
|
||||||
|
if services.LBTelegram != nil && services.LBTelegram.IsConfigured() {
|
||||||
|
if err2 := services.LBTelegram.SendNotification(chatID, text); err2 != nil {
|
||||||
|
log.Printf("⚠️ [NOTIF] lbtelegram aussi échoué: %v", err2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Database) NotifyClient(username string, commandID int, notifType, message string) error {
|
func (d *Database) NotifyClient(username string, commandID int, notifType, message string) error {
|
||||||
notifKey := fmt.Sprintf("notifications:%s", username)
|
notifKey := fmt.Sprintf("notifications:%s", username)
|
||||||
|
|
||||||
@@ -26,11 +38,7 @@ func (d *Database) NotifyClient(username string, commandID int, notifType, messa
|
|||||||
|
|
||||||
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
|
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
|
||||||
if chatID, ok, err := d.GetClientTelegramChatID(username); err == nil && ok {
|
if chatID, ok, err := d.GetClientTelegramChatID(username); err == nil && ok {
|
||||||
go func(id int64, msg string) {
|
go sendTelegramNotif(chatID, fmt.Sprintf("🔔 <b>Notification</b>\n\n%s", message))
|
||||||
if err := services.TelegramBot.SendNotif(id, fmt.Sprintf("🔔 <b>Notification</b>\n\n%s", msg)); err != nil {
|
|
||||||
log.Printf("⚠️ [NOTIF] notification client échouée pour %s: %v", username, err)
|
|
||||||
}
|
|
||||||
}(chatID, message)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,11 +64,7 @@ func (d *Database) NotifyLivreur(username string, commandID int, notifType, mess
|
|||||||
|
|
||||||
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
|
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
|
||||||
if chatID, ok, err := d.GetUserTelegramChatID(username); err == nil && ok {
|
if chatID, ok, err := d.GetUserTelegramChatID(username); err == nil && ok {
|
||||||
go func(id int64, msg string) {
|
go sendTelegramNotif(chatID, fmt.Sprintf("🔔 <b>Notification</b>\n\n%s", message))
|
||||||
if err := services.TelegramBot.SendNotif(id, fmt.Sprintf("🔔 <b>Notification</b>\n\n%s", msg)); err != nil {
|
|
||||||
log.Printf("⚠️ [NOTIF] notification livreur échouée pour %s: %v", username, err)
|
|
||||||
}
|
|
||||||
}(chatID, message)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,12 +102,7 @@ func (d *Database) NotifyAllAdminCabine(commandID int, clientUsername, deliveryA
|
|||||||
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
|
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
|
||||||
if chatID, ok, err := d.GetUserTelegramChatID(u.Username); err == nil && ok {
|
if chatID, ok, err := d.GetUserTelegramChatID(u.Username); err == nil && ok {
|
||||||
capturedChatID := chatID
|
capturedChatID := chatID
|
||||||
capturedMsg := msg
|
go sendTelegramNotif(capturedChatID, fmt.Sprintf("🔔 <b>Nouvelle commande</b>\n\n%s", msg))
|
||||||
go func(id int64, m string) {
|
|
||||||
if err := services.TelegramBot.SendNotif(id, fmt.Sprintf("🔔 <b>Nouvelle commande</b>\n\n%s", m)); err != nil {
|
|
||||||
log.Printf("⚠️ [NOTIF] notification admin/cabine échouée: %v", err)
|
|
||||||
}
|
|
||||||
}(capturedChatID, capturedMsg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count++
|
count++
|
||||||
@@ -141,12 +140,7 @@ func (d *Database) NotifyAllAdminCabineAlert(alertID int, livreurUsername, alert
|
|||||||
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
|
if services.TelegramBot != nil && services.TelegramBot.IsNotificationsEnabled() {
|
||||||
if chatID, ok, err := d.GetUserTelegramChatID(u.Username); err == nil && ok {
|
if chatID, ok, err := d.GetUserTelegramChatID(u.Username); err == nil && ok {
|
||||||
capturedChatID := chatID
|
capturedChatID := chatID
|
||||||
capturedBody := body
|
go sendTelegramNotif(capturedChatID, fmt.Sprintf("🚨 <b>Alerte livreur</b>\n\n%s", body))
|
||||||
go func(id int64, m string) {
|
|
||||||
if err := services.TelegramBot.SendNotif(id, fmt.Sprintf("🚨 <b>Alerte livreur</b>\n\n%s", m)); err != nil {
|
|
||||||
log.Printf("⚠️ [NOTIF] notification alerte échouée: %v", err)
|
|
||||||
}
|
|
||||||
}(capturedChatID, capturedBody)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count++
|
count++
|
||||||
|
|||||||
@@ -154,11 +154,6 @@ func (d *Database) GetSettings() (models.AppSettings, error) {
|
|||||||
settings.TelegramBotUsername = row.Value
|
settings.TelegramBotUsername = row.Value
|
||||||
case "telegram_notifications_enabled":
|
case "telegram_notifications_enabled":
|
||||||
settings.TelegramNotificationsEnabled = row.Value == "true"
|
settings.TelegramNotificationsEnabled = row.Value == "true"
|
||||||
case "telegram_notif_bots":
|
|
||||||
var bots []models.TelegramBotConfig
|
|
||||||
if err := json.Unmarshal([]byte(row.Value), &bots); err == nil {
|
|
||||||
settings.TelegramNotifBots = bots
|
|
||||||
}
|
|
||||||
case "delivery_mode":
|
case "delivery_mode":
|
||||||
var mode models.DeliveryModeConfig
|
var mode models.DeliveryModeConfig
|
||||||
if err := json.Unmarshal([]byte(row.Value), &mode); err == nil {
|
if err := json.Unmarshal([]byte(row.Value), &mode); err == nil {
|
||||||
@@ -254,13 +249,6 @@ func (d *Database) UpdateSettings(s models.AppSettings) error {
|
|||||||
{"telegram_bot_token", s.TelegramBotToken},
|
{"telegram_bot_token", s.TelegramBotToken},
|
||||||
{"telegram_bot_username", s.TelegramBotUsername},
|
{"telegram_bot_username", s.TelegramBotUsername},
|
||||||
{"telegram_notifications_enabled", boolStr(s.TelegramNotificationsEnabled)},
|
{"telegram_notifications_enabled", boolStr(s.TelegramNotificationsEnabled)},
|
||||||
{"telegram_notif_bots", func() string {
|
|
||||||
if s.TelegramNotifBots == nil {
|
|
||||||
s.TelegramNotifBots = []models.TelegramBotConfig{}
|
|
||||||
}
|
|
||||||
b, _ := json.Marshal(s.TelegramNotifBots)
|
|
||||||
return string(b)
|
|
||||||
}()},
|
|
||||||
{"telegram_2fa_enabled", boolStr(s.Telegram2FAEnabled)},
|
{"telegram_2fa_enabled", boolStr(s.Telegram2FAEnabled)},
|
||||||
{"delivery_mode", string(deliveryModeJSON)},
|
{"delivery_mode", string(deliveryModeJSON)},
|
||||||
{"shop_name", s.ShopName},
|
{"shop_name", s.ShopName},
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ func UpdateSettings(c *gin.Context) {
|
|||||||
if services.TelegramBot != nil {
|
if services.TelegramBot != nil {
|
||||||
services.TelegramBot.Reload(req.TelegramBotToken, req.TelegramBotUsername)
|
services.TelegramBot.Reload(req.TelegramBotToken, req.TelegramBotUsername)
|
||||||
services.TelegramBot.SetNotificationsEnabled(req.TelegramNotificationsEnabled)
|
services.TelegramBot.SetNotificationsEnabled(req.TelegramNotificationsEnabled)
|
||||||
services.TelegramBot.ReloadNotifBots(req.TelegramNotifBots)
|
|
||||||
if req.TelegramBotToken != "" {
|
if req.TelegramBotToken != "" {
|
||||||
log.Printf("✅ [SETTINGS] Service Telegram rechargé (username: %s)", req.TelegramBotUsername)
|
log.Printf("✅ [SETTINGS] Service Telegram rechargé (username: %s)", req.TelegramBotUsername)
|
||||||
if webhookURL := os.Getenv("TELEGRAM_WEBHOOK_URL"); webhookURL != "" {
|
if webhookURL := os.Getenv("TELEGRAM_WEBHOOK_URL"); webhookURL != "" {
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ func main() {
|
|||||||
if dbSettings, err := database.GetSettings(); err == nil {
|
if dbSettings, err := database.GetSettings(); err == nil {
|
||||||
telegramService.Reload(dbSettings.TelegramBotToken, dbSettings.TelegramBotUsername)
|
telegramService.Reload(dbSettings.TelegramBotToken, dbSettings.TelegramBotUsername)
|
||||||
telegramService.SetNotificationsEnabled(dbSettings.TelegramNotificationsEnabled)
|
telegramService.SetNotificationsEnabled(dbSettings.TelegramNotificationsEnabled)
|
||||||
telegramService.ReloadNotifBots(dbSettings.TelegramNotifBots)
|
|
||||||
if dbSettings.TelegramBotToken != "" {
|
if dbSettings.TelegramBotToken != "" {
|
||||||
log.Printf("✅ [TELEGRAM] Config chargée depuis la DB (username: %s)", dbSettings.TelegramBotUsername)
|
log.Printf("✅ [TELEGRAM] Config chargée depuis la DB (username: %s)", dbSettings.TelegramBotUsername)
|
||||||
if webhookURL := os.Getenv("TELEGRAM_WEBHOOK_URL"); webhookURL != "" {
|
if webhookURL := os.Getenv("TELEGRAM_WEBHOOK_URL"); webhookURL != "" {
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
// TelegramBotConfig représente un bot de notification configuré par l'admin
|
|
||||||
type TelegramBotConfig struct {
|
|
||||||
Token string `json:"token"`
|
|
||||||
Username string `json:"username"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PostalZone struct {
|
type PostalZone struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
MinAmount float64 `json:"min_amount"`
|
MinAmount float64 `json:"min_amount"`
|
||||||
@@ -100,8 +94,7 @@ type AppSettings struct {
|
|||||||
PostalZones []PostalZone `json:"postal_zones"` // zones de livraison avec minimum de commande
|
PostalZones []PostalZone `json:"postal_zones"` // zones de livraison avec minimum de commande
|
||||||
TelegramBotToken string `json:"telegram_bot_token"` // token du bot Telegram (BotFather) — pour le webhook de liaison
|
TelegramBotToken string `json:"telegram_bot_token"` // token du bot Telegram (BotFather) — pour le webhook de liaison
|
||||||
TelegramBotUsername string `json:"telegram_bot_username"` // username du bot (sans @)
|
TelegramBotUsername string `json:"telegram_bot_username"` // username du bot (sans @)
|
||||||
TelegramNotificationsEnabled bool `json:"telegram_notifications_enabled"` // activer/désactiver les notifications Telegram
|
TelegramNotificationsEnabled bool `json:"telegram_notifications_enabled"` // activer/désactiver les notifications Telegram
|
||||||
TelegramNotifBots []TelegramBotConfig `json:"telegram_notif_bots"` // bots de notification avec failover automatique
|
|
||||||
DeliveryMode DeliveryModeConfig `json:"delivery_mode"` // mode d'assignation des livreurs
|
DeliveryMode DeliveryModeConfig `json:"delivery_mode"` // mode d'assignation des livreurs
|
||||||
ShopName string `json:"shop_name"` // nom affiché dans la sidebar du site client
|
ShopName string `json:"shop_name"` // nom affiché dans la sidebar du site client
|
||||||
Telegram2FAEnabled bool `json:"telegram_2fa_enabled"` // activer/désactiver l'authentification à deux facteurs
|
Telegram2FAEnabled bool `json:"telegram_2fa_enabled"` // activer/désactiver l'authentification à deux facteurs
|
||||||
|
|||||||
@@ -4,11 +4,9 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gestion/models"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,8 +17,6 @@ type TelegramService struct {
|
|||||||
webhookSecret string
|
webhookSecret string
|
||||||
BotUsername string
|
BotUsername string
|
||||||
notificationsEnabled bool
|
notificationsEnabled bool
|
||||||
notifBots []models.TelegramBotConfig
|
|
||||||
notifMu sync.RWMutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTelegramService() *TelegramService {
|
func NewTelegramService() *TelegramService {
|
||||||
@@ -45,71 +41,6 @@ func (t *TelegramService) SetNotificationsEnabled(enabled bool) {
|
|||||||
t.notificationsEnabled = enabled
|
t.notificationsEnabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReloadNotifBots met à jour la liste des bots de notification (thread-safe).
|
|
||||||
func (t *TelegramService) ReloadNotifBots(bots []models.TelegramBotConfig) {
|
|
||||||
t.notifMu.Lock()
|
|
||||||
defer t.notifMu.Unlock()
|
|
||||||
t.notifBots = bots
|
|
||||||
log.Printf("✅ [TELEGRAM] %d bot(s) de notification chargé(s)", len(bots))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendNotif envoie un message HTML en essayant chaque bot de notification dans l'ordre.
|
|
||||||
// En cas de rate-limit (429) ou d'erreur sur le bot courant, il passe au suivant.
|
|
||||||
func (t *TelegramService) SendNotif(chatID int64, text string) error {
|
|
||||||
t.notifMu.RLock()
|
|
||||||
bots := make([]models.TelegramBotConfig, len(t.notifBots))
|
|
||||||
copy(bots, t.notifBots)
|
|
||||||
t.notifMu.RUnlock()
|
|
||||||
|
|
||||||
if len(bots) == 0 {
|
|
||||||
// Fallback : utiliser le bot webhook principal
|
|
||||||
return t.SendMessage(chatID, text)
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastErr error
|
|
||||||
for i, bot := range bots {
|
|
||||||
if err := t.sendWithToken(bot.Token, chatID, text); err != nil {
|
|
||||||
log.Printf("⚠️ [TELEGRAM] bot %d (%s) échoué: %v — essai suivant", i+1, bot.Username, err)
|
|
||||||
lastErr = err
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("tous les bots de notification ont échoué: %w", lastErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// sendWithToken envoie un message HTML avec un token arbitraire.
|
|
||||||
func (t *TelegramService) sendWithToken(token string, chatID int64, text string) error {
|
|
||||||
payload := map[string]interface{}{
|
|
||||||
"chat_id": chatID,
|
|
||||||
"text": text,
|
|
||||||
"parse_mode": "HTML",
|
|
||||||
}
|
|
||||||
body, err := json.Marshal(payload)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("marshal: %w", err)
|
|
||||||
}
|
|
||||||
url := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", token)
|
|
||||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("création requête: %w", err)
|
|
||||||
}
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
client := &http.Client{Timeout: 10 * time.Second}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("envoi: %w", err)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
if resp.StatusCode == http.StatusTooManyRequests {
|
|
||||||
return fmt.Errorf("rate limit (429)")
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return fmt.Errorf("status %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reload met à jour le token et le username (appelé après UpdateSettings)
|
// Reload met à jour le token et le username (appelé après UpdateSettings)
|
||||||
func (t *TelegramService) Reload(token, username string) {
|
func (t *TelegramService) Reload(token, username string) {
|
||||||
if token != "" {
|
if token != "" {
|
||||||
|
|||||||
@@ -1050,17 +1050,11 @@ export interface AppSettings {
|
|||||||
telegram_bot_username: string;
|
telegram_bot_username: string;
|
||||||
telegram_notifications_enabled: boolean;
|
telegram_notifications_enabled: boolean;
|
||||||
telegram_2fa_enabled: boolean;
|
telegram_2fa_enabled: boolean;
|
||||||
telegram_notif_bots: TelegramBotConfig[];
|
|
||||||
delivery_mode: DeliveryModeConfig;
|
delivery_mode: DeliveryModeConfig;
|
||||||
shop_name: string;
|
shop_name: string;
|
||||||
contact_telegram: string;
|
contact_telegram: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TelegramBotConfig = {
|
|
||||||
token: string;
|
|
||||||
username: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getSettings = async (): Promise<{
|
export const getSettings = async (): Promise<{
|
||||||
success: boolean;
|
success: boolean;
|
||||||
settings?: AppSettings;
|
settings?: AppSettings;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { Ionicons } from "@expo/vector-icons";
|
|||||||
import { spacing, fontSize, borderRadius } from "../../theme";
|
import { spacing, fontSize, borderRadius } from "../../theme";
|
||||||
import { useTheme } from "../../context/ThemeContext";
|
import { useTheme } from "../../context/ThemeContext";
|
||||||
import { getSettings, updateSettings, getCategories, getAvailableDeliveryPersons, getAllProductsAdmin, DEFAULT_DELIVERY_SCHEDULE, DEFAULT_POSTAL_ZONES } from "../../api/api_admin";
|
import { getSettings, updateSettings, getCategories, getAvailableDeliveryPersons, getAllProductsAdmin, DEFAULT_DELIVERY_SCHEDULE, DEFAULT_POSTAL_ZONES } from "../../api/api_admin";
|
||||||
import type { AppSettings, Category, CategoryRoute, DeliveryModeConfig, PointsTier, PointsPool, PointsReward, RewardCategoryConfig, DaySchedule, DeliverySchedule, PostalZone, TelegramBotConfig } from "../../api/api_admin";
|
import type { AppSettings, Category, CategoryRoute, DeliveryModeConfig, PointsTier, PointsPool, PointsReward, RewardCategoryConfig, DaySchedule, DeliverySchedule, PostalZone } from "../../api/api_admin";
|
||||||
import type { Product } from "../../api/types";
|
import type { Product } from "../../api/types";
|
||||||
import AlertModal from "../../components/ui/AlertModal";
|
import AlertModal from "../../components/ui/AlertModal";
|
||||||
import { useAlert } from "../../hooks/useAlert";
|
import { useAlert } from "../../hooks/useAlert";
|
||||||
@@ -1032,7 +1032,6 @@ export default function SettingsScreen() {
|
|||||||
telegram_bot_username: "",
|
telegram_bot_username: "",
|
||||||
telegram_notifications_enabled: false,
|
telegram_notifications_enabled: false,
|
||||||
telegram_2fa_enabled: false,
|
telegram_2fa_enabled: false,
|
||||||
telegram_notif_bots: [],
|
|
||||||
delivery_mode: { mode: "single" as const, category_routes: [] },
|
delivery_mode: { mode: "single" as const, category_routes: [] },
|
||||||
shop_name: "Milieu-Nantais",
|
shop_name: "Milieu-Nantais",
|
||||||
contact_telegram: "",
|
contact_telegram: "",
|
||||||
@@ -1905,66 +1904,6 @@ export default function SettingsScreen() {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Bots de notification (failover) */}
|
|
||||||
<View style={{ paddingHorizontal: spacing.l, paddingTop: spacing.l }}>
|
|
||||||
<Text style={[s.rowLabel, { marginBottom: spacing.xs }]}>Bots de notification (failover)</Text>
|
|
||||||
<Text style={[s.hint, { marginBottom: spacing.m }]}>
|
|
||||||
Les notifications sont envoyées par le premier bot. En cas de rate-limit ou d'erreur, le suivant prend le relais.
|
|
||||||
Si aucun bot n'est configuré ici, le bot principal est utilisé.
|
|
||||||
</Text>
|
|
||||||
{(settings.telegram_notif_bots ?? []).map((bot, idx) => (
|
|
||||||
<View key={idx} style={{ flexDirection: "row", gap: spacing.s, marginBottom: spacing.s, alignItems: "flex-start" }}>
|
|
||||||
<View style={{ flex: 1, gap: spacing.xs }}>
|
|
||||||
<TextInput
|
|
||||||
style={[s.input, { marginBottom: 0 }]}
|
|
||||||
placeholder={`Token bot ${idx + 1}`}
|
|
||||||
placeholderTextColor={colors.textSecondary}
|
|
||||||
value={bot.token}
|
|
||||||
onChangeText={(v) => setSettings((p) => {
|
|
||||||
const bots = [...(p.telegram_notif_bots ?? [])];
|
|
||||||
bots[idx] = { ...bots[idx], token: v };
|
|
||||||
return { ...p, telegram_notif_bots: bots };
|
|
||||||
})}
|
|
||||||
autoCapitalize="none"
|
|
||||||
autoCorrect={false}
|
|
||||||
secureTextEntry
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
style={[s.input, { marginBottom: 0 }]}
|
|
||||||
placeholder={`@username bot ${idx + 1}`}
|
|
||||||
placeholderTextColor={colors.textSecondary}
|
|
||||||
value={bot.username}
|
|
||||||
onChangeText={(v) => setSettings((p) => {
|
|
||||||
const bots = [...(p.telegram_notif_bots ?? [])];
|
|
||||||
bots[idx] = { ...bots[idx], username: v };
|
|
||||||
return { ...p, telegram_notif_bots: bots };
|
|
||||||
})}
|
|
||||||
autoCapitalize="none"
|
|
||||||
autoCorrect={false}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={() => setSettings((p) => ({
|
|
||||||
...p,
|
|
||||||
telegram_notif_bots: (p.telegram_notif_bots ?? []).filter((_, i) => i !== idx),
|
|
||||||
}))}
|
|
||||||
style={{ padding: spacing.s, marginTop: spacing.xs }}
|
|
||||||
>
|
|
||||||
<Ionicons name="trash-outline" size={20} color={colors.danger} />
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
))}
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={() => setSettings((p) => ({
|
|
||||||
...p,
|
|
||||||
telegram_notif_bots: [...(p.telegram_notif_bots ?? []), { token: "", username: "" }],
|
|
||||||
}))}
|
|
||||||
style={{ flexDirection: "row", alignItems: "center", gap: spacing.s, paddingVertical: spacing.s }}
|
|
||||||
>
|
|
||||||
<Ionicons name="add-circle-outline" size={20} color={colors.accent} />
|
|
||||||
<Text style={{ color: colors.accent, fontSize: fontSize.sm }}>Ajouter un bot de notification</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user