150 lines
4.8 KiB
Dart
150 lines
4.8 KiB
Dart
import 'dart:io';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:flutter_vibrate/flutter_vibrate.dart';
|
|
import 'package:moxxyv2/i18n/strings.g.dart';
|
|
import 'package:moxxyv2/shared/models/sticker.dart';
|
|
import 'package:moxxyv2/shared/models/sticker_pack.dart';
|
|
import 'package:moxxyv2/ui/bloc/navigation_bloc.dart' as nav;
|
|
import 'package:moxxyv2/ui/bloc/sticker_pack_bloc.dart';
|
|
import 'package:moxxyv2/ui/bloc/stickers_bloc.dart';
|
|
import 'package:moxxyv2/ui/constants.dart';
|
|
|
|
class StickerPicker extends StatelessWidget {
|
|
StickerPicker({
|
|
required this.width,
|
|
required this.onStickerTapped,
|
|
super.key,
|
|
}) {
|
|
_itemSize = (width - 2 * 15 - 3 * 30) / 4;
|
|
}
|
|
|
|
final double width;
|
|
late final double _itemSize;
|
|
final void Function(Sticker, StickerPack) onStickerTapped;
|
|
|
|
Widget _buildList(BuildContext context, StickersState state) {
|
|
// TODO(PapaTutuWawa): Solve this somewhere else
|
|
final stickerPacks = state.stickerPacks
|
|
.where((pack) => !pack.restricted)
|
|
.toList();
|
|
|
|
if (stickerPacks.isEmpty) {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: Align(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(
|
|
'${t.pages.conversation.stickerPickerNoStickersLine1}\n${t.pages.conversation.stickerPickerNoStickersLine2}',
|
|
textAlign: TextAlign.center,
|
|
),
|
|
TextButton(
|
|
onPressed: () {
|
|
context.read<nav.NavigationBloc>().add(
|
|
nav.PushedNamedEvent(
|
|
const nav.NavigationDestination(stickersRoute),
|
|
),
|
|
);
|
|
},
|
|
child: Text(t.pages.conversation.stickerSettings),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
return ListView.builder(
|
|
itemCount: stickerPacks.length * 2,
|
|
itemBuilder: (_, si) {
|
|
if (si.isEven) {
|
|
return Padding(
|
|
padding: const EdgeInsets.only(left: 15),
|
|
child: Text(
|
|
stickerPacks[si ~/ 2].name,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: const TextStyle(
|
|
fontSize: 20,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
final sindex = (si - 1) ~/ 2;
|
|
return ListView.builder(
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
itemCount: (stickerPacks[sindex].stickers.length / 4).ceil(),
|
|
itemBuilder: (_, index) {
|
|
final stickersLength = stickerPacks[sindex].stickers.length - index * 4;
|
|
return SizedBox(
|
|
width: width,
|
|
child: Row(
|
|
children: List<int>.generate(
|
|
stickersLength >= 4 ?
|
|
4 :
|
|
stickersLength,
|
|
(i) => i,
|
|
).map((rowIndex) {
|
|
return Padding(
|
|
padding: const EdgeInsets.all(15),
|
|
child: InkWell(
|
|
onTap: () {
|
|
onStickerTapped(
|
|
stickerPacks[sindex].stickers[index * 4 + rowIndex],
|
|
stickerPacks[sindex],
|
|
);
|
|
},
|
|
onLongPress: () {
|
|
Vibrate.feedback(FeedbackType.medium);
|
|
|
|
context.read<StickerPackBloc>().add(
|
|
LocallyAvailableStickerPackRequested(
|
|
stickerPacks[sindex].id,
|
|
),
|
|
);
|
|
},
|
|
child: Image.file(
|
|
File(
|
|
stickerPacks[sindex].stickers[index * 4 + rowIndex].path,
|
|
),
|
|
key: ValueKey('${state.stickerPacks[sindex].id}_${index * 4 + rowIndex}'),
|
|
fit: BoxFit.contain,
|
|
width: _itemSize,
|
|
height: _itemSize,
|
|
),
|
|
),
|
|
);
|
|
}).toList(),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return BlocBuilder<StickersBloc, StickersState>(
|
|
builder: (context, state) {
|
|
|
|
return SizedBox(
|
|
height: 250,
|
|
width: MediaQuery.of(context).size.width,
|
|
child: ColoredBox(
|
|
color: Theme.of(context).scaffoldBackgroundColor,
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(top: 16),
|
|
child: _buildList(context, state),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|