|
|
|
|
@ -4,6 +4,8 @@
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
|
|
import 'package:collection/collection.dart';
|
|
|
|
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|
|
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
|
|
|
|
|
|
import 'package:fluffychat/config/themes.dart';
|
|
|
|
|
import 'package:fluffychat/pangea/activity_planner/activity_plan_model.dart';
|
|
|
|
|
@ -19,7 +21,6 @@ import 'package:fluffychat/widgets/matrix.dart';
|
|
|
|
|
|
|
|
|
|
class ActivitySuggestionsArea extends StatefulWidget {
|
|
|
|
|
const ActivitySuggestionsArea({super.key});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
ActivitySuggestionsAreaState createState() => ActivitySuggestionsAreaState();
|
|
|
|
|
}
|
|
|
|
|
@ -39,7 +40,6 @@ class ActivitySuggestionsAreaState extends State<ActivitySuggestionsArea> {
|
|
|
|
|
|
|
|
|
|
final List<ActivityPlanModel> _activityItems = [];
|
|
|
|
|
final ScrollController _scrollController = ScrollController();
|
|
|
|
|
|
|
|
|
|
final double cardHeight = 235.0;
|
|
|
|
|
final double cardPadding = 8.0;
|
|
|
|
|
double get cardWidth => FluffyThemes.isColumnMode(context) ? 225.0 : 160.0;
|
|
|
|
|
@ -49,14 +49,11 @@ class ActivitySuggestionsAreaState extends State<ActivitySuggestionsArea> {
|
|
|
|
|
final double scrollOffset = FluffyThemes.isColumnMode(context)
|
|
|
|
|
? index * cardWidth - (viewportDimension / 2) + (cardWidth / 2)
|
|
|
|
|
: (index + 1) * (cardHeight + 8.0);
|
|
|
|
|
|
|
|
|
|
final maxScrollExtent = _scrollController.position.maxScrollExtent;
|
|
|
|
|
final safeOffset = scrollOffset.clamp(0.0, maxScrollExtent);
|
|
|
|
|
|
|
|
|
|
if (safeOffset == _scrollController.offset) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_scrollController.animateTo(
|
|
|
|
|
safeOffset,
|
|
|
|
|
duration: FluffyThemes.animationDuration,
|
|
|
|
|
@ -64,6 +61,21 @@ class ActivitySuggestionsAreaState extends State<ActivitySuggestionsArea> {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _scrollToNextItem(AxisDirection direction) {
|
|
|
|
|
final currentOffset = _scrollController.offset;
|
|
|
|
|
final scrollAmount =
|
|
|
|
|
FluffyThemes.isColumnMode(context) ? cardWidth : cardHeight;
|
|
|
|
|
|
|
|
|
|
_scrollController.animateTo(
|
|
|
|
|
(direction == AxisDirection.left
|
|
|
|
|
? currentOffset - scrollAmount
|
|
|
|
|
: currentOffset + scrollAmount)
|
|
|
|
|
.clamp(0.0, _scrollController.position.maxScrollExtent),
|
|
|
|
|
duration: FluffyThemes.animationDuration,
|
|
|
|
|
curve: FluffyThemes.animationCurve,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> _setActivityItems() async {
|
|
|
|
|
final ActivityPlanRequest request = ActivityPlanRequest(
|
|
|
|
|
topic: "",
|
|
|
|
|
@ -123,12 +135,99 @@ class ActivitySuggestionsAreaState extends State<ActivitySuggestionsArea> {
|
|
|
|
|
vertical: 16.0,
|
|
|
|
|
horizontal: FluffyThemes.isColumnMode(context) ? 16.0 : 0.0,
|
|
|
|
|
),
|
|
|
|
|
child: SingleChildScrollView(
|
|
|
|
|
controller: _scrollController,
|
|
|
|
|
child: Wrap(
|
|
|
|
|
children: cards,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
height: FluffyThemes.isColumnMode(context)
|
|
|
|
|
? cardHeight + 2 * cardPadding + 16.0
|
|
|
|
|
: null,
|
|
|
|
|
child: FluffyThemes.isColumnMode(context)
|
|
|
|
|
? Stack(
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
children: [
|
|
|
|
|
// Main content
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.symmetric(
|
|
|
|
|
horizontal: 45.0,
|
|
|
|
|
), // Space for buttons
|
|
|
|
|
child: ListView(
|
|
|
|
|
controller: _scrollController,
|
|
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
|
|
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
|
|
|
|
children: cards,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
// Left button
|
|
|
|
|
Positioned(
|
|
|
|
|
left: 0,
|
|
|
|
|
top: cardHeight / 2 - 20.0,
|
|
|
|
|
child: Container(
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: Theme.of(context)
|
|
|
|
|
.cardColor
|
|
|
|
|
.withAlpha((0.8 * 255).toInt()),
|
|
|
|
|
borderRadius: BorderRadius.circular(25),
|
|
|
|
|
),
|
|
|
|
|
child: IconButton(
|
|
|
|
|
icon: const Icon(Icons.chevron_left),
|
|
|
|
|
onPressed: () => _scrollToNextItem(AxisDirection.left),
|
|
|
|
|
iconSize: 24.0,
|
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
|
constraints: const BoxConstraints(),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
// Right button
|
|
|
|
|
Positioned(
|
|
|
|
|
right: 0,
|
|
|
|
|
top: cardHeight / 2 - 20.0,
|
|
|
|
|
child: Container(
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: Theme.of(context)
|
|
|
|
|
.cardColor
|
|
|
|
|
.withAlpha((0.8 * 255).toInt()),
|
|
|
|
|
borderRadius: BorderRadius.circular(25),
|
|
|
|
|
),
|
|
|
|
|
child: IconButton(
|
|
|
|
|
icon: const Icon(Icons.chevron_right),
|
|
|
|
|
onPressed: () => _scrollToNextItem(AxisDirection.right),
|
|
|
|
|
iconSize: 24.0,
|
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
|
constraints: const BoxConstraints(),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
// Create Chat button
|
|
|
|
|
Positioned(
|
|
|
|
|
right: 0,
|
|
|
|
|
top: cardHeight / 2 + 30.0,
|
|
|
|
|
child: Container(
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: Theme.of(context)
|
|
|
|
|
.primaryColor
|
|
|
|
|
.withAlpha((0.9 * 255).toInt()),
|
|
|
|
|
borderRadius: BorderRadius.circular(25),
|
|
|
|
|
),
|
|
|
|
|
child: IconButton(
|
|
|
|
|
icon: const Icon(Icons.add_comment, color: Colors.white),
|
|
|
|
|
tooltip: L10n.of(context).createOwnChat,
|
|
|
|
|
onPressed: () => context.go('/rooms/newgroup'),
|
|
|
|
|
iconSize: 24.0,
|
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
|
constraints: const BoxConstraints(),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
: SingleChildScrollView(
|
|
|
|
|
controller: _scrollController,
|
|
|
|
|
child: Wrap(
|
|
|
|
|
spacing: 8.0,
|
|
|
|
|
runSpacing: 8.0,
|
|
|
|
|
children: cards,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|