Skip to content

Commit

Permalink
Merge branch 'new'
Browse files Browse the repository at this point in the history
  • Loading branch information
duong2417 committed Nov 14, 2024
2 parents d92580b + 340766f commit 1a09241
Show file tree
Hide file tree
Showing 33 changed files with 1,537 additions and 148 deletions.
145 changes: 145 additions & 0 deletions lib/_shared/button/button_with_popup.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import 'package:flutter/material.dart';

class ButtonWithPopup<T> extends StatefulWidget {
const ButtonWithPopup(
{
// required this.onChanged,
required this.items,
this.onTap,
required this.child});
// final Function(T) onChanged;
final List<DropdownMenuItem<T>> items;
final Widget child;
final Function()? onTap;
@override
_ButtonWithPopupState<T> createState() => _ButtonWithPopupState<T>();
}

class _ButtonWithPopupState<T> extends State<ButtonWithPopup<T>> {
String? selectedItem;
final LayerLink _layerLink = LayerLink();

void _onDropdownTap() async {
print('onDropdownTap');
// Khi đã có dữ liệu, hiển thị dropdown items
if (widget.items.isNotEmpty) {
print('items không rỗng');
_showOverlay(); //ko do day
} else {
print('items rỗng');
// MsgDialog.showError(msg: 'Không tải được dữ liệu!');
}
}

final GlobalKey _key = GlobalKey();
OverlayEntry? _overlayEntry;
void _showOverlay() {
print('show overlay');
//null check
final renderBox = _key.currentContext!.findRenderObject() as RenderBox;
final size = renderBox.size;
print('size (dropdownNoFetchItems): $size');
final position = renderBox.localToGlobal(Offset.zero);

// Tính chiều cao của popup dựa trên số lượng items
double popupHeight = widget.items.length * 50.0; // Giả sử mỗi item cao 58px
// final offset = renderBox.localToGlobal(Offset.zero);
// Lấy chiều cao màn hình
// Tính khoảng cách từ vị trí widget đến mép trên
double distanceToTop = position.dy;

// Tính khoảng cách offset để giữ popup cách mép trên 100 pixels nếu cần thiết
double offsetY = -popupHeight;
if (distanceToTop - popupHeight < 20) {
//cach mep tren man hinh 20
offsetY = -distanceToTop + 20;
}
_overlayEntry = OverlayEntry(
builder: (context) => Stack(
children: [
GestureDetector(
onTap: () {
_removeOverlay(); // Call this when tapping outside
},
child: Container(
color: Colors.transparent, // Transparent barrier
),
),
Positioned(
// left: offset.dx,
// top: offset.dy + size.height,
width: size.width,
// width: _key.currentContext!.size!.width,
child: CompositedTransformFollower(
//để popup luôn di chuyển theo field khi cuộn
link: _layerLink,
showWhenUnlinked: false,
offset: Offset(0, offsetY),
// offset: Offset(0, -popupHeight),
// offset: Offset(0, _key.currentContext!.size!.height),
child: Material(
elevation: 2.0,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: popupHeight, // Đặt chiều cao tối đa của popup
),
child: ListView(
padding: EdgeInsets.zero,
shrinkWrap: true,
children: widget.items.map((item) {
return SizedBox(
height: 50,
child: ListTile(
title: item.child,
onTap: () {
item.onTap?.call();
// setState(() {
// selectedItem = (item.child as Text).data;
// });
// if (item.value != null) {
// widget.onChanged(item.value!);
// }
_removeOverlay();
},
),
);
}).toList(),
),
),
),
),
),
],
),
);

Overlay.of(context).insert(_overlayEntry!);
}

void _removeOverlay() {
_overlayEntry?.remove();
_overlayEntry = null;
}

@override
Widget build(BuildContext context) {
// const lightgrey = const Color.fromRGBO(237, 237, 237, 1);
// const darkgrey = const Color.fromRGBO(104, 102, 102, 1);
return CompositedTransformTarget(
link: _layerLink,
child: GestureDetector(
key: _key,
onTap: widget.onTap,
onLongPress: _onDropdownTap,
behavior: HitTestBehavior.opaque,
onTapDown: (details) {
if (_overlayEntry != null) {
_removeOverlay();
}
}, // Điều khiển khi tap vào dropdown
child: Material(
child: widget.child,
)),
);
}
}
26 changes: 26 additions & 0 deletions lib/_shared/button/my_chip_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';

