Files
hash-wallet/lib/nostr/nostr_api.dart
T
c746b85a4b UI updates (#2368)
* Add Black theme

* Fix black theme

* Add WixMadefor Font

* feat: Enhance theme setup

This change:
- Adds support for custom themes
- Updates theme retrieval logic to ensure the right theme is used based on user preferences(especially for custom themes).

* Add black custom colors

* Add custom accent colors

* feat: Restructure custom colors handling for themes

* feat: Integrate new custom colors structure across various components - WIP

* feat: Integrate new custom colors structure across various components, black theme now ready for tests

* feat: Add new accent color themes and update theme selection UI

- Enhanced theme selection UI in display settings to support accent color choices.
- Updated theme handling logic to accommodate new accent color variants.

* Minor updates to display_settings_page.dart

* Update settings_theme_choice.dart

* Revert accidental change in display_settings_page.dart

* Revert WixMadeFor font, fix SVG colors for CakeImageWidget, and test some color changes

* Update Monero Orange

* fix: Remove unused custom colors

* Test outline

* Test spacing and colors

* Add padding

* Remove outline

* Add other accent colors

* Update display_settings_view_model.dart

* Update names and fix switch case

* Add outline and update dark_theme.dart colors

* Add gradient to option_tile.dart

* Update icons

* Update some colors

* Switch option_tile.dart to TextButton

* Add updated icons

* Fix icon resolution

* Cleanup old icons + Update pubspec_base.yaml

* Remove unused fonts

* Update more icons

* Update image paths

* Remove more icons + update some component colors

* Add back DAI icon

* Fix errors

* feat: Implement OLED mode for BlackTheme

* feat: Add OLED mode for BlackTheme and localizations

* feat: Implement OLED mode for Black Theme

* refactor: Remove unused theme parameters and set up easy access to toggleKnob custom colors

* fix: Cleanup UI and overflows

* feat: Persist black theme selection if OS theme mode while app is in system mode

* fix: OS theme change when app is in background restrict pin screen from proceed

* Fix theme picker sizing

* Update lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* refactor: Enhance theme access by introducing ThemeX extension for easier retrieval of current theme and custom colors

* refactor: Remove currentTheme parameter from GradientBackground widget and adjust across affected widgets

* refactor: Remove currentTheme parameter from StandardSwitch and SettingsSwitcherCell, using ThemeX extension for theme access

* refactor: Remove currentTheme parameter from various widgets dependent on SettingsSwitcherCell and StandardxSwitcher, using ThemeX extension for theme access

* refactor: Remove currentTheme in bottomsheets and related widgets, switching to theme extension

* refactor: Remove constructor theme access in OptionTile and related widgets, switching to theme extension

* refactor: Switch bottomsheet related widgets to use theme extension instead of constructor access

* refactor: Migrate currentTheme access from constructor based to extension base

* refactor: Switch theme access from constructor base to extension base [skip ci]

* refactor: Migrate more widgets to use extension based theme access and clean up code

* refactor: Update theme access across multiple widgets to use the new theme extension

* refactor: Clean up theme access in various widgets, moving to extension-based theme usage

* refactor: Make theme picker preview responsive

* fix: Persist saved black theme accent when app is put in background and brought back

* remove unused variables [skip ci]

---------

Co-authored-by: Blazebrain <davidadegoke16@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
2025-10-10 16:00:39 +03:00

151 lines
4.2 KiB
Dart

import 'dart:convert';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/nostr/nostr_user.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:flutter/material.dart';
import 'package:nostr_tools/nostr_tools.dart';
class NostrProfileHandler {
static final relayToDomainMap = {
'relay.snort.social': 'snort.social',
};
static Nip05 _nip05 = Nip05();
static Future<ProfilePointer?> queryProfile(BuildContext context, String nip05Address) async {
var profile = await _nip05.queryProfile(nip05Address);
if (profile?.pubkey != null) {
if (profile?.relays?.isNotEmpty == true) {
return profile;
} else {
await _showErrorDialog(context, S.of(context).no_relays, S.of(context).no_relays_message);
}
}
return null;
}
static Future<UserMetadata?> processRelays(
BuildContext context,
ProfilePointer profile,
String nip05Address,
) async {
String userDomain = _extractDomain(nip05Address);
const int metaData = 0;
for (String relayUrl in profile.relays ?? []) {
final relayDomain = _getDomainFromRelayUrl(relayUrl);
final formattedRelayDomain = relayToDomainMap[relayDomain] ?? relayDomain;
if (formattedRelayDomain == userDomain) {
final userDomainData = await _fetchInfoFromRelay(relayUrl, profile.pubkey, [metaData]);
if (userDomainData != null) {
return userDomainData;
}
}
}
await _showErrorDialog(context, S.of(context).no_relays, S.of(context).no_relay_on_domain);
String? chosenRelayUrl =
await _showRelayChoiceDialog(context, profile.relays ?? []);
if (chosenRelayUrl != null) {
final userData = await _fetchInfoFromRelay(chosenRelayUrl, profile.pubkey, [metaData]);
if (userData != null) {
return userData;
}
}
return null;
}
static Future<UserMetadata?> _fetchInfoFromRelay(
String relayUrl, String userPubKey, List<int> kinds) async {
try {
final relay = RelayApi(relayUrl: relayUrl);
final stream = await relay.connect();
relay.sub([
Filter(
kinds: kinds,
authors: [userPubKey],
)
]);
await for (var message in stream) {
if (message.type == 'EVENT') {
final event = message.message as Event;
final eventContent = json.decode(event.content) as Map<String, dynamic>;
final userMetadata = UserMetadata.fromJson(eventContent);
relay.close();
return userMetadata;
}
}
relay.close();
return null;
} catch (e) {
printV('[!] Error with relay $relayUrl: $e');
return null;
}
}
static Future<void> _showErrorDialog(
BuildContext context, String title, String errorMessage) async {
if (context.mounted) {
await showPopUp<void>(
context: context,
builder: (BuildContext dialogContext) {
return AlertWithOneAction(
alertTitle: title,
alertContent: errorMessage,
buttonText: S.of(dialogContext).ok,
buttonAction: () => Navigator.of(dialogContext).pop(),
);
},
);
}
}
static String _extractDomain(String nip05Address) {
var parts = nip05Address.split('@');
return parts.length == 2 ? parts[1] : '';
}
static String _getDomainFromRelayUrl(String relayUrl) {
try {
var uri = Uri.parse(relayUrl);
return uri.host;
} catch (e) {
printV('Error parsing URL: $e');
return '';
}
}
static Future<String?> _showRelayChoiceDialog(
BuildContext context,
List<String> relays,
) async {
String? selectedRelay;
if (context.mounted) {
await showPopUp<void>(
context: context,
builder: (BuildContext dialogContext) {
return Picker<String>(
selectedAtIndex: 0,
title: S.of(dialogContext).choose_relay,
items: relays,
onItemSelected: (String relay) => selectedRelay = relay,
);
},
);
}
return selectedRelay;
}
}