Refactor avatars (#251)

This commit is contained in:
KoalaSat
2022-09-23 01:55:11 +02:00
committed by Reckless_Satoshi
parent c9a18751e9
commit ae193f19a4
13 changed files with 171 additions and 230 deletions

View File

@ -46,10 +46,8 @@ jobs:
with: with:
images: recksato/robosats-client images: recksato/robosats-client
tags: | tags: |
type=ref,event=branch
type=ref,event=pr type=ref,event=pr
type=ref,event=tag type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}}.{{minor}}
type=sha,enable=true,priority=100,prefix=,suffix=,format=short type=sha,enable=true,priority=100,prefix=,suffix=,format=short
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
@ -71,5 +69,4 @@ jobs:
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}

View File

@ -35,10 +35,8 @@ jobs:
with: with:
images: recksato/robosats images: recksato/robosats
tags: | tags: |
type=ref,event=branch
type=ref,event=pr type=ref,event=pr
type=ref,event=tag type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}}.{{minor}}
type=sha,enable=true,priority=100,prefix=,suffix=,format=short type=sha,enable=true,priority=100,prefix=,suffix=,format=short
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
@ -57,5 +55,4 @@ jobs:
context: . context: .
push: true push: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}

View File

@ -54,17 +54,16 @@ jobs:
name: main-js name: main-js
path: frontend/static/frontend/main.js path: frontend/static/frontend/main.js
invoke-docker-builds: # Invoke pre-release image build if this was not a tag push
if: inputs.semver == '' # Docker images tagged only with short commit hash
runs-on: ubuntu-latest
needs: build
steps:
- name: 'Invoke Coodinator Image CI' - name: 'Invoke Coodinator Image CI'
if: inputs.semver == ''
uses: benc-uk/workflow-dispatch@v1 uses: benc-uk/workflow-dispatch@v1
with: with:
workflow: 'Coodinator Image CI' workflow: 'Coodinator Image CI'
token: ${{ secrets.PERSONAL_TOKEN }} token: ${{ secrets.PERSONAL_TOKEN }}
- name: 'Invoke Client App Build CI/CD workflow' - name: 'Invoke Client App Build CI/CD workflow'
if: inputs.semver == ''
uses: benc-uk/workflow-dispatch@v1 uses: benc-uk/workflow-dispatch@v1
with: with:
workflow: 'Client App Image CI/CD' workflow: 'Client App Image CI/CD'

View File

@ -96,6 +96,4 @@ jobs:
# upload_url: ${{ steps.create-release.outputs.upload_url }} # upload_url: ${{ steps.create-release.outputs.upload_url }}
# asset_path: app-release.apk # asset_path: app-release.apk
# asset_name: robosats-${{ needs.check-versions.outputs.semver }}.apk # asset_name: robosats-${{ needs.check-versions.outputs.semver }}.apk
# asset_content_type: application/apk # asset_content_type: application/apk

View File