class MyFilterChipButton extends StatelessWidget {
const MyFilterChipButton({
super.key,
required this.onSelected,
required this.label,
required this.selected,
});
final void Function(bool) onSelected;
final String label;
final bool selected;
@override
Widget build(BuildContext context) {
return FilterChip(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
label: Text(label),
selected: selected, //t//bloc.hasLyric &&
// selected: bloc.isHighLightMode,//f
disabledColor: Colors.grey,
selectedColor: Colors.black,
onSelected: (bool value) {
onSelected(value);
});
}
}
20 changes: 20 additions & 0 deletions lib/_shared/button/my_close_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:flutter/material.dart';

class MyCloseButton extends StatelessWidget {
const MyCloseButton({super.key, required this.onPressed});
final void Function() onPressed;
@override
Widget build(BuildContext context) {
return IconButton(
icon: Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey,
),
child: const Icon(Icons.close, size: 20)), //24
padding: EdgeInsets.zero, // Không có padding
constraints: const BoxConstraints(), // Loại bỏ các ràng buộc mặc định
onPressed: onPressed,
);
}
}
35 changes: 35 additions & 0 deletions lib/_shared/button/my_elevated_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:flutter/material.dart';

// ignore: must_be_immutable
class MyElevatedButton extends StatelessWidget {
const MyElevatedButton(
{super.key,
required this.onPressed,
required this.buttonName,
this.textColor,
this.backgroundColor,
this.width,
this.height});
final String buttonName;
final Function()? onPressed;
final Color? textColor;
final Color? backgroundColor;
final double? width;
final double? height;
@override
Widget build(BuildContext context) {
return ElevatedButton(
style: ButtonStyle(
// fixedSize:MaterialStatePropertyAll(Size(width??,height)),
// textStyle: MaterialStatePropertyAll(
// GoogleFonts.sarabun(
// color: textColor, fontWeight: FontWeight.bold, fontSize: 12)
// ),
elevation: WidgetStateProperty.all(6),
backgroundColor:
WidgetStatePropertyAll(backgroundColor ?? Colors.transparent),
),
onPressed: onPressed,
child: Text(buttonName));
}
}
3 changes: 3 additions & 0 deletions lib/_shared/data/chat_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ final class Message {

Map<String, dynamic> toMap() =>
{'message': message, 'sender': sender, 'time': timestamp};
@override
String toString() => toMap().toString();
// 'Message(id: $id, message: $message, sender: $sender, timestamp: $timestamp, translations: $translations)';
}

final class UserDetail {
Expand Down
28 changes: 28 additions & 0 deletions lib/_shared/dialog/loading_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:flutter/cupertino.dart';
import '../../config/routes/navigator.dart';
import '../../main.dart';

class LoadingDialog {
static showLoading({BuildContext? context}) {
showCupertinoDialog(
context: globalAppContext ?? context!,
builder: (context) {
return const CupertinoAlertDialog(
content: LoadingState(),
);
});
}

static hideLoading() {
pop();
}
}

class LoadingState extends StatelessWidget {
const LoadingState({super.key});

@override
Widget build(BuildContext context) {
return const Center(child: CupertinoActivityIndicator());
}
}
71 changes: 71 additions & 0 deletions lib/_shared/dialog/message_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../config/routes/navigator.dart';
import '../../main.dart';

class MessageDialog {
static void showMessageDialog({
Widget? contentWidget,
String? contentText,
String? closeText = 'Close',
List<Widget>? actions,
bool tapOutsideToClose = false,
Color? color,
Widget? titleWidget,
String? titleText,
Function()? onTapClose,
bool showCloseButton = true,
}) {
showCupertinoModalPopup<void>(
context: globalAppContext!,
barrierDismissible: tapOutsideToClose,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: titleWidget ??
Text(
titleText ?? '',
style: const TextStyle(
color: Colors.blue, fontWeight: FontWeight.bold),
),
content: Material(
color: Colors.transparent,
child: contentWidget ??
Text(contentText ?? '',
textAlign: TextAlign.start,
style: const TextStyle(fontSize: 16)),
),
actions: showCloseButton
? actions ??
[
TextButton(
onPressed: onTapClose ??
() {
pop();
},
child: Text(closeText ?? 'OK'))
]
: [],
);
},
);
}

static void showError(
String err, {
Widget? contentWidget,
String? closeText = 'Close',
List<Widget>? actions,
bool tapOutsideToClose = false,
String? titleText,
}) {
showMessageDialog(
color: Colors.red,
contentText: err,
titleWidget: Text(titleText ?? 'Error',
style: const TextStyle(color: Colors.red, fontSize: 20)),
contentWidget: contentWidget,
closeText: closeText,
actions: actions,
tapOutsideToClose: tapOutsideToClose);
}
}
Loading

0 comments on commit 1a09241

Please sign in to comment.