Skip to content

Commit 88df6cc

Browse files
Merge pull request #1674 from atsign-foundation/1615-npt-desktop-refresh-button
fix: npt refresh problems resolved.
2 parents 865f55e + 19aec48 commit 88df6cc

25 files changed

+123
-62
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import 'dart:developer';
2+
3+
import 'package:at_client_mobile/at_client_mobile.dart';
4+
import 'package:flutter_bloc/flutter_bloc.dart';
5+
import 'package:npt_flutter/app.dart';
6+
import 'package:npt_flutter/features/profile_list/bloc/profile_list_bloc.dart';
7+
8+
class ProfileProgressListener extends SyncProgressListener {
9+
@override
10+
void onSyncProgressEvent(SyncProgress syncProgress) {
11+
final profileListBlock = App.navState.currentContext!.read<ProfileListBloc>();
12+
13+
if (syncProgress.syncStatus == SyncStatus.success &&
14+
(profileListBlock.state is ProfileListLoaded &&
15+
(profileListBlock.state as ProfileListLoaded).profiles.isEmpty)) {
16+
profileListBlock.add(const ProfileListLoadEvent());
17+
log('ProfileProgressListener: ProfileListLoadEvent triggered to reload profiles');
18+
}
19+
}
20+
}

packages/dart/npt_flutter/lib/features/onboarding/widgets/activate_atsign_dialog.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ class _ActivateAtsignDialogState extends State<ActivateAtsignDialog> {
133133
setState(() {
134134
status = ActivationStatus.otpWait;
135135
});
136+
// pinFocusNode.
137+
if (!pinFocusNode.hasFocus) {
138+
pinFocusNode.requestFocus();
139+
}
136140
} else {
137141
if (!mounted) return;
138142
if (status == ActivationStatus.preparing) {
@@ -148,9 +152,6 @@ class _ActivateAtsignDialogState extends State<ActivateAtsignDialog> {
148152
),
149153
);
150154
}
151-
if (!pinFocusNode.hasFocus) {
152-
pinFocusNode.requestFocus();
153-
}
154155
}
155156