@ -81,13 +81,13 @@ class BookPage extends Component {
// Colors for the status badges // Colors for the status badges
statusBadgeColor(status) { statusBadgeColor(status) {
if (status == 'Active') { if (status === 'Active') {
return 'success'; return 'success';
} }
if (status == 'Seen recently') { if (status === 'Seen recently') {
return 'warning'; return 'warning';
} }
if (status == 'Inactive') { if (status === 'Inactive') {
return 'error'; return 'error';
} }
} }
@ -167,7 +167,12 @@ class BookPage extends Component {
return ( return (
<ListItemButton style={{ cursor: 'pointer' }}> <ListItemButton style={{ cursor: 'pointer' }}>
<ListItemAvatar> <ListItemAvatar>
<RobotAvatar order={params.row} /> <RobotAvatar
nickname={params.row.maker_nick}
orderType={params.row.type}
statusColor={this.statusBadgeColor(params.row.maker_status)}
tooltip={t(params.row.maker_status)}
/>
</ListItemAvatar> </ListItemAvatar>
<ListItemText primary={params.row.maker_nick} /> <ListItemText primary={params.row.maker_nick} />
</ListItemButton> </ListItemButton>
@ -307,7 +312,13 @@ class BookPage extends Component {
renderCell: (params) => { renderCell: (params) => {
return ( return (
<div style={{ position: 'relative', left: '-5px' }}> <div style={{ position: 'relative', left: '-5px' }}>
<RobotAvatar order={params.row} /> <RobotAvatar
nickname={params.row.maker_nick}
smooth={true}
orderType={params.row.type}
statusColor={this.statusBadgeColor(params.row.maker_status)}
tooltip={t(params.row.maker_status)}
/>
</div> </div>
); );
}, },

View File

@ -19,6 +19,7 @@ import MediaQuery from 'react-responsive';
import Flags from 'country-flag-icons/react/3x2'; import Flags from 'country-flag-icons/react/3x2';
import { Link as LinkRouter } from 'react-router-dom'; import { Link as LinkRouter } from 'react-router-dom';
import { apiClient } from '../services/api'; import { apiClient } from '../services/api';
import RobotAvatar from './Robots/RobotAvatar';
// Icons // Icons
import BarChartIcon from '@mui/icons-material/BarChart'; import BarChartIcon from '@mui/icons-material/BarChart';
@ -204,29 +205,16 @@ class BottomBar extends Component {
} }
> >
<ListItemAvatar sx={{ width: 30 * fontSizeFactor, height: 30 * fontSizeFactor }}> <ListItemAvatar sx={{ width: 30 * fontSizeFactor, height: 30 * fontSizeFactor }}>
<Badge <RobotAvatar
badgeContent={ style={{ marginTop: -13 }}
(this.props.activeOrderId > 0) & !this.props.profileShown ? '' : null statusColor={
(this.props.activeOrderId > 0) & !this.props.profileShown
? 'primary'
: undefined
} }
color='primary' nickname={this.props.nickname}
> onLoad={() => this.props.setAppState({ avatarLoaded: true })}
<Avatar />
className='flippedSmallAvatar'
sx={{ margin: 0, top: -13 }}
alt={this.props.nickname}
imgProps={{
onLoad: () => this.props.setAppState({ avatarLoaded: true }),
}}
src={
this.props.nickname
? window.location.origin +
'/static/assets/avatars/' +
this.props.nickname +
'.png'
: null
}
/>
</Badge>
</ListItemAvatar> </ListItemAvatar>
</Tooltip> </Tooltip>
<ListItemText primary={this.props.nickname} /> <ListItemText primary={this.props.nickname} />
@ -512,29 +500,17 @@ class BottomBar extends Component {
onClick={this.handleClickOpenProfile} onClick={this.handleClickOpenProfile}
sx={{ margin: 0, bottom: 17, right: 8 }} sx={{ margin: 0, bottom: 17, right: 8 }}
> >
<Badge <RobotAvatar
badgeContent={ style={{ width: 55, height: 55 }}
(this.state.active_order_id > 0) & !this.state.profileShown ? '' : null avatarClass='phoneFlippedSmallAvatar'
statusColor={
(this.props.activeOrderId > 0) & !this.props.profileShown
? 'primary'
: undefined
} }
color='primary' nickname={this.props.nickname}
> onLoad={() => this.props.setAppState({ avatarLoaded: true })}
<Avatar />
className='phoneFlippedSmallAvatar'
sx={{ width: 55, height: 55 }}
alt={this.props.nickname}
imgProps={{
onLoad: () => this.props.setAppState({ avatarLoaded: true }),
}}
src={
this.props.nickname
? window.location.origin +
'/static/assets/avatars/' +
this.props.nickname +
'.png'
: null
}
/>
</Badge>
</IconButton> </IconButton>
</Tooltip> </Tooltip>
</div> </div>

View File

@ -216,6 +216,17 @@ const DepthChart: React.FC<DepthChartProps> = ({
/> />
); );
const statusBadgeColor = (status: string) => {
if (status === 'Active') {
return 'success';
}
if (status === 'Seen recently') {
return 'warning';
}
return 'error';
};
const generateTooltip: React.FunctionComponent<PointTooltipProps> = ( const generateTooltip: React.FunctionComponent<PointTooltipProps> = (
pointTooltip: PointTooltipProps, pointTooltip: PointTooltipProps,
) => { ) => {
@ -225,7 +236,12 @@ const DepthChart: React.FC<DepthChartProps> = ({
<Grid container justifyContent='space-between'> <Grid container justifyContent='space-between'>
<Grid item xs={3}> <Grid item xs={3}>
<Grid container justifyContent='center' alignItems='center'> <Grid container justifyContent='center' alignItems='center'>
<RobotAvatar order={order} /> <RobotAvatar
nickname={order.maker_nick}
orderType={order.type}
statusColor={statusBadgeColor(order.maker_status)}
tooltip={t(order.maker_status)}
/>
</Grid> </Grid>
</Grid> </Grid>
<Grid item xs={8}> <Grid item xs={8}>

View File

@ -39,6 +39,7 @@ import { UserNinjaIcon, BitcoinIcon } from '../Icons';
import { getCookie } from '../../utils/cookies'; import { getCookie } from '../../utils/cookies';
import { copyToClipboard } from '../../utils/clipboard'; import { copyToClipboard } from '../../utils/clipboard';
import { getWebln } from '../../utils/webln'; import { getWebln } from '../../utils/webln';
import RobotAvatar from '../Robots/RobotAvatar';
interface Props { interface Props {
isOpen: boolean; isOpen: boolean;
@ -167,13 +168,10 @@ const ProfileDialog = ({
</ListItemText> </ListItemText>
<ListItemAvatar> <ListItemAvatar>
<Avatar <RobotAvatar
className='profileAvatar' avatarClass='profileAvatar'
sx={{ width: 65, height: 65 }} style={{ width: 65, height: 65 }}
alt={nickname} nickname={nickname}
src={
nickname ? `${window.location.origin}/static/assets/avatars/${nickname}.png` : ''
}
/> />
</ListItemAvatar> </ListItemAvatar>
</ListItem> </ListItem>

View File

@ -20,6 +20,7 @@ import { getCookie } from '../utils/cookies';
import { saveAsJson } from '../utils/saveFile'; import { saveAsJson } from '../utils/saveFile';
import { copyToClipboard } from '../utils/clipboard'; import { copyToClipboard } from '../utils/clipboard';
import { AuditPGPDialog } from './Dialogs'; import { AuditPGPDialog } from './Dialogs';
import RobotAvatar from './Robots/RobotAvatar';
// Icons // Icons
import CheckIcon from '@mui/icons-material/Check'; import CheckIcon from '@mui/icons-material/Check';
@ -270,23 +271,10 @@ class Chat extends Component {
<CardHeader <CardHeader
sx={{ color: '#333333' }} sx={{ color: '#333333' }}
avatar={ avatar={
<Badge <RobotAvatar
variant='dot' statusColor={props.userConnected ? 'success' : 'error'}
overlap='circular' nickname={props.message.userNick}
badgeContent='' />
color={props.userConnected ? 'success' : 'error'}
>
<Avatar
className='flippedSmallAvatar'
alt={props.message.userNick}
src={
window.location.origin +
'/static/assets/avatars/' +
props.message.userNick +
'.png'
}
/>
</Badge>
} }
style={{ backgroundColor: props.cardColor }} style={{ backgroundColor: props.cardColor }}
title={ title={

View File

@ -55,6 +55,7 @@ import { pn } from '../utils/prettyNumbers';
import { copyToClipboard } from '../utils/clipboard'; import { copyToClipboard } from '../utils/clipboard';
import { getWebln } from '../utils/webln'; import { getWebln } from '../utils/webln';
import { apiClient } from '../services/api'; import { apiClient } from '../services/api';
import RobotAvatar from './Robots/RobotAvatar';
class OrderPage extends Component { class OrderPage extends Component {
constructor(props) { constructor(props) {
@ -667,13 +668,13 @@ class OrderPage extends Component {
// Colors for the status badges // Colors for the status badges
statusBadgeColor(status) { statusBadgeColor(status) {
if (status == 'Active') { if (status === 'Active') {
return 'success'; return 'success';
} }
if (status == 'Seen recently') { if (status === 'Seen recently') {
return 'warning'; return 'warning';
} }
if (status == 'Inactive') { if (status === 'Inactive') {
return 'error'; return 'error';
} }
} }
@ -692,46 +693,12 @@ class OrderPage extends Component {
<List dense={true}> <List dense={true}>
<ListItem> <ListItem>
<ListItemAvatar sx={{ width: 56, height: 56 }}> <ListItemAvatar sx={{ width: 56, height: 56 }}>
<Tooltip placement='top' enterTouchDelay={0} title={t(this.state.maker_status)}> <RobotAvatar
<Badge statusColor={this.statusBadgeColor(this.state.maker_status)}
variant='dot' nickname={this.state.maker_nick}
overlap='circular' tooltip={t(this.state.maker_status)}
badgeContent='' orderType={this.state.type}
color={this.statusBadgeColor(this.state.maker_status)} />
>
<Badge
overlap='circular'
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
badgeContent={
<div style={{ position: 'relative', left: '5px', top: '2px' }}>
{' '}
{!this.state.type ? (
<SendReceiveIcon
sx={{ transform: 'scaleX(-1)', height: '18px', width: '18px' }}
color='secondary'
/>
) : (
<SendReceiveIcon
sx={{ height: '18px', width: '18px' }}
color='primary'
/>
)}
</div>
}
>
<Avatar
className='flippedSmallAvatar'
alt={this.state.maker_nick}
src={
window.location.origin +
'/static/assets/avatars/' +
this.state.maker_nick +
'.png'
}
/>
</Badge>
</Badge>
</Tooltip>
</ListItemAvatar> </ListItemAvatar>
<ListItemText <ListItemText
primary={ primary={
@ -745,7 +712,7 @@ class OrderPage extends Component {
{this.state.is_participant ? ( {this.state.is_participant ? (
<> <>
{this.state.taker_nick != 'None' ? ( {this.state.taker_nick !== 'None' ? (
<> <>
<Divider /> <Divider />
<ListItem align='left'> <ListItem align='left'>
@ -757,50 +724,13 @@ class OrderPage extends Component {
secondary={t('Order taker')} secondary={t('Order taker')}
/> />
<ListItemAvatar> <ListItemAvatar>
<Tooltip enterTouchDelay={0} title={t(this.state.taker_status)}> <RobotAvatar
<Badge avatarClass='smallAvatar'
variant='dot' statusColor={this.statusBadgeColor(this.state.taker_status)}
overlap='circular' nickname={this.state.taker_nick}
badgeContent='' tooltip={t(this.state.taker_status)}
color={this.statusBadgeColor(this.state.taker_status)} orderType={this.state.type === 0 ? 1 : 0}
> />
<Badge
overlap='circular'
anchorOrigin={{ horizontal: 'left', vertical: 'bottom' }}
badgeContent={
<div style={{ position: 'relative', right: '5px', top: '2px' }}>
{' '}
{this.state.type ? (
<SendReceiveIcon
sx={{ height: '18px', width: '18px' }}
color='secondary'
/>
) : (
<SendReceiveIcon
sx={{
transform: 'scaleX(-1)',
height: '18px',
width: '18px',
}}
color='primary'
/>
)}
</div>
}
>
<Avatar
className='smallAvatar'
alt={this.state.taker_nick}
src={
window.location.origin +
'/static/assets/avatars/' +
this.state.taker_nick +
'.png'
}
/>
</Badge>
</Badge>
</Tooltip>
</ListItemAvatar> </ListItemAvatar>
</ListItem> </ListItem>
</> </>

View File

@ -1,24 +1,37 @@
import React from 'react'; import React from 'react';
import { Badge, Tooltip } from '@mui/material';
import SmoothImage from 'react-smooth-image'; import SmoothImage from 'react-smooth-image';
import { Avatar, Badge, Tooltip } from '@mui/material';
import Order from '../../../models/Order.model';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { SendReceiveIcon } from '../../Icons'; import { SendReceiveIcon } from '../../Icons';
interface DepthChartProps { interface DepthChartProps {
order: Order; nickname: string;
smooth?: boolean;
style?: object;
statusColor?: 'primary' | 'secondary' | 'default' | 'error' | 'info' | 'success' | 'warning';
orderType?: number;
tooltip?: string;
avatarClass?: string;
onLoad?: () => void;
} }
const RobotAvatar: React.FC<DepthChartProps> = ({ order }) => { const RobotAvatar: React.FC<DepthChartProps> = ({
nickname,
orderType,
statusColor,
tooltip,
smooth = false,
style = {},
avatarClass = 'flippedSmallAvatar',
onLoad = () => {},
}) => {
const { t } = useTranslation(); const { t } = useTranslation();
const avatarSrc: string = const avatarSrc: string = window.location.origin + '/static/assets/avatars/' + nickname + '.png';
window.location.origin + '/static/assets/avatars/' + order?.maker_nick + '.png';
const statusBadge = ( const statusBadge = (
<div style={{ position: 'relative', left: '6px', top: '1px' }}> <div style={{ position: 'relative', left: '6px', top: '1px' }}>
{order?.type === 0 ? ( {orderType === 0 ? (
<SendReceiveIcon <SendReceiveIcon
sx={{ transform: 'scaleX(-1)', height: '18px', width: '18px' }} sx={{ transform: 'scaleX(-1)', height: '18px', width: '18px' }}
color='secondary' color='secondary'
@ -29,45 +42,68 @@ const RobotAvatar: React.FC<DepthChartProps> = ({ order }) => {
</div> </div>
); );
const statusBadgeColor = () => { const getAvatar = () => {
if (!order) { if (smooth) {
return; return (
} <SmoothImage
if (order.maker_status === 'Active') { className={avatarClass}
return 'success'; src={avatarSrc}
} imageStyles={{
if (order.maker_status === 'Seen recently') { ...style,
return 'warning'; borderRadius: '50%',
} transform: 'scaleX(-1)',
if (order.maker_status === 'Inactive') { border: '0.3px solid #555',
return 'error'; filter: 'dropShadow(0.5px 0.5px 0.5px #000000)',
}}
/>
);
} else {
return (
<Avatar
className={avatarClass}
style={style}
alt={nickname}
src={avatarSrc}
imgProps={{
onLoad,
}}
/>
);
} }
}; };
return order ? ( const getAvatarWithBadges = () => {
<Tooltip placement='right' enterTouchDelay={0} title={t(order.maker_status) || ''}> let component = getAvatar();
<Badge variant='dot' overlap='circular' badgeContent='' color={statusBadgeColor()}>
if (statusColor) {
component = (
<Badge variant='dot' overlap='circular' badgeContent='' color={statusColor}>
{component}
</Badge>
);
}
if (orderType !== undefined) {
component = (
<Badge <Badge
overlap='circular' overlap='circular'
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
badgeContent={statusBadge} badgeContent={statusBadge}
> >
<div style={{ width: 45, height: 45 }}> {component}
<SmoothImage
src={avatarSrc}
imageStyles={{
borderRadius: '50%',
transform: 'scaleX(-1)',
border: '0.3px solid #555',
filter: 'dropShadow(0.5px 0.5px 0.5px #000000)',
}}
/>
</div>
</Badge> </Badge>
</Badge> );
}
return component;
};
return tooltip ? (
<Tooltip placement='right' enterTouchDelay={0} title={tooltip}>
{getAvatarWithBadges()}
</Tooltip> </Tooltip>
) : ( ) : (
<></> getAvatarWithBadges()
); );
}; };

View File

@ -20,6 +20,7 @@ import {
} from '@mui/material'; } from '@mui/material';
import { pn } from '../utils/prettyNumbers'; import { pn } from '../utils/prettyNumbers';
import { saveAsJson } from '../utils/saveFile'; import { saveAsJson } from '../utils/saveFile';
import RobotAvatar from './Robots/RobotAvatar';
// Icons // Icons
import FlagWithProps from './FlagWithProps'; import FlagWithProps from './FlagWithProps';
@ -94,12 +95,7 @@ const TradeSummary = ({
> >
<ToggleButtonGroup size='small' value={buttonValue} exclusive> <ToggleButtonGroup size='small' value={buttonValue} exclusive>
<ToggleButton value={0} disableRipple={true} onClick={() => setButtonValue(0)}> <ToggleButton value={0} disableRipple={true} onClick={() => setButtonValue(0)}>
<Avatar <RobotAvatar style={{ height: 24, width: 24 }} nickname={makerNick} />
className='flippedSmallAvatar'
sx={{ height: 24, width: 24 }}
alt={makerNick}
src={window.location.origin + '/static/assets/avatars/' + makerNick + '.png'}
/>
&nbsp; &nbsp;
{t('Maker')} {t('Maker')}
</ToggleButton> </ToggleButton>
@ -109,11 +105,10 @@ const TradeSummary = ({
<ToggleButton value={2} disableRipple={true} onClick={() => setButtonValue(2)}> <ToggleButton value={2} disableRipple={true} onClick={() => setButtonValue(2)}>
{t('Taker')} {t('Taker')}
&nbsp; &nbsp;
<Avatar <RobotAvatar
className='smallAvatar' avatarClass='smallAvatar'
sx={{ height: 28, width: 28 }} style={{ height: 28, width: 28 }}
alt={takerNick} nickname={takerNick}
src={window.location.origin + '/static/assets/avatars/' + takerNick + '.png'}
/> />
</ToggleButton> </ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>

View File

@ -6,7 +6,7 @@
"Hide": "Amagar", "Hide": "Amagar",
"You are self-hosting RoboSats": "Estàs hostejant RoboSats", "You are self-hosting RoboSats": "Estàs hostejant RoboSats",
"RoboSats client is served from your own node granting you the strongest security and privacy.": "El client RoboSats és servit pel teu propi node, gaudeixes de la major seguretat i privacitat.", "RoboSats client is served from your own node granting you the strongest security and privacy.": "El client RoboSats és servit pel teu propi node, gaudeixes de la major seguretat i privacitat.",
"USER GENERATION PAGE - UserGenPage.js": "Landing Page and User Generation", "USER GENERATION PAGE - UserGenPage.js": "Landing Page and User Generation",
"Simple and Private LN P2P Exchange": "Intercanvi LN P2P Fàcil y Privat", "Simple and Private LN P2P Exchange": "Intercanvi LN P2P Fàcil y Privat",
"This is your trading avatar": "Aquest és el teu Robot de compravenda", "This is your trading avatar": "Aquest és el teu Robot de compravenda",
@ -88,7 +88,7 @@
"Google Play Gift Code": "Targeta Regal de Google Play", "Google Play Gift Code": "Targeta Regal de Google Play",
"Cash F2F": "Efectiu en persona", "Cash F2F": "Efectiu en persona",
"On-Chain BTC": "On-Chain BTC", "On-Chain BTC": "On-Chain BTC",
"BOOK PAGE - BookPage.js": "The Book Order page", "BOOK PAGE - BookPage.js": "The Book Order page",
"Seller": "Ven", "Seller": "Ven",
"Buyer": "Compra", "Buyer": "Compra",
@ -235,7 +235,7 @@
"On your own sovereign node": "Al teu propi node sobirà", "On your own sovereign node": "Al teu propi node sobirà",
"Simply refresh your Tor Browser tab (or press Ctrl+Shift+R)": "Simplement actualitzeu la pestanya del navegador Tor (o premeu Ctrl+Shift+R)", "Simply refresh your Tor Browser tab (or press Ctrl+Shift+R)": "Simplement actualitzeu la pestanya del navegador Tor (o premeu Ctrl+Shift+R)",
"On remotely served client via web": "Al client servit de forma remota via web", "On remotely served client via web": "Al client servit de forma remota via web",
"ORDER PAGE - OrderPage.js": "Order details page", "ORDER PAGE - OrderPage.js": "Order details page",
"Order Box": "Ordre", "Order Box": "Ordre",
"Contract": "Contracte", "Contract": "Contracte",
@ -310,7 +310,7 @@
"Payment not received, please check your WebLN wallet.": "No s'ha rebut el pagament, fes un cop d'ull a la teva wallet WebLN.", "Payment not received, please check your WebLN wallet.": "No s'ha rebut el pagament, fes un cop d'ull a la teva wallet WebLN.",
"Invoice not received, please check your WebLN wallet.": "No s'ha rebut la factura, fes un cop d'ull a la teva wallet WebLN.", "Invoice not received, please check your WebLN wallet.": "No s'ha rebut la factura, fes un cop d'ull a la teva wallet WebLN.",
"You can close now your WebLN wallet popup.": "Ara pots tancar el popup de la teva wallet WebLN.", "You can close now your WebLN wallet popup.": "Ara pots tancar el popup de la teva wallet WebLN.",
"CHAT BOX - Chat.js": "Finestra del xat", "CHAT BOX - Chat.js": "Finestra del xat",
"You": "Tu", "You": "Tu",
"Peer": "Ell", "Peer": "Ell",
@ -446,7 +446,7 @@
"The invoice provided has already expired": "La factura que has entregat ja ha caducat", "The invoice provided has already expired": "La factura que has entregat ja ha caducat",
"Make sure to EXPORT the chat log. The staff might request your exported chat log JSON in order to solve discrepancies. It is your responsibility to store it.": "Assegura't d' EXPORTAR el registre del xat. Els administradors poden demanar-te elregistre del xat en cas de discrepàncies. És la teva responsabilitat proveir-ho.", "Make sure to EXPORT the chat log. The staff might request your exported chat log JSON in order to solve discrepancies. It is your responsibility to store it.": "Assegura't d' EXPORTAR el registre del xat. Els administradors poden demanar-te elregistre del xat en cas de discrepàncies. És la teva responsabilitat proveir-ho.",
"Invalid address": "Direcció invàlida", "Invalid address": "Direcció invàlida",
"Unable to validate address, check bitcoind backend": "No ha estat possible validar l'adreça, comprovar el backend bitcoind", "Unable to validate address, check bitcoind backend": "No ha estat possible validar l'adreça, comprovar el backend bitcoind",
"Submit payout info for {{amountSats}} Sats": "Envia info per rebre {{amountSats}} Sats", "Submit payout info for {{amountSats}} Sats": "Envia info per rebre {{amountSats}} Sats",
"Submit a valid invoice for {{amountSats}} Satoshis.": "Envia una factura per {{amountSats}} Sats", "Submit a valid invoice for {{amountSats}} Satoshis.": "Envia una factura per {{amountSats}} Sats",
"Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC.": "Abans de deixar-te enviar {{amountFiat}} {{currencyCode}}, volem assegurar-nos que pots rebre BTC.", "Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC.": "Abans de deixar-te enviar {{amountFiat}} {{currencyCode}}, volem assegurar-nos que pots rebre BTC.",