From e0e1ff528da6ec923688534eb931130327b07bbf Mon Sep 17 00:00:00 2001 From: koalasat Date: Sat, 12 Jul 2025 11:18:37 +0200 Subject: [PATCH] Robot garage in mobile navbar --- frontend/src/basic/NavBar/AppBar/index.tsx | 80 ++++++++++++++++++++-- frontend/src/basic/RobotPage/index.tsx | 4 +- frontend/src/models/Garage.model.ts | 55 ++++++++------- frontend/static/locales/ca.json | 2 +- frontend/static/locales/cs.json | 2 +- frontend/static/locales/de.json | 2 +- frontend/static/locales/en.json | 2 +- frontend/static/locales/es.json | 2 +- frontend/static/locales/eu.json | 2 +- frontend/static/locales/fr.json | 2 +- frontend/static/locales/it.json | 2 +- frontend/static/locales/ja.json | 2 +- frontend/static/locales/pl.json | 2 +- frontend/static/locales/pt.json | 2 +- frontend/static/locales/ru.json | 2 +- frontend/static/locales/sv.json | 2 +- frontend/static/locales/sw.json | 2 +- frontend/static/locales/th.json | 2 +- frontend/static/locales/zh-SI.json | 2 +- frontend/static/locales/zh-TR.json | 2 +- 20 files changed, 122 insertions(+), 51 deletions(-) diff --git a/frontend/src/basic/NavBar/AppBar/index.tsx b/frontend/src/basic/NavBar/AppBar/index.tsx index 9a9eb27a..4d2dcd04 100644 --- a/frontend/src/basic/NavBar/AppBar/index.tsx +++ b/frontend/src/basic/NavBar/AppBar/index.tsx @@ -14,12 +14,15 @@ import { useTheme, Fab, Button, + Collapse, } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { Add, Assignment, BubbleChart, + ExpandLess, + ExpandMore, Info, Menu as MenuIcon, People, @@ -34,6 +37,8 @@ import { Page } from '..'; import RobotAvatar from '../../../components/RobotAvatar'; import { AppContext, closeAll, UseAppStoreType } from '../../../contexts/AppContext'; import { RoboSatsTextIcon } from '../../../components/Icons'; +import { genBase62Token } from '../../../utils'; +import { UseFederationStoreType, FederationContext } from '../../../contexts/FederationContext'; interface AppBarProps { changePage: (newPage: Page) => void; @@ -44,7 +49,9 @@ const AppBar = ({ changePage }: AppBarProps): React.JSX.Element => { const theme = useTheme(); const { garage } = useContext(GarageContext); const { open, setOpen, page } = useContext(AppContext); + const { federation } = useContext(FederationContext); const [show, setShow] = useState(false); + const [openGarage, setOpenGarage] = useState(false); const slot = garage.getSlot(); @@ -53,6 +60,11 @@ const AppBar = ({ changePage }: AppBarProps): React.JSX.Element => { changePage(newPage); }; + const handleAddRobot = (): void => { + const token = genBase62Token(36); + void garage.createRobot(federation, token, Object.keys(garage.slots).length > 0); + }; + return ( @@ -112,27 +124,87 @@ const AppBar = ({ changePage }: AppBarProps): React.JSX.Element => { setShow(false)}> - + {slot?.hashId ? ( <> { setOpen({ ...closeAll, profile: !open.profile }); }} > - + + + + + setOpenGarage((op) => !op)} + sx={{ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + pl: 0, + }} + > {slot?.nickname} + {openGarage ? : } - + + + {Object.values(garage.slots).map((garageSlot, index) => { + if (garageSlot.token === slot.token) return
; + + return ( + + { + garage.setCurrentSlot(garageSlot.token ?? ''); + setOpenGarage(false); + setTimeout(() => setShow(false), 300); + }} + > + + + + + {garageSlot?.nickname} + + + + ); + })} + + +
+ {t('Add Robot')} + + + + ) : ( - <> + + + +
+ {t('Add Robot')} + + + )} + { diff --git a/frontend/src/basic/RobotPage/index.tsx b/frontend/src/basic/RobotPage/index.tsx index 033f811c..2988bca3 100644 --- a/frontend/src/basic/RobotPage/index.tsx +++ b/frontend/src/basic/RobotPage/index.tsx @@ -22,7 +22,7 @@ import RecoveryDialog from '../../components/Dialogs/Recovery'; const RobotPage = (): React.JSX.Element => { const { torStatus, windowSize, settings, page, client } = useContext(AppContext); - const { garage } = useContext(GarageContext); + const { garage, slotUpdatedAt } = useContext(GarageContext); const { t } = useTranslation(); const params = useParams(); const urlToken = settings.selfhostedClient ? params.token : null; @@ -43,7 +43,7 @@ const RobotPage = (): React.JSX.Element => { setView('profile'); } } - }, [torStatus, page]); + }, [torStatus, page, slotUpdatedAt]); if (settings.useProxy && client === 'mobile' && !(torStatus === 'ON')) { return ( diff --git a/frontend/src/models/Garage.model.ts b/frontend/src/models/Garage.model.ts index 01f78d15..edf5a738 100644 --- a/frontend/src/models/Garage.model.ts +++ b/frontend/src/models/Garage.model.ts @@ -129,37 +129,36 @@ class Garage { }; // Robots - createRobot: (federation: Federation, token: string) => Promise = async ( - federation, - token, - ) => { - if (!token) return; + createRobot: (federation: Federation, token: string, skipSelect?: boolean) => Promise = + async (federation, token, skipSelect) => { + if (!token) return; - if (this.getSlot(token) === null) { - try { - const key = await genKey(token); - const robotAttributes = { - token, - pubKey: key.publicKeyArmored, - encPrivKey: key.encryptedPrivateKeyArmored, - }; + if (this.getSlot(token) === null) { + try { + const key = await genKey(token); + const robotAttributes = { + token, + pubKey: key.publicKeyArmored, + encPrivKey: key.encryptedPrivateKeyArmored, + }; - this.setCurrentSlot(token); - this.slots[token] = new Slot( - token, - federation.getCoordinatorsAlias(), - robotAttributes, - () => { - this.triggerHook('onSlotUpdate'); - }, - ); - void this.fetchRobot(federation, token); - this.save(); - } catch (error) { - console.error('Error:', error); + if (!skipSelect) this.setCurrentSlot(token); + + this.slots[token] = new Slot( + token, + federation.getCoordinatorsAlias(), + robotAttributes, + () => { + this.triggerHook('onSlotUpdate'); + }, + ); + void this.fetchRobot(federation, token); + this.save(); + } catch (error) { + console.error('Error:', error); + } } - } - }; + }; fetchRobot = async (federation: Federation, token: string): Promise => { const slot = this.getSlot(token); diff --git a/frontend/static/locales/ca.json b/frontend/static/locales/ca.json index 3b197dd8..8a5d8d12 100644 --- a/frontend/static/locales/ca.json +++ b/frontend/static/locales/ca.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Existeixen ordres que coincideixen!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Un Simple i Privat Exchange LN P2P", + "Add Robot": "Afegir Robot", "Client info": "Client info", "Community": "Comunitat", "Exchange summary": "Resum de l'intercanvi", @@ -55,7 +56,6 @@ "roll again": "rodar de nou", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Ordre activa #{{orderID}}", - "Add Robot": "Afegir Robot", "Building...": "Construint...", "Delete Robot": "Delete Robot", "Last order #{{orderID}}": "Última ordre #{{orderID}}", diff --git a/frontend/static/locales/cs.json b/frontend/static/locales/cs.json index 10a065b1..7b4bbadb 100644 --- a/frontend/static/locales/cs.json +++ b/frontend/static/locales/cs.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Existující objednávky odpovídají vaší!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Jednoduchá a soukromá LN P2P burza", + "Add Robot": "Přidat robota", "Client info": "Client info", "Community": "Komunita", "Exchange summary": "Shrnutí směny", @@ -55,7 +56,6 @@ "roll again": "házet znovu", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Aktivní objednávka #{{orderID}}", - "Add Robot": "Přidat robota", "Building...": "Budování...", "Delete Robot": "Smazat robota", "Last order #{{orderID}}": "Poslední objednávka #{{orderID}}", diff --git a/frontend/static/locales/de.json b/frontend/static/locales/de.json index dcf3acd6..66fa9a9e 100644 --- a/frontend/static/locales/de.json +++ b/frontend/static/locales/de.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Bestehende Bestellungen passen zu deiner!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Ein einfacher und privater LN P2P-Börse", + "Add Robot": "Roboter hinzufügen", "Client info": "Client info", "Community": "Gemeinschaft", "Exchange summary": "Börsenzusammenfassung", @@ -55,7 +56,6 @@ "roll again": "noch einmal würfeln", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Aktive Bestellung #{{orderID}}", - "Add Robot": "Roboter hinzufügen", "Building...": "Erstelle...", "Delete Robot": "Roboter löschen", "Last order #{{orderID}}": "Letzte Bestellung #{{orderID}}", diff --git a/frontend/static/locales/en.json b/frontend/static/locales/en.json index 2eb0416f..18033f45 100644 --- a/frontend/static/locales/en.json +++ b/frontend/static/locales/en.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Existing orders match yours!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "A Simple and Private LN P2P Exchange", + "Add Robot": "Add Robot", "Client info": "Client info", "Community": "Community", "Exchange summary": "Exchange summary", @@ -55,7 +56,6 @@ "roll again": "roll again", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Active order #{{orderID}}", - "Add Robot": "Add Robot", "Building...": "Building...", "Delete Robot": "Delete Robot", "Last order #{{orderID}}": "Last order #{{orderID}}", diff --git a/frontend/static/locales/es.json b/frontend/static/locales/es.json index 2d544d10..9137de70 100644 --- a/frontend/static/locales/es.json +++ b/frontend/static/locales/es.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "¡Existen órdenes que coinciden!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Un exchange LN P2P sencillo y privado", + "Add Robot": "Añadir Robot", "Client info": "Client info", "Community": "Comunidad", "Exchange summary": "Resumen del intercambio", @@ -55,7 +56,6 @@ "roll again": "Tira otra vez", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Orden activa #{{orderID}}", - "Add Robot": "Añadir Robot", "Building...": "Construyendo...", "Delete Robot": "Eliminar Robot", "Last order #{{orderID}}": "Última orden #{{orderID}}", diff --git a/frontend/static/locales/eu.json b/frontend/static/locales/eu.json index 65bfa0c1..5d4818e2 100644 --- a/frontend/static/locales/eu.json +++ b/frontend/static/locales/eu.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Dauden eskaerak zureekin bat datoz!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "LN P2P Truke Sinple eta Pribatua", + "Add Robot": "Gehitu Robota", "Client info": "Client info", "Community": "Komunitatea", "Exchange summary": "Truke-laburpena", @@ -55,7 +56,6 @@ "roll again": "berriz bota", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Eskaera aktiboa #{{orderID}}", - "Add Robot": "Gehitu Robota", "Building...": "Eraikitzen...", "Delete Robot": "Ezabatu Robota", "Last order #{{orderID}}": "Azken eskaera #{{orderID}}", diff --git a/frontend/static/locales/fr.json b/frontend/static/locales/fr.json index 89693e39..a94a89ed 100644 --- a/frontend/static/locales/fr.json +++ b/frontend/static/locales/fr.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Commandes existantes correspondent aux vôtres !", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Une bourse d'échange P2P LN simple et privée", + "Add Robot": "Ajouter un robot", "Client info": "Client info", "Community": "Communauté", "Exchange summary": "Résumé de l'échange", @@ -55,7 +56,6 @@ "roll again": "recommencer", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Ordre actif #{{orderID}}", - "Add Robot": "Ajouter un robot", "Building...": "Construction...", "Delete Robot": "Supprimer le robot", "Last order #{{orderID}}": "Dernier ordre #{{orderID}}", diff --git a/frontend/static/locales/it.json b/frontend/static/locales/it.json index 01abc219..0836f914 100644 --- a/frontend/static/locales/it.json +++ b/frontend/static/locales/it.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Gli ordini esistenti si abbinano ai tuoi!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Una piattaforma di scambio P2P su LN semplice e privata", + "Add Robot": "Aggiungi robot", "Client info": "Client info", "Community": "Comunità", "Exchange summary": "Riepilogo dell'exchange", @@ -55,7 +56,6 @@ "roll again": "tira di nuovo", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Ordine attivo #{{orderID}}", - "Add Robot": "Aggiungi robot", "Building...": "Costruzione...", "Delete Robot": "Elimina robot", "Last order #{{orderID}}": "Ultimo ordine #{{orderID}}", diff --git a/frontend/static/locales/ja.json b/frontend/static/locales/ja.json index 3adccd6e..760621fd 100644 --- a/frontend/static/locales/ja.json +++ b/frontend/static/locales/ja.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "あなたの注文にマッチする既存の注文があります!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "シンプルでプライベートなライトニングP2P取引所", + "Add Robot": "ロボットを追加", "Client info": "Client info", "Community": "コミュニティ", "Exchange summary": "取引所の概要", @@ -55,7 +56,6 @@ "roll again": "もう一度生成する。", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "公開中の注文 #{{orderID}}", - "Add Robot": "ロボットを追加", "Building...": "生成中...", "Delete Robot": "ロボットを削除", "Last order #{{orderID}}": "直前の注文 #{{orderID}}", diff --git a/frontend/static/locales/pl.json b/frontend/static/locales/pl.json index e96ba6f8..bd0e99aa 100644 --- a/frontend/static/locales/pl.json +++ b/frontend/static/locales/pl.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Istniejące zlecenia pasują do twojego!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Prosta i prywatna wymiana LN P2P", + "Add Robot": "Dodaj Robota", "Client info": "Client info", "Community": "Społeczność", "Exchange summary": "Podsumowanie wymiany", @@ -55,7 +56,6 @@ "roll again": "przewróć ponownie", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Aktywne zamówienie #{{orderID}}", - "Add Robot": "Dodaj Robota", "Building...": "Budowanie...", "Delete Robot": "Usuń robota", "Last order #{{orderID}}": "Ostatnie zamówienie #{{orderID}}", diff --git a/frontend/static/locales/pt.json b/frontend/static/locales/pt.json index 82f8e842..26b86f75 100644 --- a/frontend/static/locales/pt.json +++ b/frontend/static/locales/pt.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Existem ordens correspondentes!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Uma Exchange P2P LN Simples e Privada", + "Add Robot": "Adicionar Robô", "Client info": "Client info", "Community": "Comunidade", "Exchange summary": "Resumo da Exchange", @@ -55,7 +56,6 @@ "roll again": "Girar novamente", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Ordem ativa #{{orderID}}", - "Add Robot": "Adicionar Robô", "Building...": "Criando...", "Delete Robot": "Deletar Robô", "Last order #{{orderID}}": "Última ordem #{{orderID}}", diff --git a/frontend/static/locales/ru.json b/frontend/static/locales/ru.json index c54269fd..a4a1a5ec 100644 --- a/frontend/static/locales/ru.json +++ b/frontend/static/locales/ru.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Существующие ордеры совпадают с вашими!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Простой и приватный LN P2P обменник", + "Add Robot": "Добавить робота", "Client info": "Client info", "Community": "Сообщество", "Exchange summary": "Сводка обмена", @@ -55,7 +56,6 @@ "roll again": "ещё раз", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Активный ордер #{{orderID}}", - "Add Robot": "Добавить робота", "Building...": "Строим...", "Delete Robot": "Удалить робота", "Last order #{{orderID}}": "Последний ордер #{{orderID}}", diff --git a/frontend/static/locales/sv.json b/frontend/static/locales/sv.json index 08336849..f99ddcff 100644 --- a/frontend/static/locales/sv.json +++ b/frontend/static/locales/sv.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Befintliga ordrar matchar dina!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "En enkel och privat LN P2P Exchange", + "Add Robot": "Lägg till robot", "Client info": "Client info", "Community": "Gemenskap", "Exchange summary": "Utbytesöversikt", @@ -55,7 +56,6 @@ "roll again": "slå igen", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Aktiv order #{{orderID}}", - "Add Robot": "Lägg till robot", "Building...": "Bygger...", "Delete Robot": "Radera robot", "Last order #{{orderID}}": "Senaste order #{{orderID}}", diff --git a/frontend/static/locales/sw.json b/frontend/static/locales/sw.json index 6039e6d3..dbd45c26 100644 --- a/frontend/static/locales/sw.json +++ b/frontend/static/locales/sw.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "Amri zilizopo zinafanana na yako!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "Kubadilishana LN P2P Rahisi na Binafsi", + "Add Robot": "Ongeza Roboti", "Client info": "Client info", "Community": "Jumuiya", "Exchange summary": "Muhtasari wa Ubadilishanaji", @@ -55,7 +56,6 @@ "roll again": "chezesha tena", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "Amri hai #{{orderID}}", - "Add Robot": "Ongeza Roboti", "Building...": "Inajengwa...", "Delete Robot": "Futa Roboti", "Last order #{{orderID}}": "Amri ya mwisho #{{orderID}}", diff --git a/frontend/static/locales/th.json b/frontend/static/locales/th.json index 3b1bda97..9c84f5ae 100644 --- a/frontend/static/locales/th.json +++ b/frontend/static/locales/th.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "มีคำสั่งซื้อที่ตรงกันกับของคุณ!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "การแลกเปลี่ยน LN P2P ที่เรียบง่ายและเป็นส่วนตัว", + "Add Robot": "เพิ่มหุ่นยนต์", "Client info": "Client info", "Community": "ชุมชน", "Exchange summary": "สรุปการแลกเปลี่ยน", @@ -55,7 +56,6 @@ "roll again": "สุ่มใหม่", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "รายการที่ใช้งาน #{{orderID}}", - "Add Robot": "เพิ่มหุ่นยนต์", "Building...": "กำลังสร้าง...", "Delete Robot": "ลบหุ่นยนต์", "Last order #{{orderID}}": "คำสั่งล่าสุด #{{orderID}}", diff --git a/frontend/static/locales/zh-SI.json b/frontend/static/locales/zh-SI.json index 8ca2ba8c..1ff34c94 100644 --- a/frontend/static/locales/zh-SI.json +++ b/frontend/static/locales/zh-SI.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "有与你的订单相匹配的现有订单!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "一个简单且隐秘的点对点闪电交易所", + "Add Robot": "添加机器人", "Client info": "Client info", "Community": "社区", "Exchange summary": "交易总结", @@ -55,7 +56,6 @@ "roll again": "再试一次", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "活跃订单 #{{orderID}}", - "Add Robot": "添加机器人", "Building...": "正在建造...", "Delete Robot": "删除机器人", "Last order #{{orderID}}": "上一张订单 #{{orderID}}", diff --git a/frontend/static/locales/zh-TR.json b/frontend/static/locales/zh-TR.json index 50a8b386..ac91d08a 100644 --- a/frontend/static/locales/zh-TR.json +++ b/frontend/static/locales/zh-TR.json @@ -17,6 +17,7 @@ "Existing orders match yours!": "有與你的訂單相匹配的現有訂單!", "#5": "Phrases in basic/NavBar/AppBar/index.tsx", "A Simple and Private LN P2P Exchange": "一個簡單且隱密的點對點閃電交易所", + "Add Robot": "添加機器人", "Client info": "Client info", "Community": "社群", "Exchange summary": "匯率總結", @@ -55,7 +56,6 @@ "roll again": "再擲一次", "#10": "Phrases in basic/RobotPage/RobotProfile.tsx", "Active order #{{orderID}}": "活躍訂單 #{{orderID}}", - "Add Robot": "添加機器人", "Building...": "正在建造...", "Delete Robot": "刪除機器人", "Last order #{{orderID}}": "上一張訂單 #{{orderID}}",