dev
dart 266 lines 7.83 KB
Raw
1 import 'package:flutter/material.dart';
2 import 'package:cake_wallet/entities/solana_nft_asset_model.dart';
3 import 'package:cake_wallet/entities/wallet_nft_response.dart';
4 import 'package:cake_wallet/generated/i18n.dart';
5 import 'package:cake_wallet/src/screens/base_page.dart';
6 import 'package:cake_wallet/src/screens/dashboard/widgets/menu_widget.dart';
7 import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
8 import 'package:cake_wallet/src/widgets/gradient_background.dart';
9 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
10
11 class NFTDetailsPage extends BasePage {
12 NFTDetailsPage({
13 required this.dashboardViewModel,
14 required this.arguments,
15 Key? key,
16 });
17
18 final DashboardViewModel dashboardViewModel;
19 final NFTDetailsPageArguments arguments;
20
21 @override
22 bool get gradientBackground => true;
23
24 @override
25 Widget Function(BuildContext, Widget) get rootWrapper =>
26 (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
27
28 @override
29 bool get resizeToAvoidBottomInset => false;
30
31 @override
32 Widget get endDrawer => MenuWidget(
33 dashboardViewModel,
34 const ValueKey('nft_details_page_menu_widget_key'),
35 );
36
37 @override
38 Widget trailing(BuildContext context) {
39 return SizedBox.shrink();
40 // final menuButton = Image.asset(
41 // 'assets/images/menu.png',
42 // color: Theme.of(context).colorScheme.onSurface,
43 // );
44 //
45 // return Container(
46 // alignment: Alignment.centerRight,
47 // width: 40,
48 // child: TextButton(
49 // // FIX-ME: Style
50 // //highlightColor: Colors.transparent,
51 // //splashColor: Colors.transparent,
52 // //padding: EdgeInsets.all(0),
53 // onPressed: () => onOpenEndDrawer(),
54 // child: Semantics(label: S.of(context).wallet_menu, child: menuButton),
55 // ),
56 // );
57 }
58
59 @override
60 Widget body(BuildContext context) {
61 return SingleChildScrollView(
62 child: Container(
63 width: double.infinity,
64 margin: const EdgeInsets.all(16),
65 decoration: BoxDecoration(
66 borderRadius: BorderRadius.circular(24.0),
67 border: Border.all(
68 color: Theme.of(context).colorScheme.outline,
69 width: 1,
70 ),
71 color: Theme.of(context).colorScheme.surface,
72 ),
73 child: arguments.isSolanaNFT
74 ? SolanaNFTDetailsWidget(
75 solanaNftAsset: arguments.solanaNFTAssetModel,
76 )
77 : EVMChainNFTDetailsWidget(
78 nftAsset: arguments.nftAsset,
79 ),
80 ),
81 );
82 }
83 }
84
85 class _NFTImageWidget extends StatelessWidget {
86 final String? imageUrl;
87
88 const _NFTImageWidget({Key? key, this.imageUrl}) : super(key: key);
89
90 @override
91 Widget build(BuildContext context) {
92 return Container(
93 height: MediaQuery.sizeOf(context).height / 2.5,
94 width: double.infinity,
95 margin: const EdgeInsets.all(8),
96 clipBehavior: Clip.hardEdge,
97 decoration: BoxDecoration(
98 borderRadius: BorderRadius.circular(24.0),
99 border: Border.all(
100 color: Theme.of(context).colorScheme.outline,
101 width: 1,
102 ),
103 color: Theme.of(context).colorScheme.surface,
104 ),
105 child: CakeImageWidget(imageUrl: imageUrl),
106 );
107 }
108 }
109
110 class EVMChainNFTDetailsWidget extends StatelessWidget {
111 final NFTAssetModel? nftAsset;
112
113 const EVMChainNFTDetailsWidget({Key? key, this.nftAsset}) : super(key: key);
114
115 @override
116 Widget build(BuildContext context) {
117 if (nftAsset == null) {
118 return Center(child: Text(S.current.no_extra_detail));
119 }
120
121 final metadata = nftAsset!.normalizedMetadata;
122
123 return Column(
124 crossAxisAlignment: CrossAxisAlignment.start,
125 children: [
126 _NFTImageWidget(imageUrl: metadata?.imageUrl),
127 const SizedBox(height: 16),
128 _NFTSingleInfoTile(
129 infoType: S.current.name,
130 infoValue: metadata?.name ?? '---',
131 ),
132 if (metadata?.description != null) ...[
133 const SizedBox(height: 16),
134 _NFTSingleInfoTile(
135 infoType: S.current.description,
136 infoValue: metadata!.description ?? '---',
137 ),
138 ],
139 const SizedBox(height: 16),
140 _NFTSingleInfoTile(
141 infoType: S.current.contractName,
142 infoValue: nftAsset!.name ?? '---',
143 ),
144 const SizedBox(height: 8),
145 _NFTSingleInfoTile(
146 infoType: S.current.contractSymbol,
147 infoValue: nftAsset!.symbol ?? '---',
148 ),
149 ],
150 );
151 }
152 }
153
154 class SolanaNFTDetailsWidget extends StatelessWidget {
155 final SolanaNFTAssetModel? solanaNftAsset;
156
157 const SolanaNFTDetailsWidget({Key? key, this.solanaNftAsset}) : super(key: key);
158
159 @override
160 Widget build(BuildContext context) {
161 if (solanaNftAsset == null) {
162 return Center(child: Text(S.current.no_extra_detail));
163 }
164
165 return Column(
166 crossAxisAlignment: CrossAxisAlignment.start,
167 children: [
168 _NFTImageWidget(imageUrl: solanaNftAsset?.imageOriginalUrl),
169 const SizedBox(height: 16),
170 _NFTSingleInfoTile(
171 infoType: S.current.name,
172 infoValue: solanaNftAsset?.name ?? '---',
173 ),
174 if (solanaNftAsset?.description != null) ...[
175 const SizedBox(height: 16),
176 _NFTSingleInfoTile(
177 infoType: S.current.description,
178 infoValue: solanaNftAsset!.description ?? '---',
179 ),
180 ],
181 const SizedBox(height: 16),
182 _NFTSingleInfoTile(
183 infoType: S.current.mint_address,
184 infoValue: solanaNftAsset?.mint ?? '---',
185 ),
186 const SizedBox(height: 16),
187 _NFTSingleInfoTile(
188 infoType: S.current.contractName,
189 infoValue: solanaNftAsset?.contract?.name ?? '---',
190 ),
191 const SizedBox(height: 16),
192 _NFTSingleInfoTile(
193 infoType: S.current.contractSymbol,
194 infoValue: solanaNftAsset?.contract?.symbol ?? '---',
195 ),
196 const SizedBox(height: 16),
197 _NFTSingleInfoTile(
198 infoType: S.current.collection_name,
199 infoValue: solanaNftAsset?.collection?.name ?? '---',
200 ),
201 const SizedBox(height: 16),
202 _NFTSingleInfoTile(
203 infoType: S.current.collection_description,
204 infoValue: solanaNftAsset?.collection?.description ?? '---',
205 ),
206 const SizedBox(height: 16),
207 _NFTSingleInfoTile(
208 infoType: S.current.collection_address,
209 infoValue: solanaNftAsset?.collection?.collectionAddress ?? '---',
210 ),
211 const SizedBox(height: 16),
212 ],
213 );
214 }
215 }
216
217 class _NFTSingleInfoTile extends StatelessWidget {
218 final String infoType;
219 final String infoValue;
220
221 const _NFTSingleInfoTile({
222 required this.infoType,
223 required this.infoValue,
224 });
225
226 @override
227 Widget build(BuildContext context) {
228 return Padding(
229 padding: const EdgeInsets.symmetric(horizontal: 24),
230 child: Column(
231 crossAxisAlignment: CrossAxisAlignment.start,
232 children: [
233 Text(
234 infoType,
235 style: Theme.of(context).textTheme.bodySmall?.copyWith(
236 color: Theme.of(context).colorScheme.onSurfaceVariant,
237 fontWeight: FontWeight.w500,
238 height: 1,
239 ),
240 ),
241 const SizedBox(height: 8),
242 Text(
243 infoValue,
244 style: Theme.of(context).textTheme.titleMedium?.copyWith(
245 fontWeight: FontWeight.w600,
246 color: Theme.of(context).colorScheme.onSurface,
247 height: 1,
248 ),
249 ),
250 ],
251 ),
252 );
253 }
254 }
255
256 class NFTDetailsPageArguments {
257 NFTDetailsPageArguments({
258 this.nftAsset,
259 this.solanaNFTAssetModel,
260 required this.isSolanaNFT,
261 });
262
263 final NFTAssetModel? nftAsset;
264 final SolanaNFTAssetModel? solanaNFTAssetModel;
265 final bool isSolanaNFT;
266 }