feat(block2): trust UI — vouch for a person in chat (web of trust)
- TrustCubit: reads how many vouch for the peer + whether YOU do; toggleVouch certifies/revokes over TrustTransport; never vouches for self; offline-safe. Kept simple — the full known-member rule (threshold+distance) and its bootstrap set are still-open policy (network-trust §2); a live count + your vouch is the honest first step. - Chat screen now opens ONE session carrying both messaging AND trust (the shared-connection shape), and shows a slim vouch banner: 'Vouched for by N' + an 'I know this person' / 'You vouch for them' toggle. - i18n en/es/pt (human words: 'I know this person', not 'certify'). Tests: 4 trust cubit + messaging + chat, 10 green; analyzer clean.
This commit is contained in:
parent
4326e79419
commit
7cba4f7fcf
10 changed files with 367 additions and 17 deletions
|
|
@ -366,5 +366,11 @@
|
|||
"send": "Send",
|
||||
"empty": "No messages yet — say hello",
|
||||
"offline": "Set up sharing to send messages"
|
||||
},
|
||||
"trust": {
|
||||
"none": "No one vouches for them yet",
|
||||
"count": "Vouched for by {n}",
|
||||
"vouch": "I know this person",
|
||||
"vouched": "You vouch for them"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -366,5 +366,11 @@
|
|||
"send": "Enviar",
|
||||
"empty": "Aún no hay mensajes — saluda",
|
||||
"offline": "Configura el compartir para enviar mensajes"
|
||||
},
|
||||
"trust": {
|
||||
"none": "Nadie los avala aún",
|
||||
"count": "Avalada por {n}",
|
||||
"vouch": "Conozco a esta persona",
|
||||
"vouched": "Avalas a esta persona"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -362,5 +362,11 @@
|
|||
"send": "Enviar",
|
||||
"empty": "Ainda não há mensagens — diz olá",
|
||||
"offline": "Configura a partilha para enviar mensagens"
|
||||
},
|
||||
"trust": {
|
||||
"none": "Ainda ninguém os avaliza",
|
||||
"count": "Avalizada por {n}",
|
||||
"vouch": "Conheço esta pessoa",
|
||||
"vouched": "Avalizas esta pessoa"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 3
|
||||
/// Strings: 974 (324 per locale)
|
||||
/// Strings: 986 (328 per locale)
|
||||
///
|
||||
/// Built on 2026-07-10 at 08:58 UTC
|
||||
/// Built on 2026-07-10 at 09:03 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint, unused_import
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ class Translations with BaseTranslations<AppLocale, Translations> {
|
|||
late final Translations$unit$en unit = Translations$unit$en.internal(_root);
|
||||
late final Translations$market$en market = Translations$market$en.internal(_root);
|
||||
late final Translations$chat$en chat = Translations$chat$en.internal(_root);
|
||||
late final Translations$trust$en trust = Translations$trust$en.internal(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
|
|
@ -1162,6 +1163,27 @@ class Translations$chat$en {
|
|||
String get offline => 'Set up sharing to send messages';
|
||||
}
|
||||
|
||||
// Path: trust
|
||||
class Translations$trust$en {
|
||||
Translations$trust$en.internal(this._root);
|
||||
|
||||
final Translations _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
|
||||
/// en: 'No one vouches for them yet'
|
||||
String get none => 'No one vouches for them yet';
|
||||
|
||||
/// en: 'Vouched for by {n}'
|
||||
String count({required Object n}) => 'Vouched for by ${n}';
|
||||
|
||||
/// en: 'I know this person'
|
||||
String get vouch => 'I know this person';
|
||||
|
||||
/// en: 'You vouch for them'
|
||||
String get vouched => 'You vouch for them';
|
||||
}
|
||||
|
||||
// Path: intro.slides
|
||||
class Translations$intro$slides$en {
|
||||
Translations$intro$slides$en.internal(this._root);
|
||||
|
|
@ -1945,6 +1967,10 @@ extension on Translations {
|
|||
'chat.send' => 'Send',
|
||||
'chat.empty' => 'No messages yet — say hello',
|
||||
'chat.offline' => 'Set up sharing to send messages',
|
||||
'trust.none' => 'No one vouches for them yet',
|
||||
'trust.count' => ({required Object n}) => 'Vouched for by ${n}',
|
||||
'trust.vouch' => 'I know this person',
|
||||
'trust.vouched' => 'You vouch for them',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class TranslationsEs extends Translations with BaseTranslations<AppLocale, Trans
|
|||
@override late final _Translations$unit$es unit = _Translations$unit$es._(_root);
|
||||
@override late final _Translations$market$es market = _Translations$market$es._(_root);
|
||||
@override late final _Translations$chat$es chat = _Translations$chat$es._(_root);
|
||||
@override late final _Translations$trust$es trust = _Translations$trust$es._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
|
|
@ -646,6 +647,19 @@ class _Translations$chat$es extends Translations$chat$en {
|
|||
@override String get offline => 'Configura el compartir para enviar mensajes';
|
||||
}
|
||||
|
||||
// Path: trust
|
||||
class _Translations$trust$es extends Translations$trust$en {
|
||||
_Translations$trust$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get none => 'Nadie los avala aún';
|
||||
@override String count({required Object n}) => 'Avalada por ${n}';
|
||||
@override String get vouch => 'Conozco a esta persona';
|
||||
@override String get vouched => 'Avalas a esta persona';
|
||||
}
|
||||
|
||||
// Path: intro.slides
|
||||
class _Translations$intro$slides$es extends Translations$intro$slides$en {
|
||||
_Translations$intro$slides$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
|
@ -1313,6 +1327,10 @@ extension on TranslationsEs {
|
|||
'chat.send' => 'Enviar',
|
||||
'chat.empty' => 'Aún no hay mensajes — saluda',
|
||||
'chat.offline' => 'Configura el compartir para enviar mensajes',
|
||||
'trust.none' => 'Nadie los avala aún',
|
||||
'trust.count' => ({required Object n}) => 'Avalada por ${n}',
|
||||
'trust.vouch' => 'Conozco a esta persona',
|
||||
'trust.vouched' => 'Avalas a esta persona',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class TranslationsPt extends Translations with BaseTranslations<AppLocale, Trans
|
|||
@override late final _Translations$unit$pt unit = _Translations$unit$pt._(_root);
|
||||
@override late final _Translations$market$pt market = _Translations$market$pt._(_root);
|
||||
@override late final _Translations$chat$pt chat = _Translations$chat$pt._(_root);
|
||||
@override late final _Translations$trust$pt trust = _Translations$trust$pt._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
|
|
@ -642,6 +643,19 @@ class _Translations$chat$pt extends Translations$chat$en {
|
|||
@override String get offline => 'Configura a partilha para enviar mensagens';
|
||||
}
|
||||
|
||||
// Path: trust
|
||||
class _Translations$trust$pt extends Translations$trust$en {
|
||||
_Translations$trust$pt._(TranslationsPt root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsPt _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get none => 'Ainda ninguém os avaliza';
|
||||
@override String count({required Object n}) => 'Avalizada por ${n}';
|
||||
@override String get vouch => 'Conheço esta pessoa';
|
||||
@override String get vouched => 'Avalizas esta pessoa';
|
||||
}
|
||||
|
||||
// Path: intro.slides
|
||||
class _Translations$intro$slides$pt extends Translations$intro$slides$en {
|
||||
_Translations$intro$slides$pt._(TranslationsPt root) : this._root = root, super.internal(root);
|
||||
|
|
@ -1305,6 +1319,10 @@ extension on TranslationsPt {
|
|||
'chat.send' => 'Enviar',
|
||||
'chat.empty' => 'Ainda não há mensagens — diz olá',
|
||||
'chat.offline' => 'Configura a partilha para enviar mensagens',
|
||||
'trust.none' => 'Ainda ninguém os avaliza',
|
||||
'trust.count' => ({required Object n}) => 'Avalizada por ${n}',
|
||||
'trust.vouch' => 'Conheço esta pessoa',
|
||||
'trust.vouched' => 'Avalizas esta pessoa',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue