fixup! data-saving: implement gate with bypass
This commit is contained in:
		| @@ -34,88 +34,85 @@ class CloudFileWidget extends HookConsumerWidget { | |||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context, WidgetRef ref) { |   Widget build(BuildContext context, WidgetRef ref) { | ||||||
|     final dataSaving = ref.watch(appSettingsNotifierProvider.select((s) => s.dataSavingMode)); |     final dataSaving = ref.watch( | ||||||
|  |       appSettingsNotifierProvider.select((s) => s.dataSavingMode), | ||||||
|  |     ); | ||||||
|     final serverUrl = ref.watch(serverUrlProvider); |     final serverUrl = ref.watch(serverUrlProvider); | ||||||
|     final uri = '$serverUrl/drive/files/${item.id}'; |     final uri = '$serverUrl/drive/files/${item.id}'; | ||||||
|  |  | ||||||
|     var ratio = |     final unlocked = useState(false); | ||||||
|         item.fileMeta?['ratio'] is num |  | ||||||
|             ? item.fileMeta!['ratio'].toDouble() |     final meta = item.fileMeta is Map ? (item.fileMeta as Map) : const {}; | ||||||
|             : 1.0; |     final blurHash = noBlurhash ? null : (meta['blur'] as String?); | ||||||
|  |     var ratio = meta['ratio'] is num ? (meta['ratio'] as num).toDouble() : 1.0; | ||||||
|     if (ratio == 0) ratio = 1.0; |     if (ratio == 0) ratio = 1.0; | ||||||
|  |  | ||||||
|  |     Widget cloudImage() => UniversalImage(uri: uri, blurHash: blurHash, fit: fit); | ||||||
|  |     Widget cloudVideo() => CloudVideoWidget(item: item); | ||||||
|  |  | ||||||
|  |     Widget dataPlaceHolder(IconData icon) => _DataSavingPlaceholder( | ||||||
|  |           icon: icon, | ||||||
|  |           onTap: () { | ||||||
|  |             unlocked.value = true; | ||||||
|  |           }, | ||||||
|  |         ); | ||||||
|  |  | ||||||
|     var content = switch (item.mimeType?.split('/').firstOrNull) { |     var content = switch (item.mimeType?.split('/').firstOrNull) { | ||||||
|       "image" => AspectRatio( |       'image' => AspectRatio( | ||||||
|         aspectRatio: ratio, |           aspectRatio: ratio, | ||||||
|         child: dataSaving ? _DataSavingPlaceholder( |           child: (dataSaving && !unlocked.value) ? dataPlaceHolder(Symbols.image) : cloudImage(), | ||||||
|             icon: Symbols.image, |  | ||||||
|             onTap: () { |  | ||||||
|                 // TODO: single picture unlock logic |  | ||||||
|             }) |  | ||||||
|         : UniversalImage( |  | ||||||
|           uri: uri, |  | ||||||
|           blurHash: |  | ||||||
|               noBlurhash |  | ||||||
|                   ? null |  | ||||||
|                   : (item.fileMeta is String ? item.fileMeta!['blur'] : null), |  | ||||||
|         ), |         ), | ||||||
|       ), |       'video' => AspectRatio( | ||||||
|       "video" => AspectRatio( |           aspectRatio: ratio, | ||||||
|         aspectRatio: ratio, |           child: (dataSaving && !unlocked.value) ? dataPlaceHolder(Symbols.play_arrow) : cloudVideo(), | ||||||
|         child: dataSaving ? _DataSavingPlaceholder( |         ), | ||||||
|             icon: Symbols.play_arrow, |       'audio' => Center( | ||||||
|             onTap: () { |           child: ConstrainedBox( | ||||||
|                 // TODO: single vedio unlock logic |             constraints: BoxConstraints( | ||||||
|             } |               maxWidth: math.min(360, MediaQuery.of(context).size.width * 0.8), | ||||||
|         ) |             ), | ||||||
|         : CloudVideoWidget(item: item), |             child: UniversalAudio(uri: uri, filename: item.name), | ||||||
|       ), |  | ||||||
|       "audio" => Center( |  | ||||||
|         child: ConstrainedBox( |  | ||||||
|           constraints: BoxConstraints( |  | ||||||
|             maxWidth: math.min(360, MediaQuery.of(context).size.width * 0.8), |  | ||||||
|           ), |           ), | ||||||
|           child: UniversalAudio(uri: uri, filename: item.name), |  | ||||||
|         ), |         ), | ||||||
|       ), |  | ||||||
|       _ => Column( |       _ => Column( | ||||||
|         mainAxisSize: MainAxisSize.min, |           mainAxisSize: MainAxisSize.min, | ||||||
|         mainAxisAlignment: MainAxisAlignment.center, |           mainAxisAlignment: MainAxisAlignment.center, | ||||||
|         children: [ |           children: [ | ||||||
|           Icon( |             Icon( | ||||||
|             Symbols.insert_drive_file, |               Symbols.insert_drive_file, | ||||||
|             size: 48, |               size: 48, | ||||||
|             color: Theme.of(context).colorScheme.onSurfaceVariant, |  | ||||||
|           ), |  | ||||||
|           const Gap(8), |  | ||||||
|           Text( |  | ||||||
|             item.name, |  | ||||||
|             maxLines: 1, |  | ||||||
|             overflow: TextOverflow.ellipsis, |  | ||||||
|             style: TextStyle( |  | ||||||
|               fontSize: 14, |  | ||||||
|               color: Theme.of(context).colorScheme.onSurfaceVariant, |               color: Theme.of(context).colorScheme.onSurfaceVariant, | ||||||
|             ), |             ), | ||||||
|           ), |             const Gap(8), | ||||||
|           Text( |             Text( | ||||||
|             formatFileSize(item.size), |               item.name, | ||||||
|             style: TextStyle( |               maxLines: 1, | ||||||
|               fontSize: 12, |               overflow: TextOverflow.ellipsis, | ||||||
|               color: Theme.of(context).colorScheme.onSurfaceVariant, |               style: TextStyle( | ||||||
|  |                 fontSize: 14, | ||||||
|  |                 color: Theme.of(context).colorScheme.onSurfaceVariant, | ||||||
|  |               ), | ||||||
|             ), |             ), | ||||||
|           ), |             Text( | ||||||
|           const Gap(8), |               formatFileSize(item.size), | ||||||
|           TextButton.icon( |               style: TextStyle( | ||||||
|             onPressed: () { |                 fontSize: 12, | ||||||
|               launchUrlString( |                 color: Theme.of(context).colorScheme.onSurfaceVariant, | ||||||
|                 'https://fs.solian.app/files/${item.id}', |               ), | ||||||
|                 mode: LaunchMode.externalApplication, |             ), | ||||||
|               ); |             const Gap(8), | ||||||
|             }, |             TextButton.icon( | ||||||
|             icon: const Icon(Symbols.launch), |               onPressed: () { | ||||||
|             label: Text('openInBrowser').tr(), |                 launchUrlString( | ||||||
|           ), |                   'https://fs.solian.app/files/${item.id}', | ||||||
|         ], |                   mode: LaunchMode.externalApplication, | ||||||
|       ).padding(all: 8), |                 ); | ||||||
|  |               }, | ||||||
|  |               icon: const Icon(Symbols.launch), | ||||||
|  |               label: Text('openInBrowser').tr(), | ||||||
|  |             ), | ||||||
|  |           ], | ||||||
|  |         ).padding(all: 8), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (heroTag != null) { |     if (heroTag != null) { | ||||||
| @@ -375,7 +372,7 @@ class ProfilePictureWidget extends ConsumerWidget { | |||||||
|         child: id == null |         child: id == null | ||||||
|             ? fallback |             ? fallback | ||||||
|             : DataSavingGate( |             : DataSavingGate( | ||||||
|                 bypass: true, // 小頭像永遠繞過低數據 |                 bypass: true, | ||||||
|                 placeholder: fallback, |                 placeholder: fallback, | ||||||
|                 content: () => UniversalImage( |                 content: () => UniversalImage( | ||||||
|                   uri: '$serverUrl/drive/files/$id', |                   uri: '$serverUrl/drive/files/$id', | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user