Skip to content

Commit

Permalink
feat(logo)
Browse files Browse the repository at this point in the history
add logo on welcome back page
remove extra button to forget wallet
add logo when user has no private drives
  • Loading branch information
thiagocarvalhodev committed Dec 18, 2024
1 parent 6fed877 commit bc22d07
Show file tree
Hide file tree
Showing 18 changed files with 227 additions and 102 deletions.
6 changes: 3 additions & 3 deletions lib/arns/domain/arns_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ abstract class ARNSRepository {
Future<List<ArnsRecord>> getActiveARNSRecordsForFile(String fileId);
Future<void> waitForARNSRecordsToUpdate();
Future<PrimaryNameDetails> getPrimaryName(String address,
{bool update = false});
{bool update = false, bool getLogo = true});

factory ARNSRepository({
required ArioSDK sdk,
Expand Down Expand Up @@ -377,14 +377,14 @@ class _ARNSRepository implements ARNSRepository {

@override
Future<PrimaryNameDetails> getPrimaryName(String address,
{bool update = false}) async {
{bool update = false, bool getLogo = true}) async {
logger.d('Getting primary name for address: $address');

if (!update && _cachedPrimaryName != null) {
return _cachedPrimaryName!;
}

final primaryName = await _sdk.getPrimaryNameDetails(address);
final primaryName = await _sdk.getPrimaryNameDetails(address, getLogo);

logger.d('Primary name: $primaryName');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import 'package:ardrive/utils/plausible_event_tracker/plausible_event_tracker.da
import 'package:ardrive/utils/show_general_dialog.dart';
import 'package:ardrive_ui/ardrive_ui.dart';
import 'package:arweave/arweave.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:responsive_builder/responsive_builder.dart';
Expand Down Expand Up @@ -275,43 +274,6 @@ class _EnterYourPasswordWidgetState extends State<EnterYourPasswordWidget> {
_onSubmit();
}
}),
if (widget.alreadyLoggedIn) ...[
const SizedBox(height: 40),
Text.rich(
textAlign: TextAlign.center,
TextSpan(
children: [
TextSpan(
// TODO: create/update localization key
text: appLocalizationsOf(context).forgetWallet,
style: typography.paragraphLarge(
color: colorTokens.textLow,
fontWeight: ArFontWeight.semiBold),
recognizer: TapGestureRecognizer()
..onTap = () {
Navigator.of(context).pop();
widget.loginBloc.add(const ForgetWallet());
PlausibleEventTracker
.trackClickForgetWalletTextButton();
},
),
],
),
)
],
// if (isArioSDKSupportedOnPlatform())
// Padding(
// padding: const EdgeInsets.only(top: 16.0),
// child: ArDriveButtonNew(
// variant: ButtonVariant.outline,
// text: 'Advanced Settings',
// maxHeight: 40,
// typography: typography,
// onPressed: () {
// showGatewaySwitcherModal(context);
// },
// ),
// )
],
),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import 'package:ardrive/authentication/components/login_modal.dart';
import 'package:ardrive/authentication/login/blocs/login_bloc.dart';
import 'package:ardrive/authentication/login/views/modals/common.dart';
import 'package:ardrive/authentication/login/views/modals/enter_your_password_modal.dart';
import 'package:ardrive/components/profile_card.dart';
import 'package:ardrive/misc/resources.dart';
import 'package:ardrive/services/ethereum/provider/ethereum_provider_wallet.dart';
import 'package:ardrive/user/name/presentation/bloc/profile_name_bloc.dart';
import 'package:ardrive/utils/app_localizations_wrapper.dart';
import 'package:ardrive/utils/logger.dart';
import 'package:ardrive/utils/plausible_event_tracker/plausible_event_tracker.dart';
import 'package:ardrive/utils/show_general_dialog.dart';
import 'package:ardrive_ui/ardrive_ui.dart';
Expand Down Expand Up @@ -47,6 +51,14 @@ class _SecureYourWalletWidgetState extends State<SecureYourWalletWidget> {
PlausibleEventTracker.trackPageview(
page: PlausiblePageView.createAndConfirmPasswordPage,
);

widget.wallet.getAddress().then((walletAddress) {
logger.d('Loading profile name for anonymous user $walletAddress');

context
.read<ProfileNameBloc>()
.add(LoadProfileNameAnonymous(walletAddress));
});
}

