Skip to content

Commit

Permalink
fix: user can select atsign if available in keychain when onboarding.
Browse files Browse the repository at this point in the history
  • Loading branch information
CurtlyCritchlow committed Oct 9, 2024
1 parent a4f738f commit e6522b0
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 53 deletions.
3 changes: 1 addition & 2 deletions packages/dart/npt_flutter/lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ class App extends StatelessWidget {
create: (ctx) => FavoriteBloc(ctx.read<FavoriteRepository>()),
),
],
child: BlocSelector<SettingsBloc, SettingsState, Language>(
selector: (state) {
child: BlocSelector<SettingsBloc, SettingsState, Language>(selector: (state) {
if (state is SettingsLoadedState) {
return state.settings.language;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import 'package:npt_flutter/features/logging/models/loggable.dart';
import 'package:npt_flutter/features/logging/models/logging_bloc.dart';
import 'package:npt_flutter/features/onboarding/util/atsign_manager.dart';

class AtDirectoryCubit extends LoggingCubit<LoggableString> {
AtDirectoryCubit() : super(const LoggableString('root.atsign.org'));
class AtDirectoryCubit extends LoggingCubit<AtsignInformation> {
AtDirectoryCubit() : super(const AtsignInformation(atSign: '', rootDomain: 'root.atsign.org'));

void setRootDomain(String rootDomain) => emit(LoggableString(rootDomain));
String getRootDomain() => (state.string);
void setRootDomain(String rootDomain) => emit(AtsignInformation(atSign: state.atSign, rootDomain: rootDomain));
String getRootDomain() => (state.rootDomain);

void setAtSign(String atSign) => emit(AtsignInformation(atSign: atSign, rootDomain: state.rootDomain));
String getAtSign() => (state.atSign);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import 'package:npt_flutter/app.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';

class AtsignInformation {
class AtsignInformation extends Loggable {
final String atSign;
final String rootDomain;

AtsignInformation({required this.atSign, required this.rootDomain});
const AtsignInformation({required this.atSign, required this.rootDomain});

Map<String, String> toJson() => {
"atsign": atSign,
Expand All @@ -26,6 +26,14 @@ class AtsignInformation {
rootDomain: json["root-domain"],
);
}

@override
List<Object?> get props => [atSign, rootDomain];

@override
String toString() {
return 'AtsignInformation($atSign, $rootDomain)';
}
}

// This will return a map which looks like:
Expand Down Expand Up @@ -96,7 +104,7 @@ Future<bool> saveAtsignInformation(AtsignInformation info) async {
}
try {
f.writeAsString(
jsonEncode(atSignInfo.map((e) => e.toJson())),
jsonEncode(atSignInfo.map((e) => e.toJson()).toList()),
mode: FileMode.writeOnly,
flush: true,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class AtDirectoryDialog extends StatelessWidget {
title: strings.atDirectory,
subtitle: strings.atDirectorySubtitle,
// TODO: Add success button text to the AppLocalizations
successButtonText: 'select',
successButtonText: 'Done',
children: [
OnboardingAtDirectorySelector(),
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:npt_flutter/features/logging/models/loggable.dart';
import 'package:npt_flutter/features/onboarding/cubit/at_directory_cubit.dart';
import 'package:npt_flutter/features/onboarding/util/atsign_manager.dart';

typedef OnboardingMapCallback = void Function(Map<String, String> val);

class AtsignSelector extends StatefulWidget {
AtsignSelector({
const AtsignSelector({
super.key,
});

final List<String> options = [];

@override
State<AtsignSelector> createState() => _AtsignSelectorState();
}
Expand All @@ -21,20 +19,39 @@ class _AtsignSelectorState extends State<AtsignSelector> {
final FocusNode focusNode = FocusNode();

final TextEditingController controller = TextEditingController();
List<String> options = [];
late final List<String> originalOptions;

late int originalOptionsLength;

@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
options = (await getAtsignEntries()).keys.toList();
if (mounted) context.read<AtDirectoryCubit>().setAtSign(options[0]);

controller.text = options[0];
originalOptions = List.from(options);
originalOptionsLength = options.length;
setState(() {});
});
}

@override
Widget build(BuildContext context) {
return BlocBuilder<AtDirectoryCubit, LoggableString>(builder: (context, rootDomain) {
controller.text = rootDomain.string;
return BlocBuilder<AtDirectoryCubit, AtsignInformation>(builder: (context, atsignInformation) {
controller.text = atsignInformation.atSign;
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: DropdownMenu<String>(
initialSelection: widget.options.contains(rootDomain.string) ? rootDomain.string : null,
dropdownMenuEntries: widget.options
initialSelection:
options.contains(atsignInformation.atSign) ? atsignInformation.atSign : controller.text,
dropdownMenuEntries: options
.map<DropdownMenuEntry<String>>(
(o) => DropdownMenuEntry(
value: o,
Expand All @@ -45,7 +62,7 @@ class _AtsignSelectorState extends State<AtsignSelector> {
onSelected: (value) {
if (value == null) return;

context.read<AtDirectoryCubit>().setRootDomain(value);
context.read<AtDirectoryCubit>().setAtSign(value);
},
),
),
Expand All @@ -54,7 +71,7 @@ class _AtsignSelectorState extends State<AtsignSelector> {
focusNode: focusNode,
onKeyEvent: (value) {
if (value.logicalKey == LogicalKeyboardKey.backspace) {
if (widget.options.length > 2) widget.options.removeLast();
if (options.length > originalOptionsLength) options.removeLast();
}
},
child: TextFormField(
Expand All @@ -63,13 +80,15 @@ class _AtsignSelectorState extends State<AtsignSelector> {
// validator: FormValidator.validateRequiredAtsignField,
onChanged: (value) {
// prevent the user from adding the default values to the dropdown a second time.
if (value != widget.options[0] || value != widget.options[1]) {
widget.options.add(value);
if (!originalOptions.contains(value)) {
options.add(value);

setState(() {});
}
//removes the third element making the final entry the only additional value in options. This prevents the dropdown from having more than 3 entries.
if (widget.options.length > 3) widget.options.removeAt(2);
//removes the last element making the final entry the only additional value in options. This prevents the dropdown from having more than original options + one entries.
if (options.length > originalOptionsLength + 1) options.removeAt(originalOptionsLength);

context.read<AtDirectoryCubit>().setRootDomain(value);
context.read<AtDirectoryCubit>().setAtSign(value);
},
),
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:npt_flutter/features/logging/models/loggable.dart';
import 'package:npt_flutter/features/onboarding/cubit/at_directory_cubit.dart';
import 'package:npt_flutter/features/onboarding/util/atsign_manager.dart';

typedef OnboardingMapCallback = void Function(Map<String, String> val);

Expand All @@ -18,19 +18,17 @@ class OnboardingAtDirectorySelector extends StatelessWidget {

@override
Widget build(BuildContext context) {
return BlocBuilder<AtDirectoryCubit, LoggableString>(
builder: (context, rootDomain) {
controller.text = rootDomain.string;
return BlocBuilder<AtDirectoryCubit, AtsignInformation>(builder: (context, atsignInformation) {
controller.text = atsignInformation.rootDomain;
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: DropdownMenu<String>(
initialSelection: options.contains(rootDomain.string)
? rootDomain.string
: null,
initialSelection:
options.contains(atsignInformation.rootDomain) ? atsignInformation.rootDomain : null,
dropdownMenuEntries: options
.map<DropdownMenuEntry<String>>(
(o) => DropdownMenuEntry(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:npt_flutter/constants.dart';
import 'package:npt_flutter/features/logging/models/loggable.dart';
import 'package:npt_flutter/features/onboarding/cubit/at_directory_cubit.dart';
import 'package:npt_flutter/features/onboarding/onboarding.dart';
import 'package:npt_flutter/features/onboarding/util/atsign_manager.dart';
Expand Down Expand Up @@ -87,15 +86,15 @@ class _OnboardingButtonState extends State<OnboardingButton> {
@override
Widget build(BuildContext context) {
final strings = AppLocalizations.of(context)!;
return BlocBuilder<AtDirectoryCubit, LoggableString>(builder: (context, rootDomain) {
return BlocBuilder<AtDirectoryCubit, AtsignInformation>(builder: (context, atsignInformation) {
return ElevatedButton.icon(
onPressed: () async {
final isEmptyAtsignList = (await getAtsignEntries()).isNotEmpty;
log(isEmptyAtsignList.toString());
log('atsign entries is empty state: $isEmptyAtsignList');

if (isEmptyAtsignList) await selectAtsign();

onboard(rootDomain: rootDomain.string);
onboard(rootDomain: atsignInformation.rootDomain);
},
icon: PhosphorIcon(PhosphorIcons.arrowUpRight()),
label: Text(
Expand Down
45 changes: 29 additions & 16 deletions packages/dart/npt_flutter/lib/widgets/custom_text_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import 'package:at_onboarding_flutter/services/onboarding_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:npt_flutter/app.dart';
import 'package:npt_flutter/constants.dart';
import 'package:npt_flutter/features/logging/models/loggable.dart';
import 'package:npt_flutter/features/onboarding/cubit/at_directory_cubit.dart';
import 'package:npt_flutter/features/onboarding/util/atsign_manager.dart';
import 'package:npt_flutter/features/onboarding/util/pre_offboard.dart';
import 'package:npt_flutter/features/onboarding/widgets/at_directory_dialog.dart';
import 'package:npt_flutter/features/onboarding/widgets/onboarding_button.dart';
Expand Down Expand Up @@ -94,7 +93,7 @@ class CustomTextButton extends StatelessWidget {
// final bodyMedium = Theme.of(context).textTheme.bodyMedium!;
// final bodySmall = Theme.of(context).textTheme.bodySmall!;
final strings = AppLocalizations.of(context)!;
Future<void> onTap(String rootDomain) async {
Future<void> onTap({String? rootDomain}) async {
switch (type) {
case CustomListTileType.email:
Uri emailUri = Uri(
Expand Down Expand Up @@ -134,7 +133,7 @@ class CustomTextButton extends StatelessWidget {
}
break;
case CustomListTileType.resetAtsign:
final futurePreference = await loadAtClientPreference(rootDomain);
final futurePreference = await loadAtClientPreference(rootDomain!);
if (context.mounted) {
final result = await AtOnboarding.reset(
context: context,
Expand Down Expand Up @@ -208,20 +207,34 @@ class CustomTextButton extends StatelessWidget {
}
}

return BlocBuilder<AtDirectoryCubit, LoggableString>(builder: (context, rootDomain) {
return Padding(
padding: const EdgeInsets.only(left: Sizes.p30, right: Sizes.p30, bottom: Sizes.p10),
child: TextButton.icon(
label: Text(getTitle(strings)),
onPressed: () {
onTap(rootDomain.string);
},
icon: Icon(
iconData,
if (type == CustomListTileType.resetAtsign) {
return BlocBuilder<AtDirectoryCubit, AtsignInformation>(builder: (context, atsignInformation) {
return Padding(
padding: const EdgeInsets.only(left: Sizes.p30, right: Sizes.p30, bottom: Sizes.p10),
child: TextButton.icon(
label: Text(getTitle(strings)),
onPressed: () {
onTap(rootDomain: atsignInformation.rootDomain);
},
icon: Icon(
iconData,
),
),
);
});
}
return Padding(
padding: const EdgeInsets.only(left: Sizes.p30, right: Sizes.p30, bottom: Sizes.p10),
child: TextButton.icon(
label: Text(getTitle(strings)),
onPressed: () {
onTap();
},
icon: Icon(
iconData,
),
);
});
),
);
}
}

Expand Down

0 comments on commit e6522b0

Please sign in to comment.