Studio lot 8e : lecteur audio dans la fiche d'un point de carte
PointAudio résout la ressource et affiche le portrait du narrateur. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011VxSQeGQYUvPmSEoGdnidA
This commit is contained in:
parent
8979ab2e63
commit
296b7a7519
60
lib/Components/point_audio.dart
Normal file
60
lib/Components/point_audio.dart
Normal file
@ -0,0 +1,60 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:manager_api_new/api.dart';
|
||||
import 'package:tablet_app/Components/cached_custom_resource.dart';
|
||||
import 'package:tablet_app/Components/narrator_avatar.dart';
|
||||
|
||||
/// Audio d'un point de carte (plan Studio lot 8e) : le point range un identifiant de ressource,
|
||||
/// résolu ici, avec le portrait du narrateur quand c'est une narration.
|
||||
class PointAudio extends StatefulWidget {
|
||||
const PointAudio({Key? key, required this.resourceId, required this.resourceApi}) : super(key: key);
|
||||
|
||||
final String resourceId;
|
||||
final ResourceApi resourceApi;
|
||||
|
||||
@override
|
||||
State<PointAudio> createState() => _PointAudioState();
|
||||
}
|
||||
|
||||
class _PointAudioState extends State<PointAudio> {
|
||||
/// Gardé : la fiche du point se reconstruit souvent, et chaque reconstruction relancerait la requête.
|
||||
late Future<ResourceDTO?> _resource;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_resource = widget.resourceApi.resourceGetDetail(widget.resourceId);
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(PointAudio oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.resourceId != widget.resourceId) {
|
||||
_resource = widget.resourceApi.resourceGetDetail(widget.resourceId);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<ResourceDTO?>(
|
||||
future: _resource,
|
||||
builder: (context, snapshot) {
|
||||
final resource = snapshot.data;
|
||||
if (resource?.url == null) return const SizedBox.shrink();
|
||||
|
||||
final player = CachedCustomResource(resourceDTO: resource!, isAuto: false, webView: false);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: resource.narratorName == null
|
||||
? Align(alignment: Alignment.centerLeft, child: player)
|
||||
: Row(
|
||||
children: [
|
||||
NarratorAvatar(name: resource.narratorName!, portraitUrl: resource.narratorPortraitUrl),
|
||||
const SizedBox(width: 16),
|
||||
player,
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
import 'package:tablet_app/Components/point_audio.dart';
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@ -58,6 +59,11 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
||||
ScrollController scrollDescription = new ScrollController();
|
||||
ScrollController scrollPrice = new ScrollController();
|
||||
|
||||
// Un audio par langue, sans repli sur une autre : l'audio français à un néerlandophone est pire que le silence.
|
||||
final pointAudioId = selectedPoint?.audioIds
|
||||
?.where((a) => a.language == language && (a.value ?? '').isNotEmpty)
|
||||
.firstOrNull
|
||||
?.value;
|
||||
var isPointPrice = selectedPoint != null && selectedPoint.prices != null && selectedPoint.prices!.isNotEmpty && selectedPoint.prices!.any((d) => d.language == language) && selectedPoint.prices!.firstWhere((d) => d.language == language).value != null && selectedPoint.prices!.firstWhere((d) => d.language == language).value!.trim().length > 0;
|
||||
|
||||
Color primaryColor = new Color(int.parse(tabletAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16));
|
||||
@ -194,6 +200,12 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
if (pointAudioId != null)
|
||||
PointAudio(
|
||||
key: ValueKey('point-audio-$pointAudioId'),
|
||||
resourceId: pointAudioId,
|
||||
resourceApi: tabletAppContext.clientAPI!.resourceApi!,
|
||||
),
|
||||
if(selectedPoint.description!.any((d) => d.language == language) && selectedPoint.description!.firstWhere((d) => d.language == language).value != null && selectedPoint.description!.firstWhere((d) => d.language == language).value!.trim().length > 0)
|
||||
HtmlWidget(
|
||||
selectedPoint.description!.firstWhere((d) => d.language == language).value!,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user