mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-13 19:06:26 +00:00
Add notification for new in-app chat messages (#403)
* Add TG message for new in-app chat messages * Add emojis and collect phrases
This commit is contained in:
parent
f4ae80c593
commit
399f8102f2
@ -56,6 +56,8 @@ ALTERNATIVE_NAME = 'RoboSats Mainnet'
|
||||
# Telegram bot token
|
||||
TELEGRAM_TOKEN = ''
|
||||
TELEGRAM_BOT_NAME = ''
|
||||
# Notify new messages in-chat app (fiat exchange step) if at least X minutes has passed since the last chat message.
|
||||
CHAT_NOTIFICATION_TIMEGAP = 5
|
||||
|
||||
# Lightning node open info, url to amboss and 1ML
|
||||
NETWORK = 'testnet'
|
||||
|
@ -9,7 +9,7 @@ from django.utils import timezone
|
||||
|
||||
from api.lightning.node import LNNode
|
||||
from api.models import Currency, LNPayment, MarketTick, OnchainPayment, Order, User
|
||||
from api.tasks import send_message
|
||||
from api.tasks import send_notification
|
||||
from api.utils import validate_onchain_address
|
||||
|
||||
FEE = float(config("FEE"))
|
||||
@ -314,7 +314,7 @@ class Logics:
|
||||
order.status = Order.Status.EXP
|
||||
order.expiry_reason = Order.ExpiryReasons.NTAKEN
|
||||
order.save()
|
||||
send_message.delay(order.id, "order_expired_untaken")
|
||||
send_notification.delay(order_id=order.id, message="order_expired_untaken")
|
||||
return True
|
||||
|
||||
elif order.status == Order.Status.TAK:
|
||||
@ -368,7 +368,7 @@ class Logics:
|
||||
order.trade_escrow = None
|
||||
order.payout = None
|
||||
cls.publish_order(order)
|
||||
send_message.delay(order.id, "order_published")
|
||||
send_notification.delay(order_id=order.id, message="order_published")
|
||||
# Reward maker with part of the taker bond
|
||||
cls.add_slashed_rewards(taker_bond, order.maker.profile)
|
||||
return True
|
||||
@ -399,7 +399,7 @@ class Logics:
|
||||
order.taker_bond = None
|
||||
order.trade_escrow = None
|
||||
cls.publish_order(order)
|
||||
send_message.delay(order.id, "order_published")
|
||||
send_notification.delay(order_id=order.id, message="order_published")
|
||||
# Reward maker with part of the taker bond
|
||||
cls.add_slashed_rewards(taker_bond, order.maker.profile)
|
||||
return True
|
||||
@ -470,7 +470,7 @@ class Logics:
|
||||
).append(str(order.id))
|
||||
profile.save()
|
||||
|
||||
send_message.delay(order.id, "dispute_opened")
|
||||
send_notification.delay(order_id=order.id, message="dispute_opened")
|
||||
return True, None
|
||||
|
||||
def dispute_statement(order, user, statement):
|
||||
@ -815,7 +815,7 @@ class Logics:
|
||||
order.expires_at = timezone.now() + timedelta(
|
||||
seconds=order.t_to_expire(Order.Status.CHA)
|
||||
)
|
||||
send_message.delay(order.id, "fiat_exchange_starts")
|
||||
send_notification.delay(order_id=order.id, message="fiat_exchange_starts")
|
||||
|
||||
# If the order status is 'Waiting for both'. Move forward to 'waiting for escrow'
|
||||
elif order.status == Order.Status.WF2:
|
||||
@ -828,7 +828,9 @@ class Logics:
|
||||
order.expires_at = timezone.now() + timedelta(
|
||||
seconds=order.t_to_expire(Order.Status.CHA)
|
||||
)
|
||||
send_message.delay(order.id, "fiat_exchange_starts")
|
||||
send_notification.delay(
|
||||
order_id=order.id, message="fiat_exchange_starts"
|
||||
)
|
||||
else:
|
||||
order.status = Order.Status.WFE
|
||||
|
||||
@ -915,7 +917,9 @@ class Logics:
|
||||
if cls.return_bond(order.maker_bond):
|
||||
order.status = Order.Status.UCA
|
||||
order.save()
|
||||
send_message.delay(order.id, "public_order_cancelled")
|
||||
send_notification.delay(
|
||||
order_id=order.id, message="public_order_cancelled"
|
||||
)
|
||||
return True, None
|
||||
|
||||
# 2.b) When maker cancels after bond and before taker bond is locked
|
||||
@ -928,7 +932,9 @@ class Logics:
|
||||
cls.cancel_bond(order.taker_bond)
|
||||
order.status = Order.Status.UCA
|
||||
order.save()
|
||||
send_message.delay(order.id, "public_order_cancelled")
|
||||
send_notification.delay(
|
||||
order_id=order.id, message="public_order_cancelled"
|
||||
)
|
||||
return True, None
|
||||
|
||||
# 3) When taker cancels before bond
|
||||
@ -978,7 +984,7 @@ class Logics:
|
||||
order.payout = None
|
||||
order.trade_escrow = None
|
||||
cls.publish_order(order)
|
||||
send_message.delay(order.id, "order_published")
|
||||
send_notification.delay(order_id=order.id, message="order_published")
|
||||
# Reward maker with part of the taker bond
|
||||
cls.add_slashed_rewards(order.taker_bond, order.maker.profile)
|
||||
return True, None
|
||||
@ -1026,7 +1032,7 @@ class Logics:
|
||||
cls.return_escrow(order)
|
||||
order.status = Order.Status.CCA
|
||||
order.save()
|
||||
send_message.delay(order.id, "collaborative_cancelled")
|
||||
send_notification.delay(order_id=order.id, message="collaborative_cancelled")
|
||||
return
|
||||
|
||||
@classmethod
|
||||
@ -1040,7 +1046,7 @@ class Logics:
|
||||
order.last_satoshis = cls.satoshis_now(order)
|
||||
order.last_satoshis_time = timezone.now()
|
||||
order.save()
|
||||
# send_message.delay(order.id,'order_published') # too spammy
|
||||
# send_notification.delay(order_id=order.id,'order_published') # too spammy
|
||||
return
|
||||
|
||||
def compute_cltv_expiry_blocks(order, invoice_concept):
|
||||
@ -1071,7 +1077,7 @@ class Logics:
|
||||
return True
|
||||
elif LNNode.validate_hold_invoice_locked(order.maker_bond):
|
||||
cls.publish_order(order)
|
||||
send_message.delay(order.id, "order_published")
|
||||
send_notification.delay(order_id=order.id, message="order_published")
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -1176,7 +1182,7 @@ class Logics:
|
||||
MarketTick.log_a_tick(order)
|
||||
except Exception:
|
||||
pass
|
||||
send_message.delay(order.id, "order_taken_confirmed")
|
||||
send_notification.delay(order_id=order.id, message="order_taken_confirmed")
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
@ -1272,7 +1278,7 @@ class Logics:
|
||||
order.expires_at = timezone.now() + timedelta(
|
||||
seconds=order.t_to_expire(Order.Status.CHA)
|
||||
)
|
||||
send_message.delay(order.id, "fiat_exchange_starts")
|
||||
send_notification.delay(order_id=order.id, message="fiat_exchange_starts")
|
||||
order.save()
|
||||
|
||||
@classmethod
|
||||
@ -1439,7 +1445,7 @@ class Logics:
|
||||
order.payout.status = LNPayment.Status.FLIGHT
|
||||
order.payout.save()
|
||||
order.save()
|
||||
send_message.delay(order.id, "trade_successful")
|
||||
send_notification.delay(order_id=order.id, message="trade_successful")
|
||||
order.contract_finalization_time = timezone.now()
|
||||
order.save()
|
||||
return True
|
||||
@ -1454,7 +1460,7 @@ class Logics:
|
||||
order.payout_tx.status = OnchainPayment.Status.QUEUE
|
||||
order.payout_tx.save()
|
||||
order.save()
|
||||
send_message.delay(order.id, "trade_successful")
|
||||
send_notification.delay(order_id=order.id, message="trade_successful")
|
||||
order.contract_finalization_time = timezone.now()
|
||||
order.save()
|
||||
return True
|
||||
|
@ -9,7 +9,7 @@ from django.utils import timezone
|
||||
from api.lightning.node import LNNode
|
||||
from api.logics import Logics
|
||||
from api.models import LNPayment, OnchainPayment, Order
|
||||
from api.tasks import follow_send_payment, send_message
|
||||
from api.tasks import follow_send_payment, send_notification
|
||||
|
||||
MACAROON = b64decode(config("LND_MACAROON_BASE64"))
|
||||
|
||||
@ -228,7 +228,9 @@ class Command(BaseCommand):
|
||||
# It is a maker bond => Publish order.
|
||||
if hasattr(lnpayment, "order_made"):
|
||||
Logics.publish_order(lnpayment.order_made)
|
||||
send_message.delay(lnpayment.order_made.id, "order_published")
|
||||
send_notification.delay(
|
||||
order_id=lnpayment.order_made.id, message="order_published"
|
||||
)
|
||||
return
|
||||
|
||||
# It is a taker bond => close contract.
|
||||
|
@ -5,8 +5,8 @@ from decouple import config
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.db import transaction
|
||||
|
||||
from api.messages import Telegram
|
||||
from api.models import Profile
|
||||
from api.notifications import Telegram
|
||||
from api.utils import get_session
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ from api.utils import get_session
|
||||
|
||||
|
||||
class Telegram:
|
||||
"""Simple telegram messages by requesting to API"""
|
||||
"""Simple telegram messages using TG's API"""
|
||||
|
||||
session = get_session()
|
||||
site = config("HOST_NAME")
|
||||
@ -49,9 +49,9 @@ class Telegram:
|
||||
lang = user.profile.telegram_lang_code
|
||||
|
||||
if lang == "es":
|
||||
text = f"Hola {user.username}, te enviaré notificaciones sobre tus órdenes en RoboSats."
|
||||
text = f"🔔 Hola {user.username}, te enviaré notificaciones sobre tus órdenes en RoboSats."
|
||||
else:
|
||||
text = f"Hey {user.username}, I will send you notifications about your RoboSats orders."
|
||||
text = f"🔔 Hey {user.username}, I will send you notifications about your RoboSats orders."
|
||||
self.send_message(user.profile.telegram_chat_id, text)
|
||||
user.profile.telegram_welcomed = True
|
||||
user.profile.save()
|
||||
@ -61,17 +61,17 @@ class Telegram:
|
||||
if order.maker.profile.telegram_enabled:
|
||||
lang = order.maker.profile.telegram_lang_code
|
||||
if lang == "es":
|
||||
text = f"Hey {order.maker.username} ¡Tu orden con ID {order.id} ha sido tomada por {order.taker.username}!🥳 Visita http://{self.site}/order/{order.id} para continuar."
|
||||
text = f"✅ Hey {order.maker.username} ¡Tu orden con ID {order.id} ha sido tomada por {order.taker.username}!🥳 Visita http://{self.site}/order/{order.id} para continuar."
|
||||
else:
|
||||
text = f"Hey {order.maker.username}, your order was taken by {order.taker.username}!🥳 Visit http://{self.site}/order/{order.id} to proceed with the trade."
|
||||
text = f"✅ Hey {order.maker.username}, your order was taken by {order.taker.username}!🥳 Visit http://{self.site}/order/{order.id} to proceed with the trade."
|
||||
self.send_message(order.maker.profile.telegram_chat_id, text)
|
||||
|
||||
if order.taker.profile.telegram_enabled:
|
||||
lang = order.taker.profile.telegram_lang_code
|
||||
if lang == "es":
|
||||
text = f"Hey {order.taker.username}, acabas de tomar la orden con ID {order.id}."
|
||||
text = f"✅ Hey {order.taker.username}, acabas de tomar la orden con ID {order.id}."
|
||||
else:
|
||||
text = f"Hey {order.taker.username}, you just took the order with ID {order.id}."
|
||||
text = f"✅ Hey {order.taker.username}, you just took the order with ID {order.id}."
|
||||
self.send_message(order.taker.profile.telegram_chat_id, text)
|
||||
|
||||
return
|
||||
@ -81,9 +81,9 @@ class Telegram:
|
||||
if user.profile.telegram_enabled:
|
||||
lang = user.profile.telegram_lang_code
|
||||
if lang == "es":
|
||||
text = f"Hey {user.username}, el depósito de garantía y el recibo del comprador han sido recibidos. Es hora de enviar el dinero fiat. Visita http://{self.site}/order/{order.id} para hablar con tu contraparte."
|
||||
text = f"✅ Hey {user.username}, el depósito de garantía y el recibo del comprador han sido recibidos. Es hora de enviar el dinero fiat. Visita http://{self.site}/order/{order.id} para hablar con tu contraparte."
|
||||
else:
|
||||
text = f"Hey {user.username}, the escrow and invoice have been submitted. The fiat exchange starts now via the platform chat. Visit http://{self.site}/order/{order.id} to talk with your counterpart."
|
||||
text = f"✅ Hey {user.username}, the escrow and invoice have been submitted. The fiat exchange starts now via the platform chat. Visit http://{self.site}/order/{order.id} to talk with your counterpart."
|
||||
self.send_message(user.profile.telegram_chat_id, text)
|
||||
return
|
||||
|
||||
@ -91,9 +91,9 @@ class Telegram:
|
||||
if order.maker.profile.telegram_enabled:
|
||||
lang = order.maker.profile.telegram_lang_code
|
||||
if lang == "es":
|
||||
text = f"Hey {order.maker.username}, tu orden con ID {order.id} ha expirado sin ser tomada por ningún robot. Visita http://{self.site}/order/{order.id} para renovarla."
|
||||
text = f"😪 Hey {order.maker.username}, tu orden con ID {order.id} ha expirado sin ser tomada por ningún robot. Visita http://{self.site}/order/{order.id} para renovarla."
|
||||
else:
|
||||
text = f"Hey {order.maker.username}, your order with ID {order.id} has expired without a taker. Visit http://{self.site}/order/{order.id} to renew it."
|
||||
text = f"😪 Hey {order.maker.username}, your order with ID {order.id} has expired without a taker. Visit http://{self.site}/order/{order.id} to renew it."
|
||||
self.send_message(order.maker.profile.telegram_chat_id, text)
|
||||
return
|
||||
|
||||
@ -102,9 +102,9 @@ class Telegram:
|
||||
if user.profile.telegram_enabled:
|
||||
lang = user.profile.telegram_lang_code
|
||||
if lang == "es":
|
||||
text = f"¡Tu orden con ID {order.id} ha finalizado exitosamente!⚡ Únete a nosotros en @robosats_es y ayúdanos a mejorar."
|
||||
text = f"🥳 ¡Tu orden con ID {order.id} ha finalizado exitosamente!⚡ Únete a nosotros en @robosats_es y ayúdanos a mejorar."
|
||||
else:
|
||||
text = f"Your order with ID {order.id} has finished successfully!⚡ Join us @robosats and help us improve."
|
||||
text = f"🥳 Your order with ID {order.id} has finished successfully!⚡ Join us @robosats and help us improve."
|
||||
self.send_message(user.profile.telegram_chat_id, text)
|
||||
return
|
||||
|
||||
@ -112,9 +112,9 @@ class Telegram:
|
||||
if order.maker.profile.telegram_enabled:
|
||||
lang = order.maker.profile.telegram_lang_code
|
||||
if lang == "es":
|
||||
text = f"Hey {order.maker.username}, has cancelado tu orden pública con ID {order.id}."
|
||||
text = f"❌ Hey {order.maker.username}, has cancelado tu orden pública con ID {order.id}."
|
||||
else:
|
||||
text = f"Hey {order.maker.username}, you have cancelled your public order with ID {order.id}."
|
||||
text = f"❌ Hey {order.maker.username}, you have cancelled your public order with ID {order.id}."
|
||||
self.send_message(order.maker.profile.telegram_chat_id, text)
|
||||
return
|
||||
|
||||
@ -123,9 +123,9 @@ class Telegram:
|
||||
if user.profile.telegram_enabled:
|
||||
lang = user.profile.telegram_lang_code
|
||||
if lang == "es":
|
||||
text = f"Hey {user.username}, tu orden con ID {str(order.id)} fue cancelada colaborativamente."
|
||||
text = f"❌ Hey {user.username}, tu orden con ID {str(order.id)} fue cancelada colaborativamente."
|
||||
else:
|
||||
text = f"Hey {user.username}, your order with ID {str(order.id)} has been collaboratively cancelled."
|
||||
text = f"❌ Hey {user.username}, your order with ID {str(order.id)} has been collaboratively cancelled."
|
||||
self.send_message(user.profile.telegram_chat_id, text)
|
||||
return
|
||||
|
||||
@ -134,9 +134,9 @@ class Telegram:
|
||||
if user.profile.telegram_enabled:
|
||||
lang = user.profile.telegram_lang_code
|
||||
if lang == "es":
|
||||
text = f"Hey {user.username}, la orden con ID {str(order.id)} ha entrado en disputa."
|
||||
text = f"⚖️ Hey {user.username}, la orden con ID {str(order.id)} ha entrado en disputa."
|
||||
else:
|
||||
text = f"Hey {user.username}, a dispute has been opened on your order with ID {str(order.id)}."
|
||||
text = f"⚖️ Hey {user.username}, a dispute has been opened on your order with ID {str(order.id)}."
|
||||
self.send_message(user.profile.telegram_chat_id, text)
|
||||
return
|
||||
|
||||
@ -149,8 +149,39 @@ class Telegram:
|
||||
return
|
||||
order = queryset.last()
|
||||
if lang == "es":
|
||||
text = f"Hey {order.maker.username}, tu orden con ID {str(order.id)} es pública en el libro de ordenes."
|
||||
text = f"✅ Hey {order.maker.username}, tu orden con ID {str(order.id)} es pública en el libro de ordenes."
|
||||
else:
|
||||
text = f"Hey {order.maker.username}, your order with ID {str(order.id)} is public in the order book."
|
||||
text = f"✅ Hey {order.maker.username}, your order with ID {str(order.id)} is public in the order book."
|
||||
self.send_message(order.maker.profile.telegram_chat_id, text)
|
||||
return
|
||||
|
||||
def new_chat_message(self, order, chat_message):
|
||||
"""
|
||||
Sends a TG notification for a new in-app chat message if
|
||||
the last chat was at least CHAT_NOTIFICATION_TIMEGAP minutes ago.
|
||||
"""
|
||||
from datetime import timedelta
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
from chat.models import Message
|
||||
|
||||
TIMEGAP = config("CHAT_NOTIFICATION_TIMEGAP", cast=int, default=5)
|
||||
if chat_message.index > 1:
|
||||
previous_message = Message.objects.get(
|
||||
chatroom=chat_message.chatroom, index=(chat_message.index - 1)
|
||||
)
|
||||
notification_reason = f"(You receive this notification only because more than {TIMEGAP} minutes have passed since the last in-chat message)"
|
||||
if previous_message.created_at > timezone.now() - timedelta(
|
||||
minutes=TIMEGAP
|
||||
):
|
||||
return
|
||||
else:
|
||||
notification_reason = f"(You receive this notification because this was the first in-chat message. You will only be notified again if there is a gap bigger than {TIMEGAP} minutes between messages)"
|
||||
|
||||
user = chat_message.receiver
|
||||
if user.profile.telegram_enabled:
|
||||
text = f"💬 Hey {user.username}, a new chat message in-app was sent to you by {chat_message.sender.username} for order ID {str(order.id)}. {notification_reason}"
|
||||
self.send_message(user.profile.telegram_chat_id, text)
|
||||
|
||||
return
|
20
api/tasks.py
20
api/tasks.py
@ -313,19 +313,26 @@ def cache_market():
|
||||
return results
|
||||
|
||||
|
||||
@shared_task(name="send_message", ignore_result=True)
|
||||
def send_message(order_id, message):
|
||||
@shared_task(name="send_notification", ignore_result=True)
|
||||
def send_notification(order_id=None, chat_message_id=None, message=None):
|
||||
|
||||
from api.models import Order
|
||||
if order_id:
|
||||
from api.models import Order
|
||||
|
||||
order = Order.objects.get(id=order_id)
|
||||
elif chat_message_id:
|
||||
from chat.models import Message
|
||||
|
||||
chat_message = Message.objects.get(id=chat_message_id)
|
||||
order = chat_message.order
|
||||
|
||||
order = Order.objects.get(id=order_id)
|
||||
taker_enabled = (
|
||||
False if order.taker is None else order.taker.profile.telegram_enabled
|
||||
)
|
||||
if not (order.maker.profile.telegram_enabled or taker_enabled):
|
||||
return
|
||||
|
||||
from api.messages import Telegram
|
||||
from api.notifications import Telegram
|
||||
|
||||
telegram = Telegram()
|
||||
|
||||
@ -359,4 +366,7 @@ def send_message(order_id, message):
|
||||
elif message == "collaborative_cancelled":
|
||||
telegram.collaborative_cancelled(order)
|
||||
|
||||
elif message == "new_chat_message":
|
||||
telegram.new_chat_message(order, chat_message)
|
||||
|
||||
return
|
||||
|
@ -19,8 +19,8 @@ from robohash import Robohash
|
||||
from scipy.stats import entropy
|
||||
|
||||
from api.logics import Logics
|
||||
from api.messages import Telegram
|
||||
from api.models import Currency, LNPayment, MarketTick, OnchainPayment, Order, Profile
|
||||
from api.notifications import Telegram
|
||||
from api.oas_schemas import (
|
||||
BookViewSchema,
|
||||
HistoricalViewSchema,
|
||||
|
@ -4,6 +4,7 @@ from channels.db import database_sync_to_async
|
||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||
|
||||
from api.models import Order
|
||||
from api.tasks import send_notification
|
||||
from chat.models import ChatRoom, Message
|
||||
|
||||
|
||||
@ -78,6 +79,9 @@ class ChatRoomConsumer(AsyncWebsocketConsumer):
|
||||
receiver=receiver,
|
||||
PGP_message=PGP_message,
|
||||
)
|
||||
|
||||
# send Telegram notification for new message (if conditions apply)
|
||||
send_notification.delay(chat_message_id=msg_obj.id, message="new_chat_message")
|
||||
return msg_obj
|
||||
|
||||
@database_sync_to_async
|
||||
|
@ -7,6 +7,7 @@ from rest_framework import status, viewsets
|
||||
from rest_framework.response import Response
|
||||
|
||||
from api.models import Order, User
|
||||
from api.tasks import send_notification
|
||||
from chat.models import ChatRoom, Message
|
||||
from chat.serializers import ChatSerializer, PostMessageSerializer
|
||||
|
||||
@ -160,6 +161,11 @@ class ChatView(viewsets.ViewSet):
|
||||
receiver=receiver,
|
||||
)
|
||||
|
||||
# send Telegram notification for new message (if conditions apply)
|
||||
send_notification.delay(
|
||||
chat_message_id=new_message.id, message="new_chat_message"
|
||||
)
|
||||
|
||||
# Send websocket message
|
||||
if chatroom.maker == request.user:
|
||||
peer_connected = chatroom.taker_connected
|
||||
|
@ -77,7 +77,7 @@ const ChatHeader: React.FC<Props> = ({ connected, peerConnected, turtleMode, set
|
||||
>
|
||||
<Typography align='center' variant='caption' sx={{ color: connectedTextColor }}>
|
||||
{t('Peer') + ': '}
|
||||
{connected ? (peerConnected ? t('connected') : t('disconnected')) : '...waiting'}
|
||||
{connected ? (peerConnected ? t('connected') : t('disconnected')) : t('...waiting')}
|
||||
</Typography>
|
||||
</Paper>
|
||||
</Grid>
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "desconnectat",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activar mode lent (utilitza'l quan la connexió sigui lenta)",
|
||||
"Peer": "Ell",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Verifica la teva privacitat",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "odpojen",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Protistrana",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Ověř svou ochranu soukromí",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "getrennt",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Partner",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Überprüfe deine Privatsphäre",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "disconnected",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Peer",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Verify your privacy",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "desconectado",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activar modo lento (Úsalo cuando tu conexión sea inestable)",
|
||||
"Peer": "Él",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Verifica tu privacidad",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "deskonektatuta",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Bera",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Zure pribatasuna egiaztatu",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "déconnecté",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Pair",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Verify your privacy",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "disconnesso",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Pari",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Verificando la tua privacy",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "niepowiązany",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Par",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Verify your privacy",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "desconectado",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Par",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Verifique sua privacidade",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "отключен",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Партнёр",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Проверьте свою конфиденциальность",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "ej ansluten",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "Peer",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "Verifiera din integritet",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "ตัดการเชื่อมต่อแล้ว",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "คู่ค้า",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "ตรวจสอบความเป็นส่วนตัวของคุณ",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "离线",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "对等方",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "验证你的隐私",
|
||||
|
@ -423,6 +423,7 @@
|
||||
"disconnected": "離線",
|
||||
"Activate slow mode (use it when the connection is slow)": "Activate slow mode (use it when the connection is slow)",
|
||||
"Peer": "對等方",
|
||||
"...waiting": "...waiting",
|
||||
"#42": "Phrases in components/TradeBox/EncryptedChat/EncryptedTurtleChat/index.tsx",
|
||||
"#43": "Phrases in components/TradeBox/EncryptedChat/ChatBottom/index.tsx",
|
||||
"Verify your privacy": "驗證你的隱私",
|
||||
|
Loading…
Reference in New Issue
Block a user