fluffychat/lib/pangea/analytics_details_popup/morph_analytics_view.dart

248 lines
7.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/analytics_details_popup/analytics_details_popup.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_identifier.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_level_enum.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart';
import 'package:fluffychat/pangea/morphs/get_grammar_copy.dart';
import 'package:fluffychat/pangea/morphs/morph_icon.dart';
import 'package:fluffychat/pangea/user/client_extension.dart';
import 'package:fluffychat/widgets/matrix.dart';
class MorphAnalyticsView extends StatelessWidget {
final void Function(ConstructIdentifier) onConstructZoom;
final AnalyticsPopupWrapperState controller;
const MorphAnalyticsView({
required this.onConstructZoom,
required this.controller,
super.key,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: ListView.builder(
key: const PageStorageKey<String>('morph-analytics'),
itemCount: controller.features.length,
itemBuilder: (context, index) {
final feature = controller.features[index];
return feature.displayTags.isNotEmpty
? MorphFeatureBox(
morphFeature: feature.feature,
allTags: controller.morphs
.getDisplayTags(feature.feature)
.map((tag) => tag.toLowerCase())
.toSet(),
onConstructZoom: onConstructZoom,
)
: const SizedBox.shrink();
},
),
);
}
}
class MorphFeatureBox extends StatelessWidget {
final String morphFeature;
final Set<String> allTags;
final void Function(ConstructIdentifier) onConstructZoom;
const MorphFeatureBox({
super.key,
required this.morphFeature,
required this.allTags,
required this.onConstructZoom,
});
String _categoryCopy(
String category,
BuildContext context,
) {
if (category.toLowerCase() == "other") {
return L10n.of(context).other;
}
return ConstructTypeEnum.morph.getDisplayCopy(
category,
context,
) ??
category;
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Container(
padding: const EdgeInsets.all(16.0),
margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16.0),
border: Border.all(
color: Theme.of(context).brightness == Brightness.dark
? AppConfig.primaryColorLight
: AppConfig.primaryColor,
width: 2,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 16.0,
children: [
SizedBox(
height: 30.0,
width: 30.0,
child: MorphIcon(morphFeature: morphFeature, morphTag: null),
),
Text(
_categoryCopy(morphFeature, context),
style: theme.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 16.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
child: Wrap(
alignment: WrapAlignment.center,
spacing: 16.0,
runSpacing: 16.0,
children: allTags
.map(
(morphTag) {
final id = ConstructIdentifier(
lemma: morphTag,
type: ConstructTypeEnum.morph,
category: morphFeature,
);
final analytics = MatrixState.pangeaController
.getAnalytics.constructListModel
.getConstructUses(id) ??
ConstructUses(
lemma: morphTag,
constructType: ConstructTypeEnum.morph,
category: morphFeature,
uses: [],
);
return MorphTagChip(
morphFeature: morphFeature,
morphTag: morphTag,
constructAnalytics: analytics,
onTap: analytics.points > 0
? () => onConstructZoom(id)
: null,
);
},
)
.sortedBy<num>(
(chip) => chip.constructAnalytics.points,
)
.reversed
.toList(),
),
),
],
),
],
),
);
}
}
class MorphTagChip extends StatelessWidget {
final String morphFeature;
final String morphTag;
final ConstructUses constructAnalytics;
final VoidCallback? onTap;
const MorphTagChip({
super.key,
required this.morphFeature,
required this.morphTag,
required this.constructAnalytics,
this.onTap,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return InkWell(
borderRadius: BorderRadius.circular(32.0),
onTap: onTap,
child: Opacity(
opacity: constructAnalytics.points > 0 ? 1.0 : 0.3,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32.0),
gradient: constructAnalytics.points > 0
? LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: <Color>[
Colors.transparent,
constructAnalytics.lemmaCategory.color,
],
)
: null,
color: constructAnalytics.points > 0 ? null : theme.disabledColor,
),
padding: const EdgeInsets.symmetric(
vertical: 4.0,
horizontal: 8.0,
),
child: Row(
mainAxisSize: MainAxisSize.min,
spacing: 8.0,
children: [
SizedBox(
width: 28.0,
height: 28.0,
child: constructAnalytics.points > 0 ||
Matrix.of(context).client.isSupportAccount
? MorphIcon(
morphFeature: morphFeature,
morphTag: morphTag,
)
: const Icon(
Icons.lock,
color: Colors.white,
),
),
Text(
getGrammarCopy(
category: morphFeature,
lemma: morphTag,
context: context,
) ??
morphTag,
style: TextStyle(
fontWeight: FontWeight.bold,
color: theme.brightness == Brightness.dark
? Colors.white
: Colors.black,
),
),
],
),
),
),
);
}
}