@override
Expand Down Expand Up @@ -96,7 +108,40 @@ class _SecureYourWalletWidgetState extends State<SecureYourWalletWidget> {
style: typography.paragraphNormal(
color: colorTokens.textLow,
fontWeight: ArFontWeight.semiBold)),
const SizedBox(height: 40),
const SizedBox(height: 32),
if (!widget.showTutorials)
BlocBuilder<ProfileNameBloc, ProfileNameState>(
builder: (context, state) {
if (state is ProfileNameLoaded) {
return ProfileCardHeader(
walletAddress: state.walletAddress,
onPressed: () {},
isExpanded: true,
hasLogoutButton: true,
logoutTooltip: 'Forget wallet',
onClickLogout: () {
showArDriveDialog(context,
content: ForgetWalletDialog(
loginBloc: widget.loginBloc));
},
);
}

return ProfileCardHeader(
walletAddress: state.walletAddress ?? '',
onPressed: () {},
isExpanded: true,
hasLogoutButton: true,
logoutTooltip: 'Forget wallet',
onClickLogout: () {
showArDriveDialog(context,
content: ForgetWalletDialog(
loginBloc: widget.loginBloc));
},
);
},
),
const SizedBox(height: 32),
Text('Password',
style: typography.paragraphNormal(
color: colorTokens.textLow,
Expand Down
10 changes: 8 additions & 2 deletions lib/components/profile_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import 'package:ardrive/user/balance/user_balance_bloc.dart';
import 'package:ardrive/user/download_wallet/download_wallet_modal.dart';
import 'package:ardrive/user/name/presentation/bloc/profile_name_bloc.dart';
import 'package:ardrive/utils/app_localizations_wrapper.dart';
import 'package:ardrive/utils/logger.dart';
import 'package:ardrive/utils/open_url.dart';
import 'package:ardrive/utils/open_url_utils.dart';
import 'package:ardrive/utils/open_urls.dart';
Expand Down Expand Up @@ -693,6 +694,7 @@ class ProfileCardHeader extends StatelessWidget {
final maxWidth = _calculateMaxWidth(primaryName, state);
final truncatedWalletAddress =
_getTruncatedWalletAddress(primaryName, walletAddress);
logger.d('Truncated wallet address: $truncatedWalletAddress');
final tooltipMessage = primaryName.length > 20 ? primaryName : null;
return ArDriveTooltip(
message: tooltipMessage ?? '',
Expand Down Expand Up @@ -730,7 +732,9 @@ class ProfileCardHeader extends StatelessWidget {

String _getTruncatedWalletAddress(String primaryName, String walletAddress) {
if (primaryName.length > 20 || isExpanded) {
return truncateString(walletAddress, offsetStart: 10, offsetEnd: 10);
// replace the hyphen with a unicode minus to avoid truncation in the middle of the text
return truncateString(walletAddress.replaceAll('-', '−'),
offsetStart: 12, offsetEnd: 12);
}

var offsetStart = primaryName.length ~/ 2;
Expand Down Expand Up @@ -795,6 +799,7 @@ class ProfileCardHeader extends StatelessWidget {
Flexible(
child: Text(
isExpanded ? state.walletAddress! : truncatedWalletAddress,
softWrap: true,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: typography.paragraphNormal(
Expand Down Expand Up @@ -864,7 +869,8 @@ class ProfileCardHeader extends StatelessWidget {
isExpanded
? state.walletAddress
: truncatedWalletAddress,
overflow: TextOverflow.clip,
overflow: TextOverflow.ellipsis,
softWrap: true,
maxLines: 1,
style: typography.paragraphSmall(
fontWeight: ArFontWeight.book,
Expand Down
14 changes: 11 additions & 3 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import 'package:ardrive/theme/theme_switcher_state.dart';
import 'package:ardrive/turbo/services/payment_service.dart';
import 'package:ardrive/turbo/services/upload_service.dart';
import 'package:ardrive/turbo/turbo.dart';
import 'package:ardrive/user/name/domain/repository/profile_logo_repository.dart';
import 'package:ardrive/user/name/presentation/bloc/profile_name_bloc.dart';
import 'package:ardrive/user/repositories/user_preferences_repository.dart';
import 'package:ardrive/user/repositories/user_repository.dart';
Expand Down Expand Up @@ -77,6 +78,7 @@ late ArweaveService arweave;
late TurboUploadService _turboUpload;
late PaymentService _turboPayment;
late Database db;
late final LocalKeyValueStore localKeyValueStore;

void main() async {
await runZonedGuarded(() async {
Expand Down Expand Up @@ -110,13 +112,13 @@ Future<void> _runWithSentryLogging() async {
}

Future<void> _initializeServices() async {
final localStore = await LocalKeyValueStore.getInstance();
localKeyValueStore = await LocalKeyValueStore.getInstance();

await AppInfoServices().loadAppInfo();

configService = ConfigService(
appFlavors: AppFlavors(EnvFetcher()),
configFetcher: ConfigFetcher(localStore: localStore),
configFetcher: ConfigFetcher(localStore: localKeyValueStore),
);

MobileStatusBar.show();
Expand Down Expand Up @@ -360,6 +362,7 @@ class AppState extends State<App> {
BlocProvider(
create: (context) => ProfileNameBloc(
context.read<ARNSRepository>(),
context.read<ProfileLogoRepository>(),
context.read<ArDriveAuth>(),
),
),
Expand Down Expand Up @@ -523,6 +526,11 @@ class AppState extends State<App> {
),
RepositoryProvider(
create: (context) => createUploadRepository(context),
)
),
RepositoryProvider(
create: (context) => ProfileLogoRepository(
localKeyValueStore,
),
),
];
}
50 changes: 50 additions & 0 deletions lib/user/name/domain/repository/profile_logo_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'package:ardrive/utils/key_value_store.dart';
import 'package:ardrive/utils/logger.dart';

abstract class ProfileLogoRepository {
Future<String?> getProfileLogoTxId(String walletAddress);
Future<void> setProfileLogoTxId(String walletAddress, String txId);

factory ProfileLogoRepository(KeyValueStore keyValueStore) {
return ProfileLogoRepositoryImpl(
keyValueStore: keyValueStore,
);
}
}

class ProfileLogoRepositoryImpl implements ProfileLogoRepository {
final KeyValueStore _keyValueStore;

ProfileLogoRepositoryImpl({
required KeyValueStore keyValueStore,
}) : _keyValueStore = keyValueStore;

@override
Future<String?> getProfileLogoTxId(String walletAddress) async {
final lastSet =
await _keyValueStore.getString('profile_logo_last_set_$walletAddress');

if (lastSet != null &&
DateTime.now()
.isBefore(DateTime.parse(lastSet).add(const Duration(hours: 1)))) {
logger.d('Getting profile logo tx id from cache');
return _keyValueStore.getString('profile_logo_tx_id_$walletAddress');
}

return null;
}

@override
Future<void> setProfileLogoTxId(String walletAddress, String txId) async {
// set last time the profile logo was set
await _keyValueStore.putString(
'profile_logo_last_set_$walletAddress',
DateTime.now().toIso8601String(),
);

await _keyValueStore.putString(
'profile_logo_tx_id_$walletAddress',
txId,
);
}
}
36 changes: 31 additions & 5 deletions lib/user/name/presentation/bloc/profile_name_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:ardrive/arns/domain/arns_repository.dart';
import 'package:ardrive/authentication/ardrive_auth.dart';
import 'package:ardrive/user/name/domain/repository/profile_logo_repository.dart';
import 'package:ardrive/utils/logger.dart';
import 'package:ario_sdk/ario_sdk.dart';
import 'package:equatable/equatable.dart';
Expand All @@ -10,10 +11,14 @@ part 'profile_name_state.dart';

class ProfileNameBloc extends Bloc<ProfileNameEvent, ProfileNameState> {
final ARNSRepository _arnsRepository;
final ProfileLogoRepository _profileLogoRepository;
final ArDriveAuth _auth;

ProfileNameBloc(this._arnsRepository, this._auth)
: super(const ProfileNameInitial(null)) {
ProfileNameBloc(
this._arnsRepository,
this._profileLogoRepository,
this._auth,
) : super(const ProfileNameInitial(null)) {
on<LoadProfileName>((event, emit) async {
await _loadProfileName(
walletAddress: _auth.currentUser.walletAddress,
Expand Down Expand Up @@ -53,13 +58,27 @@ class ProfileNameBloc extends Bloc<ProfileNameEvent, ProfileNameState> {
bool isUserLoggedIn = true,
}) async {
try {
String? profileLogoTxId;

/// if we are not refreshing, we emit a loading state
if (!refresh) {
emit(ProfileNameLoading(walletAddress));
}

final primaryName =
await _arnsRepository.getPrimaryName(walletAddress, update: refresh);
if (refresh && !isUserLoggedIn) {
profileLogoTxId =
await _profileLogoRepository.getProfileLogoTxId(walletAddress);
}

var primaryNameDetails = await _arnsRepository.getPrimaryName(
walletAddress,
update: refresh,
getLogo: profileLogoTxId == null,
);

primaryNameDetails = primaryNameDetails.copyWith(
logo: profileLogoTxId == null ? primaryNameDetails.logo : null,
);

if (isUserLoggedIn && _auth.currentUser.walletAddress != walletAddress) {
// A user can load profile name and log out while fetching this request. Then log in again. We should not emit a profile name loaded state in this case.
Expand All @@ -68,7 +87,14 @@ class ProfileNameBloc extends Bloc<ProfileNameEvent, ProfileNameState> {
return;
}

emit(ProfileNameLoaded(primaryName, walletAddress));
if (profileLogoTxId == null && primaryNameDetails.logo != null) {
_profileLogoRepository.setProfileLogoTxId(
walletAddress,
primaryNameDetails.logo!,
);
}

emit(ProfileNameLoaded(primaryNameDetails, walletAddress));
} catch (e) {
if (e is PrimaryNameNotFoundException) {
logger.d('Primary name not found for address: $walletAddress');
Expand Down
2 changes: 1 addition & 1 deletion lib/user/name/presentation/bloc/profile_name_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sealed class ProfileNameState extends Equatable {
abstract final String? walletAddress;

@override
List<Object> get props => [];
List<Object?> get props => [walletAddress];
}

final class ProfileNameInitial extends ProfileNameState {
Expand Down
5 changes: 4 additions & 1 deletion packages/ario_sdk/lib/src/ario_sdk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@ abstract class ArioSDK {
/// Get the primary name for the given address
///
/// Throws [PrimaryNameNotFoundException] if the primary name is not found
Future<PrimaryNameDetails> getPrimaryNameDetails(String address);
Future<PrimaryNameDetails> getPrimaryNameDetails(
String address,
bool getLogo,
);
}
Loading

0 comments on commit bc22d07

Please sign in to comment.