156157
Widget get cancelButton => TextButton(

packages/dart/npt_flutter/lib/features/onboarding/widgets/at_directory_selector.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class _AtDirectorySelectorState extends State<AtDirectorySelector> {
2323
Widget build(BuildContext context) {
2424
final rootDomains = Constants.getRootDomains(context);
2525
return BlocBuilder<OnboardingCubit, OnboardingState>(builder: (context, state) {
26-
controller.value = TextEditingValue(text: state.rootDomain);
26+
controller.value =
27+
TextEditingValue(text: state.rootDomain, selection: TextSelection.collapsed(offset: state.rootDomain.length));
2728
return TextFormField(
2829
enabled: !widget.options.containsKey(state.atSign),
2930
controller: controller,

packages/dart/npt_flutter/lib/features/onboarding/widgets/atsign_selector.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class _AtsignSelectorState extends State<AtsignSelector> {
2121
@override
2222
Widget build(BuildContext context) {
2323
return BlocBuilder<OnboardingCubit, OnboardingState>(builder: (context, state) {
24-
controller.value = TextEditingValue(text: state.atSign);
24+
controller.value =
25+
TextEditingValue(text: state.atSign, selection: TextSelection.collapsed(offset: state.atSign.length));
2526
return TextFormField(
2627
controller: controller,
2728
onChanged: (atsign) {

packages/dart/npt_flutter/lib/features/onboarding/widgets/onboarding_button.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import 'package:npt_flutter/constants.dart';
1515
import 'package:npt_flutter/features/onboarding/onboarding.dart';
1616
import 'package:npt_flutter/features/onboarding/util/atsign_manager.dart';
1717
import 'package:npt_flutter/features/onboarding/util/onboarding_util.dart';
18+
import 'package:npt_flutter/features/onboarding/util/profile_progress_listener.dart';
1819
import 'package:npt_flutter/features/onboarding/widgets/activate_atsign_dialog.dart';
1920
import 'package:npt_flutter/features/onboarding/widgets/onboarding_dialog.dart';
2021
import 'package:npt_flutter/routes.dart';
@@ -136,13 +137,15 @@ class _OnboardingButtonState extends State<OnboardingButton> {
136137
switch (onboardingResult?.status ?? AtOnboardingResultStatus.cancel) {
137138
case AtOnboardingResultStatus.success:
138139
await initializeContactsService(rootDomain: rootDomain);
140+
AtClientManager.getInstance().atClient.syncService.addProgressListener(ProfileProgressListener());
139141
postOnboard(onboardingResult!.atsign!, rootDomain);
140142
final result = await saveAtsignInformation(
141143
AtsignInformation(
142144
atSign: onboardingResult.atsign!,
143145
rootDomain: rootDomain,
144146
),
145147
);
148+
146149
log('atsign result is:$result');
147150

148151
if (!mounted) return;

packages/dart/npt_flutter/lib/features/profile/widgets/profile_popup_menu_button.dart

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,6 @@ class ProfilePopupMenuButton extends StatelessWidget {
8686
strings.yaml: Export.getExportCallback(ExportableProfileFiletype.yaml, [json]),
8787
}));
8888
}),
89-
PopupMenuItem(
90-
child: Row(
91-
children: [
92-
PhosphorIcon(PhosphorIcons.arrowClockwise()),
93-
gapW10,
94-
Text(strings.refresh),
95-
],
96-
),
97-
onTap: () {
98-
context.read<ProfileBloc>().add(const ProfileLoadEvent(useCache: false));
99-
}),
10089
PopupMenuItem(
10190
child: Row(
10291
children: [

packages/dart/npt_flutter/lib/features/profile_form/widgets/profile_device_at_sign_text_field.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ class _ProfileDeviceAtSignTextFieldState extends State<ProfileDeviceAtSignTextFi
3636
},
3737
builder: (BuildContext context, String? state) {
3838
if (state == null) return gap0;
39-
Future.microtask(() => controller.text = state);
39+
Future.microtask(() => controller.value =
40+
TextEditingValue(text: state, selection: TextSelection.collapsed(offset: state.length)));
4041
return SizedBox(
4142
width: Sizes.p300,
4243
height: Sizes.p80,

packages/dart/npt_flutter/lib/features/profile_form/widgets/profile_relay_at_sign_text_field.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
44
import 'package:npt_flutter/features/profile/profile.dart';
55
import 'package:npt_flutter/styles/sizes.dart';
66
import 'package:npt_flutter/util/form_validator.dart';
7+
import 'package:npt_flutter/util/general_extensions.dart';
78

89
class ProfileRelayAtSignTextField extends StatefulWidget {
910
const ProfileRelayAtSignTextField({super.key});
@@ -25,7 +26,8 @@ class _ProfileRelayAtSignTextFieldState extends State<ProfileRelayAtSignTextFiel
2526
},
2627
builder: (BuildContext context, String? relayAtsign) {
2728
if (relayAtsign == null) return gap0;
28-
Future.microtask(() => controller.text = relayAtsign);
29+
Future.microtask(() => controller.value =
30+
TextEditingValue(text: relayAtsign, selection: TextSelection.collapsed(offset: relayAtsign.length)));
2931
return SizedBox(
3032
width: Sizes.p200,
3133
height: Sizes.p70,
@@ -38,9 +40,9 @@ class _ProfileRelayAtSignTextFieldState extends State<ProfileRelayAtSignTextFiel
3840
),
3941
validator: FormValidator.validateEmptyRelayField,
4042
onChanged: (value) {
41-
if (!value.startsWith('@')) {
42-
value = '@$value';
43-
}
43+
value = value.atsignify();
44+
controller.value =
45+
TextEditingValue(text: value, selection: TextSelection.collapsed(offset: value.length));
4446
var bloc = context.read<ProfileBloc>();
4547
bloc.add(ProfileEditEvent(
4648
profile: (bloc.state as ProfileLoadedState).profile.copyWith(relayAtsign: value),

packages/dart/npt_flutter/lib/features/profile_form/widgets/profile_relay_quick_buttons.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ class ProfileRelayQuickButtons extends StatelessWidget {
6666
),
6767
),
6868
),
69-
const ProfileRelayAtSignTextField(),
69+
const Padding(
70+
padding: EdgeInsets.only(top: Sizes.p4),
71+
child: ProfileRelayAtSignTextField(),
72+
),
7073
],
7174
),
7275
)),

packages/dart/npt_flutter/lib/features/profile_list/view/profile_list_view.dart

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import 'dart:developer';
2+
3+
import 'package:at_client_mobile/at_client_mobile.dart';
14
import 'package:flutter/material.dart';
25
import 'package:flutter_bloc/flutter_bloc.dart';
36
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -46,7 +49,8 @@ class ProfileListView extends StatelessWidget {
4649

4750
final profiles = state.profiles.toList();
4851
final isFullProfile = profiles.isNotEmpty;
49-
52+
log('profile: isFullProfile: $isFullProfile');
53+
AtClientManager.getInstance().atClient.syncService.isInSync();
5054
return Stack(
5155
children: [
5256
Align(
@@ -68,8 +72,6 @@ class ProfileListView extends StatelessWidget {
6872
gapW10,
6973
ProfileListImportButton(),
7074
gapW10,
71-
ProfileListRefreshButton(),
72-
gapW10,
7375
ProfileSelectedExportButton(),
7476
gapW10,
7577
ProfileSelectedDeleteButton(),
@@ -106,13 +108,34 @@ class ProfileListView extends StatelessWidget {
106108
alignment: Alignment.center,
107109
child: SvgPicture.asset('assets/empty_state_profile_bg.svg'),
108110
),
109-
Align(
110-
alignment: Alignment.bottomCenter,
111-
child: Text(
112-
strings.emptyProfileMessage,
113-
textAlign: TextAlign.center,
114-
),
115-
),
111+
FutureBuilder(
112+
future: AtClientManager.getInstance().atClient.syncService.isInSync(),
113+
builder: (context, AsyncSnapshot<bool> snapshot) {
114+
if (snapshot.connectionState == ConnectionState.waiting) {
115+
return const CircularProgressIndicator();
116+
}
117+
if (snapshot.hasData && snapshot.data == false) {
118+
return Align(
119+
alignment: Alignment.bottomCenter,
120+
child: Row(
121+
mainAxisAlignment: MainAxisAlignment.center,
122+
children: [
123+
Text(
124+
strings.syncInProgress,
125+
textAlign: TextAlign.center,
126+
),
127+
],
128+
),
129+
);
130+
}
131+
return Align(
132+
alignment: Alignment.bottomCenter,
133+
child: Text(
134+
strings.emptyProfileMessage,
135+
textAlign: TextAlign.center,
136+
),
137+
);
138+
}),
116139
],
117140
),
118141
],

packages/dart/npt_flutter/lib/features/settings/view/settings_view.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ class SettingsView extends StatelessWidget {
4343
crossAxisAlignment: CrossAxisAlignment.start,
4444
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
4545
children: [
46-
// gapH30,
47-
CustomTextButton.discord(),
48-
CustomTextButton.email(),
46+
gapH10,
47+
CustomTextButton.backUpYourKey(),
4948
CustomTextButton.faq(),
50-
CustomTextButton.privacyPolicy(),
49+
CustomTextButton.email(),
50+
CustomTextButton.discord(),
5151
CustomTextButton.feedback(),
52-
CustomTextButton.backUpYourKey(),
52+
CustomTextButton.privacyPolicy(),
5353
CustomTextButton.signOut(),
5454
ContactListTile(),
5555
],

packages/dart/npt_flutter/lib/features/settings/widgets/contact_list_tile.dart

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,18 @@ class ContactListTile extends StatelessWidget {
2121
builder: ((context, snapshot) {
2222
if (snapshot.hasData) {
2323
return Padding(
24-
padding: const EdgeInsets.symmetric(horizontal: 13.0),
24+
padding: const EdgeInsets.symmetric(horizontal: Sizes.p15),
2525
child: Container(
2626
decoration: BoxDecoration(
2727
borderRadius: BorderRadius.circular(Sizes.p10),
2828
color: AppColor.cardColorDark,
2929
),
3030
child: ListTile(
31+
contentPadding: const EdgeInsets.symmetric(horizontal: Sizes.p30),
32+
dense: true,
3133
shape: RoundedRectangleBorder(
3234
borderRadius: BorderRadius.circular(Sizes.p8.toFont),
3335
),
34-
leading: CircleAvatar(
35-
radius: Sizes.p18.toFont,
36-
backgroundColor: AppColor.primaryColor,
37-
backgroundImage: snapshot.data!['image'] != null ? MemoryImage(snapshot.data!['image']) : null,
38-
),
3936
title: Text(
4037
snapshot.data?['name'] ?? '',
4138
style: bodyMedium.copyWith(fontSize: 8.toFont),
@@ -48,9 +45,6 @@ class ContactListTile extends StatelessWidget {
4845
);
4946
} else {
5047
return ListTile(
51-
leading: const CircleAvatar(
52-
child: Icon(Icons.person),
53-
),
5448
title: Text(strings.noName),
5549
subtitle: Text(strings.noAtsign),
5650
);

packages/dart/npt_flutter/lib/features/settings/widgets/settings_relay_at_sign_text_field.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
44
import 'package:npt_flutter/features/settings/settings.dart';
55
import 'package:npt_flutter/styles/sizes.dart';
66
import 'package:npt_flutter/util/form_validator.dart';
7+
import 'package:npt_flutter/util/general_extensions.dart';
78

89
class SettingsRelayAtSignTextField extends StatefulWidget {
910
const SettingsRelayAtSignTextField({super.key});
@@ -25,18 +26,23 @@ class _SettingsRelayAtSignTextFieldState extends State<SettingsRelayAtSignTextFi
2526
},
2627
builder: (BuildContext context, String? relayAtsign) {
2728
if (relayAtsign == null) return gap0;
28-
Future.microtask(() => controller.text = relayAtsign);
29+
Future.microtask(() => controller.value =
30+
TextEditingValue(text: relayAtsign, selection: TextSelection.collapsed(offset: relayAtsign.length)));
2931
return SizedBox(
3032
width: Sizes.p200,
3133
height: Sizes.p70,
3234
child: TextFormField(
3335
controller: controller,
3436
autovalidateMode: AutovalidateMode.onUserInteraction,
35-
validator: FormValidator.validateRequiredAtsignField,
37+
validator: FormValidator.validateEmptyRelayField,
3638
decoration: InputDecoration(
3739
labelText: AppLocalizations.of(context)!.custom,
40+
errorMaxLines: 2,
3841
),
3942
onChanged: (value) {
43+
value = value.atsignify();
44+
controller.value =
45+
TextEditingValue(text: value, selection: TextSelection.collapsed(offset: value.length));
4046
var bloc = context.read<SettingsBloc>();
4147
bloc.add(SettingsEditEvent(
4248
settings: (bloc.state as SettingsLoadedState).settings.copyWith(relayAtsign: value),

packages/dart/npt_flutter/lib/localization/app_en.arb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"atsignDialogTitle": "AtSign",
1616
"back": "Back",
1717
"backupKeyDialogTitle": "Please select a file to export to:",
18-
"backupYourKey": "Back up your Key",
18+
"backupYourKey": "Back Up Your Key",
1919
"cancel": "Cancel",
2020
"confirm": "Confirm",
2121
"connected": "Connected",
@@ -128,6 +128,7 @@
128128
"status": "Status",
129129
"stopping": "Stopping",
130130
"submit": "Submit",
131+
"syncInProgress": "Sync in progress.",
131132
"validationErrorAtsignField": "Field must be a valid atsign that starts with @",
132133
"validationErrorDeviceNameField": "Field can only contain lowercase letters, digits, underscores.",
133134
"validationErrorEmptyField": "This field cannot be left blank",

packages/dart/npt_flutter/lib/localization/app_es.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
"status": "Estado",
129129
"stopping": "Apagando",
130130
"submit": "Enviar",
131+
"syncInProgress": "Sincronización en curso.",
131132
"validationErrorAtsignField": "El campo debe ser un atSign válido que comience con @",
132133
"validationErrorDeviceNameField": "El campo solo puede contener letras minúsculas, dígitos, guiones bajos.",
133134
"validationErrorEmptyField": "Este campo no puede quedar vacío",

packages/dart/npt_flutter/lib/localization/app_pt.arb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"done": "Concluído",
3535
"duplicate": "Duplicar",
3636
"edit": "Editar",
37-
"email": "Suporte por E-mail",
37+
"email": "Suporte por Email",
3838
"emptyProfileMessage": "Nenhum perfil encontrado\nCrie ou importe um perfil para começar a usar NoPorts.",
3939
"enableLogging": "Habilitar Log",
4040
"errorAtKeySaveFailed": "Falha ao salvar o arquivo atKeys: {error}",
@@ -70,7 +70,7 @@
7070
"minimal": "Simples",
7171
"next": "Próximo",
7272
"noAtsign": "Sem atSign",
73-
"noEmailClientAvailable": "Nenhum cliente de e-mail disponível",
73+
"noEmailClientAvailable": "Nenhum cliente de email disponível",
7474
"noName": "Sem Nome",
7575
"noPorts": "NoPorts",
7676
"onboard": "Integrar",
@@ -128,6 +128,7 @@
128128
"status": "Status",
129129
"stopping": "Desligando",
130130
"submit": "Enviar",
131+
"syncInProgress": "Sincronização em andamento.",
131132
"validationErrorAtsignField": "O campo deve ser um atSign válido que comece com @",
132133
"validationErrorDeviceNameField": "O campo só pode conter letras minúsculas, dígitos e underscores.",
133134
"validationErrorEmptyField": "Este campo não pode ser deixado em branco",

packages/dart/npt_flutter/lib/localization/app_pt_BR.arb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"done": "Concluído",
3535
"duplicate": "Duplicar",
3636
"edit": "Editar",
37-
"email": "Suporte por E-mail",
37+
"email": "Suporte por Email",
3838
"emptyProfileMessage": "Nenhum perfil encontrado\nCrie ou importe um perfil para começar a usar NoPorts.",
3939
"enableLogging": "Habilitar Log",
4040
"errorAtKeySaveFailed": "Falha ao salvar o arquivo atKeys: {error}",
@@ -70,7 +70,7 @@
7070
"minimal": "Simples",
7171
"next": "Próximo",
7272
"noAtsign": "Sem atSign",
73-
"noEmailClientAvailable": "Nenhum cliente de e-mail disponível",
73+
"noEmailClientAvailable": "Nenhum cliente de email disponível",
7474
"noName": "Sem Nome",
7575
"noPorts": "NoPorts",
7676
"onboard": "Integrar",
@@ -128,6 +128,7 @@
128128
"status": "Status",
129129
"stopping": "Desligando",
130130
"submit": "Enviar",
131+
"syncInProgress": "Sincronização em andamento.",
131132
"validationErrorAtsignField": "O campo deve ser um atSign válido que comece com @",
132133
"validationErrorDeviceNameField": "O campo só pode conter letras minúsculas, dígitos e underscores.",
133134
"validationErrorEmptyField": "Este campo não pode ser deixado em branco",

packages/dart/npt_flutter/lib/localization/app_zh.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
"status": "状态",
129129
"stopping": "正在关闭",
130130
"submit": "提交",
131+
"syncInProgress": "同步进行中。",
131132
"validationErrorAtsignField": "字段必须是以 @ 开头的有效 atsign",
132133
"validationErrorDeviceNameField": "字段只能包含小写字母、数字和下划线。",
133134
"validationErrorEmptyField": "此字段不能为空",

0 commit comments

Comments
 (0)