mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-22 02:24:30 +00:00
firo private/public balance desktop toggle
This commit is contained in:
parent
b333253287
commit
e2a172f747
6 changed files with 215 additions and 225 deletions
BIN
assets/images/glasses-hidden.png
Normal file
BIN
assets/images/glasses-hidden.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1 KiB |
BIN
assets/images/glasses.png
Normal file
BIN
assets/images/glasses.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,60 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
|
||||||
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
|
||||||
|
class DesktopBalanceToggleButton extends ConsumerWidget {
|
||||||
|
const DesktopBalanceToggleButton({
|
||||||
|
Key? key,
|
||||||
|
this.onPressed,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final VoidCallback? onPressed;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 22,
|
||||||
|
width: 22,
|
||||||
|
child: MaterialButton(
|
||||||
|
color: Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
|
||||||
|
splashColor: Theme.of(context).extension<StackColors>()!.highlight,
|
||||||
|
onPressed: () {
|
||||||
|
if (ref.read(walletBalanceToggleStateProvider.state).state ==
|
||||||
|
WalletBalanceToggleState.available) {
|
||||||
|
ref.read(walletBalanceToggleStateProvider.state).state =
|
||||||
|
WalletBalanceToggleState.full;
|
||||||
|
} else {
|
||||||
|
ref.read(walletBalanceToggleStateProvider.state).state =
|
||||||
|
WalletBalanceToggleState.available;
|
||||||
|
}
|
||||||
|
onPressed?.call();
|
||||||
|
},
|
||||||
|
elevation: 0,
|
||||||
|
highlightElevation: 0,
|
||||||
|
hoverElevation: 0,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Image(
|
||||||
|
image: AssetImage(
|
||||||
|
ref.watch(walletBalanceToggleStateProvider.state).state ==
|
||||||
|
WalletBalanceToggleState.available
|
||||||
|
? Assets.png.glassesHidden
|
||||||
|
: Assets.png.glasses,
|
||||||
|
),
|
||||||
|
width: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,15 @@
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart';
|
|
||||||
import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_refresh_button.dart';
|
import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_refresh_button.dart';
|
||||||
|
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
|
||||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||||
import 'package:stackwallet/services/coins/manager.dart';
|
import 'package:stackwallet/services/coins/manager.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
|
||||||
import 'package:stackwallet/utilities/format.dart';
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
@ -33,19 +35,6 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
|
||||||
late final String walletId;
|
late final String walletId;
|
||||||
late final ChangeNotifierProvider<Manager> managerProvider;
|
late final ChangeNotifierProvider<Manager> managerProvider;
|
||||||
|
|
||||||
void showSheet() {
|
|
||||||
showModalBottomSheet<dynamic>(
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
context: context,
|
|
||||||
shape: const RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.vertical(
|
|
||||||
top: Radius.circular(20),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
builder: (_) => WalletBalanceToggleSheet(walletId: walletId),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Decimal? _balanceTotalCached;
|
Decimal? _balanceTotalCached;
|
||||||
Decimal? _balanceCached;
|
Decimal? _balanceCached;
|
||||||
|
|
||||||
|
@ -59,225 +48,161 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
debugPrint("BUILD: $runtimeType");
|
debugPrint("BUILD: $runtimeType");
|
||||||
return Row(
|
return Consumer(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
builder: (context, ref, __) {
|
||||||
children: [
|
final Coin coin =
|
||||||
Column(
|
ref.watch(managerProvider.select((value) => value.coin));
|
||||||
|
return Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Consumer(
|
Column(
|
||||||
builder: (_, ref, __) {
|
children: [
|
||||||
final Coin coin =
|
Consumer(
|
||||||
ref.watch(managerProvider.select((value) => value.coin));
|
builder: (_, ref, __) {
|
||||||
final externalCalls = ref.watch(prefsChangeNotifierProvider
|
final externalCalls = ref.watch(prefsChangeNotifierProvider
|
||||||
.select((value) => value.externalCalls));
|
.select((value) => value.externalCalls));
|
||||||
|
|
||||||
Future<Decimal>? totalBalanceFuture;
|
Future<Decimal>? totalBalanceFuture;
|
||||||
Future<Decimal>? availableBalanceFuture;
|
Future<Decimal>? availableBalanceFuture;
|
||||||
if (coin == Coin.firo || coin == Coin.firoTestNet) {
|
if (coin == Coin.firo || coin == Coin.firoTestNet) {
|
||||||
final firoWallet =
|
final firoWallet = ref.watch(
|
||||||
ref.watch(managerProvider.select((value) => value.wallet))
|
managerProvider.select((value) => value.wallet))
|
||||||
as FiroWallet;
|
as FiroWallet;
|
||||||
totalBalanceFuture = firoWallet.availablePublicBalance();
|
totalBalanceFuture = firoWallet.availablePublicBalance();
|
||||||
availableBalanceFuture = firoWallet.availablePrivateBalance();
|
availableBalanceFuture =
|
||||||
} else {
|
firoWallet.availablePrivateBalance();
|
||||||
totalBalanceFuture = ref.watch(
|
|
||||||
managerProvider.select((value) => value.totalBalance));
|
|
||||||
|
|
||||||
availableBalanceFuture = ref.watch(managerProvider
|
|
||||||
.select((value) => value.availableBalance));
|
|
||||||
}
|
|
||||||
|
|
||||||
final locale = ref.watch(localeServiceChangeNotifierProvider
|
|
||||||
.select((value) => value.locale));
|
|
||||||
|
|
||||||
final baseCurrency = ref.watch(prefsChangeNotifierProvider
|
|
||||||
.select((value) => value.currency));
|
|
||||||
|
|
||||||
final priceTuple = ref.watch(priceAnd24hChangeNotifierProvider
|
|
||||||
.select((value) => value.getPrice(coin)));
|
|
||||||
|
|
||||||
final _showAvailable = false;
|
|
||||||
// ref.watch(walletBalanceToggleStateProvider.state).state ==
|
|
||||||
// WalletBalanceToggleState.available;
|
|
||||||
|
|
||||||
return FutureBuilder(
|
|
||||||
future: _showAvailable
|
|
||||||
? availableBalanceFuture
|
|
||||||
: totalBalanceFuture,
|
|
||||||
builder: (fbContext, AsyncSnapshot<Decimal> snapshot) {
|
|
||||||
if (snapshot.connectionState == ConnectionState.done &&
|
|
||||||
snapshot.hasData &&
|
|
||||||
snapshot.data != null) {
|
|
||||||
if (_showAvailable) {
|
|
||||||
_balanceCached = snapshot.data!;
|
|
||||||
} else {
|
|
||||||
_balanceTotalCached = snapshot.data!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Decimal? balanceToShow =
|
|
||||||
_showAvailable ? _balanceCached : _balanceTotalCached;
|
|
||||||
|
|
||||||
if (balanceToShow != null) {
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
// GestureDetector(
|
|
||||||
// onTap: showSheet,
|
|
||||||
// child: Row(
|
|
||||||
// children: [
|
|
||||||
// if (coin == Coin.firo ||
|
|
||||||
// coin == Coin.firoTestNet)
|
|
||||||
// Text(
|
|
||||||
// "${_showAvailable ? "Private" : "Public"} Balance",
|
|
||||||
// style: STextStyles.subtitle500(context)
|
|
||||||
// .copyWith(
|
|
||||||
// color: Theme.of(context)
|
|
||||||
// .extension<StackColors>()!
|
|
||||||
// .textFavoriteCard,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// if (coin != Coin.firo &&
|
|
||||||
// coin != Coin.firoTestNet)
|
|
||||||
// Text(
|
|
||||||
// "${_showAvailable ? "Available" : "Full"} Balance",
|
|
||||||
// style: STextStyles.subtitle500(context)
|
|
||||||
// .copyWith(
|
|
||||||
// color: Theme.of(context)
|
|
||||||
// .extension<StackColors>()!
|
|
||||||
// .textFavoriteCard,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// const SizedBox(
|
|
||||||
// width: 4,
|
|
||||||
// ),
|
|
||||||
// SvgPicture.asset(
|
|
||||||
// Assets.svg.chevronDown,
|
|
||||||
// color: Theme.of(context)
|
|
||||||
// .extension<StackColors>()!
|
|
||||||
// .textFavoriteCard,
|
|
||||||
// width: 8,
|
|
||||||
// height: 4,
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
FittedBox(
|
|
||||||
fit: BoxFit.scaleDown,
|
|
||||||
child: Text(
|
|
||||||
"${Format.localizedStringAsFixed(
|
|
||||||
value: balanceToShow,
|
|
||||||
locale: locale,
|
|
||||||
decimalPlaces: 8,
|
|
||||||
)} ${coin.ticker}",
|
|
||||||
style: STextStyles.desktopH3(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (externalCalls)
|
|
||||||
Text(
|
|
||||||
"${Format.localizedStringAsFixed(
|
|
||||||
value: priceTuple.item1 * balanceToShow,
|
|
||||||
locale: locale,
|
|
||||||
decimalPlaces: 2,
|
|
||||||
)} $baseCurrency",
|
|
||||||
style: STextStyles.desktopTextExtraSmall(context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textSubtitle1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return Column(
|
totalBalanceFuture = ref.watch(managerProvider
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
.select((value) => value.totalBalance));
|
||||||
children: [
|
|
||||||
// GestureDetector(
|
availableBalanceFuture = ref.watch(managerProvider
|
||||||
// onTap: showSheet,
|
.select((value) => value.availableBalance));
|
||||||
// child: Row(
|
|
||||||
// children: [
|
|
||||||
// if (coin == Coin.firo ||
|
|
||||||
// coin == Coin.firoTestNet)
|
|
||||||
// Text(
|
|
||||||
// "${_showAvailable ? "Private" : "Public"} Balance",
|
|
||||||
// style: STextStyles.subtitle500(context)
|
|
||||||
// .copyWith(
|
|
||||||
// color: Theme.of(context)
|
|
||||||
// .extension<StackColors>()!
|
|
||||||
// .textFavoriteCard,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// if (coin != Coin.firo &&
|
|
||||||
// coin != Coin.firoTestNet)
|
|
||||||
// Text(
|
|
||||||
// "${_showAvailable ? "Available" : "Full"} Balance",
|
|
||||||
// style: STextStyles.subtitle500(context)
|
|
||||||
// .copyWith(
|
|
||||||
// color: Theme.of(context)
|
|
||||||
// .extension<StackColors>()!
|
|
||||||
// .textFavoriteCard,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// const SizedBox(
|
|
||||||
// width: 4,
|
|
||||||
// ),
|
|
||||||
// SvgPicture.asset(
|
|
||||||
// Assets.svg.chevronDown,
|
|
||||||
// width: 8,
|
|
||||||
// height: 4,
|
|
||||||
// color: Theme.of(context)
|
|
||||||
// .extension<StackColors>()!
|
|
||||||
// .textFavoriteCard,
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
AnimatedText(
|
|
||||||
stringsToLoopThrough: const [
|
|
||||||
"Loading balance ",
|
|
||||||
"Loading balance. ",
|
|
||||||
"Loading balance.. ",
|
|
||||||
"Loading balance..."
|
|
||||||
],
|
|
||||||
style: STextStyles.desktopH3(context).copyWith(
|
|
||||||
fontSize: 24,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textDark,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (externalCalls)
|
|
||||||
AnimatedText(
|
|
||||||
stringsToLoopThrough: const [
|
|
||||||
"Loading balance ",
|
|
||||||
"Loading balance. ",
|
|
||||||
"Loading balance.. ",
|
|
||||||
"Loading balance..."
|
|
||||||
],
|
|
||||||
style: STextStyles.desktopTextExtraSmall(context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textSubtitle1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final locale = ref.watch(localeServiceChangeNotifierProvider
|
||||||
|
.select((value) => value.locale));
|
||||||
|
|
||||||
|
final baseCurrency = ref.watch(prefsChangeNotifierProvider
|
||||||
|
.select((value) => value.currency));
|
||||||
|
|
||||||
|
final priceTuple = ref.watch(
|
||||||
|
priceAnd24hChangeNotifierProvider
|
||||||
|
.select((value) => value.getPrice(coin)));
|
||||||
|
|
||||||
|
final _showAvailable = ref
|
||||||
|
.watch(walletBalanceToggleStateProvider.state)
|
||||||
|
.state ==
|
||||||
|
WalletBalanceToggleState.available;
|
||||||
|
|
||||||
|
return FutureBuilder(
|
||||||
|
future: _showAvailable
|
||||||
|
? availableBalanceFuture
|
||||||
|
: totalBalanceFuture,
|
||||||
|
builder: (fbContext, AsyncSnapshot<Decimal> snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done &&
|
||||||
|
snapshot.hasData &&
|
||||||
|
snapshot.data != null) {
|
||||||
|
if (_showAvailable) {
|
||||||
|
_balanceCached = snapshot.data!;
|
||||||
|
} else {
|
||||||
|
_balanceTotalCached = snapshot.data!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Decimal? balanceToShow = _showAvailable
|
||||||
|
? _balanceCached
|
||||||
|
: _balanceTotalCached;
|
||||||
|
|
||||||
|
if (balanceToShow != null) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: Text(
|
||||||
|
"${Format.localizedStringAsFixed(
|
||||||
|
value: balanceToShow,
|
||||||
|
locale: locale,
|
||||||
|
decimalPlaces: 8,
|
||||||
|
)} ${coin.ticker}",
|
||||||
|
style: STextStyles.desktopH3(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (externalCalls)
|
||||||
|
Text(
|
||||||
|
"${Format.localizedStringAsFixed(
|
||||||
|
value: priceTuple.item1 * balanceToShow,
|
||||||
|
locale: locale,
|
||||||
|
decimalPlaces: 2,
|
||||||
|
)} $baseCurrency",
|
||||||
|
style:
|
||||||
|
STextStyles.desktopTextExtraSmall(context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
AnimatedText(
|
||||||
|
stringsToLoopThrough: const [
|
||||||
|
"Loading balance ",
|
||||||
|
"Loading balance. ",
|
||||||
|
"Loading balance.. ",
|
||||||
|
"Loading balance..."
|
||||||
|
],
|
||||||
|
style: STextStyles.desktopH3(context).copyWith(
|
||||||
|
fontSize: 24,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textDark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (externalCalls)
|
||||||
|
AnimatedText(
|
||||||
|
stringsToLoopThrough: const [
|
||||||
|
"Loading balance ",
|
||||||
|
"Loading balance. ",
|
||||||
|
"Loading balance.. ",
|
||||||
|
"Loading balance..."
|
||||||
|
],
|
||||||
|
style:
|
||||||
|
STextStyles.desktopTextExtraSmall(context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
),
|
||||||
},
|
],
|
||||||
),
|
),
|
||||||
|
if (coin == Coin.firo || coin == Coin.firoTestNet)
|
||||||
|
const SizedBox(
|
||||||
|
width: 8,
|
||||||
|
),
|
||||||
|
if (coin == Coin.firo || coin == Coin.firoTestNet)
|
||||||
|
const DesktopBalanceToggleButton(),
|
||||||
|
const SizedBox(
|
||||||
|
width: 8,
|
||||||
|
),
|
||||||
|
WalletRefreshButton(
|
||||||
|
walletId: walletId,
|
||||||
|
initialSyncStatus: widget.initialSyncStatus,
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
);
|
||||||
const SizedBox(
|
},
|
||||||
width: 8,
|
|
||||||
),
|
|
||||||
WalletRefreshButton(
|
|
||||||
walletId: walletId,
|
|
||||||
initialSyncStatus: widget.initialSyncStatus,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,9 @@ class _PNG {
|
||||||
String get bitcoincash => "assets/images/bitcoincash.png";
|
String get bitcoincash => "assets/images/bitcoincash.png";
|
||||||
String get namecoin => "assets/images/namecoin.png";
|
String get namecoin => "assets/images/namecoin.png";
|
||||||
|
|
||||||
|
String get glasses => "assets/images/glasses.png";
|
||||||
|
String get glassesHidden => "assets/images/glasses-hidden.png";
|
||||||
|
|
||||||
String imageFor({required Coin coin}) {
|
String imageFor({required Coin coin}) {
|
||||||
switch (coin) {
|
switch (coin) {
|
||||||
case Coin.bitcoin:
|
case Coin.bitcoin:
|
||||||
|
|
|
@ -202,6 +202,8 @@ flutter:
|
||||||
- assets/images/epic-cash.png
|
- assets/images/epic-cash.png
|
||||||
- assets/images/bitcoincash.png
|
- assets/images/bitcoincash.png
|
||||||
- assets/images/namecoin.png
|
- assets/images/namecoin.png
|
||||||
|
- assets/images/glasses.png
|
||||||
|
- assets/images/glasses-hidden.png
|
||||||
- assets/svg/plus.svg
|
- assets/svg/plus.svg
|
||||||
- assets/svg/gear.svg
|
- assets/svg/gear.svg
|
||||||
- assets/svg/bell.svg
|
- assets/svg/bell.svg
|
||||||
|
|
Loading…
Reference in a new issue