correções do pr
This commit is contained in:
parent
aa1bd55818
commit
a7f1ea418b
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
|
|
@ -164,13 +164,14 @@ class _DocumentViewerScreenState extends ScreenState<DocumentViewerScreen> {
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backAction() => widget.bloc.events.unselectDocument();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final String title = widget.doc.$1.description;
|
final String title = widget.doc.$1.description;
|
||||||
final theme = FlutterFlowTheme.of(context);
|
final theme = FlutterFlowTheme.of(context);
|
||||||
final locale = FFLocalizations.of(context);
|
final locale = FFLocalizations.of(context);
|
||||||
|
|
||||||
backAction() => widget.bloc.events.unselectDocument();
|
|
||||||
infoAction() => DetailsComponentWidget(
|
infoAction() => DetailsComponentWidget(
|
||||||
buttons: [],
|
buttons: [],
|
||||||
statusHashMap: [
|
statusHashMap: [
|
||||||
|
@ -225,6 +226,7 @@ class _DocumentViewerScreenState extends ScreenState<DocumentViewerScreen> {
|
||||||
return ReadView(
|
return ReadView(
|
||||||
title: widget.doc.$1.description,
|
title: widget.doc.$1.description,
|
||||||
url: widget.doc.$2.toString(),
|
url: widget.doc.$2.toString(),
|
||||||
|
onError: backAction,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,14 +332,16 @@ class DocumentModel extends FlutterFlowModel<DocumentPage> {
|
||||||
Widget itemFooterBuilder<T extends Category>(
|
Widget itemFooterBuilder<T extends Category>(
|
||||||
Future<List<T?>> Function() fetchData) =>
|
Future<List<T?>> Function() fetchData) =>
|
||||||
Builder(builder: (context) {
|
Builder(builder: (context) {
|
||||||
CategoryComponent categoryItemBuilder<T>(T? item) {
|
CategoryComponent categoryItemBuilder<T>(T? item, bool isSelected) {
|
||||||
return CategoryComponent(category: item! as Category);
|
return CategoryComponent(
|
||||||
|
category: item! as Category, isSelected: isSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EnhancedCarouselView<T>(
|
return EnhancedCarouselView<T>(
|
||||||
dataProvider: fetchData,
|
dataProvider: fetchData,
|
||||||
itemBuilder: categoryItemBuilder,
|
itemBuilder: categoryItemBuilder,
|
||||||
filter: filterByCategory<T>,
|
filter: filterByCategory<T>,
|
||||||
|
showIndicator: true,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -654,64 +658,71 @@ class DocumentComponent extends StatelessComponent {
|
||||||
final description = document.description;
|
final description = document.description;
|
||||||
final title = document.category.title;
|
final title = document.category.title;
|
||||||
const double size = 20;
|
const double size = 20;
|
||||||
|
final date = ValidatorUtil.toLocalDateTime(
|
||||||
|
'yyyy-MM-dd',
|
||||||
|
document.updatedAt,
|
||||||
|
);
|
||||||
|
|
||||||
return InkWell(
|
return Tooltip(
|
||||||
onTap: () => onPressed(document, context),
|
message: description,
|
||||||
enableFeedback: true,
|
child: InkWell(
|
||||||
overlayColor: WidgetStateProperty.all<Color>(primaryColor),
|
onTap: () => onPressed(document, context),
|
||||||
borderRadius: BorderRadius.circular(10),
|
enableFeedback: true,
|
||||||
child: SizedBox(
|
overlayColor: WidgetStateProperty.all<Color>(primaryColor),
|
||||||
height: boxHeight,
|
borderRadius: BorderRadius.circular(10),
|
||||||
child: Row(
|
child: SizedBox(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
height: boxHeight,
|
||||||
spacing: size,
|
child: Row(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
// const SizedBox(width: 10),
|
spacing: size,
|
||||||
Icon(icon, color: color),
|
children: [
|
||||||
|
// const SizedBox(width: 10),
|
||||||
|
Icon(icon, color: color),
|
||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: description,
|
message: description,
|
||||||
child: AutoText(
|
child: AutoText(
|
||||||
description,
|
description,
|
||||||
style: textStyleMajor,
|
style: textStyleMajor,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Tooltip(
|
||||||
AutoText(
|
message: date,
|
||||||
ValidatorUtil.toLocalDateTime(
|
child: AutoText(
|
||||||
'yyyy-MM-dd',
|
date,
|
||||||
document.updatedAt,
|
style: textStyleMinor,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
style: textStyleMinor,
|
],
|
||||||
overflow: TextOverflow.ellipsis,
|
),
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
Expanded(
|
child: Column(
|
||||||
child: Column(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
children: [
|
||||||
children: [
|
_buildTooltip(title, color, context, constraints),
|
||||||
_buildTooltip(title, color, context, constraints),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
// const SizedBox(width: 10),
|
||||||
// const SizedBox(width: 10),
|
Center(
|
||||||
Center(
|
child: Icon(
|
||||||
child: Icon(
|
Icons.arrow_right,
|
||||||
Icons.arrow_right,
|
color: primaryText,
|
||||||
color: primaryText,
|
),
|
||||||
),
|
),
|
||||||
),
|
] //
|
||||||
] //
|
.addToStart(space)
|
||||||
.addToStart(space)
|
.addToEnd(space),
|
||||||
.addToEnd(space),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -732,16 +743,19 @@ class DocumentComponent extends StatelessComponent {
|
||||||
|
|
||||||
class CategoryComponent extends StatelessComponent {
|
class CategoryComponent extends StatelessComponent {
|
||||||
final Category category;
|
final Category category;
|
||||||
|
final bool isSelected;
|
||||||
|
|
||||||
const CategoryComponent({
|
const CategoryComponent({
|
||||||
super.key,
|
super.key,
|
||||||
required this.category,
|
required this.category,
|
||||||
|
this.isSelected = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final backgroundTheme = FlutterFlowTheme.of(context).primaryBackground;
|
final backgroundTheme = FlutterFlowTheme.of(context).primaryBackground;
|
||||||
final textTheme = FlutterFlowTheme.of(context).primaryText;
|
final textTheme = FlutterFlowTheme.of(context).primaryText;
|
||||||
|
final color = isSelected ? category.color.highlight : category.color;
|
||||||
return ColoredBox(
|
return ColoredBox(
|
||||||
color: backgroundTheme,
|
color: backgroundTheme,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
@ -751,7 +765,7 @@ class CategoryComponent extends StatelessComponent {
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: category.color,
|
color: color,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
|
|
|
@ -34,20 +34,13 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
||||||
try {
|
try {
|
||||||
final GetLocalsCall callback = FreAccessWSGlobal.getLocalsCall;
|
final GetLocalsCall callback = FreAccessWSGlobal.getLocalsCall;
|
||||||
var response = await callback.call();
|
var response = await callback.call();
|
||||||
final bool? isError = response.jsonBody['error'];
|
if (response.jsonBody == null) return;
|
||||||
|
|
||||||
|
final bool? isError = response.jsonBody['error'];
|
||||||
if (isError == true) {
|
if (isError == true) {
|
||||||
LocalUtil.handleError(context, response.jsonBody['error_msg']);
|
LocalUtil.handleError(context, response.jsonBody['error_msg']);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (response.jsonBody == null) {
|
|
||||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
|
||||||
// enText: 'Verify your connection',
|
|
||||||
// ptText: 'Verifique sua conexão',
|
|
||||||
// );
|
|
||||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<dynamic> locals = response.jsonBody['locais'] ?? [];
|
final List<dynamic> locals = response.jsonBody['locais'] ?? [];
|
||||||
final bool isEmpty = locals.isEmpty;
|
final bool isEmpty = locals.isEmpty;
|
||||||
|
|
|
@ -12,3 +12,4 @@ export 'utils/string_util.dart';
|
||||||
export 'utils/text_util.dart';
|
export 'utils/text_util.dart';
|
||||||
export 'utils/validator_util.dart';
|
export 'utils/validator_util.dart';
|
||||||
export 'utils/webview_util.dart';
|
export 'utils/webview_util.dart';
|
||||||
|
export 'utils/color_util.dart';
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ColorUtil {
|
||||||
|
static Color getContrastColor(Color a, Color b) {
|
||||||
|
double luminance(Color color) {
|
||||||
|
return (0.299 * color.r + 0.587 * color.g + 0.114 * color.b) / 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
double contrastRatio(Color a, Color b) {
|
||||||
|
final lumA = luminance(a) + 0.05;
|
||||||
|
final lumB = luminance(b) + 0.05;
|
||||||
|
return lumA > lumB ? lumA / lumB : lumB / lumA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contrastRatio(a, b) < 4.5) {
|
||||||
|
// Find a color with higher contrast within the same hue
|
||||||
|
final hsv = HSVColor.fromColor(a);
|
||||||
|
double hue = hsv.hue;
|
||||||
|
double saturation = hsv.saturation;
|
||||||
|
double brightness = hsv.value;
|
||||||
|
|
||||||
|
// Increase brightness to ensure higher contrast
|
||||||
|
brightness = brightness > 0.5 ? brightness - 0.5 : brightness + 0.5;
|
||||||
|
|
||||||
|
return HSVColor.fromAHSV(1.0, hue, saturation, brightness).toColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color getSelfContrastColor(Color color) {
|
||||||
|
final hsv = HSVColor.fromColor(color);
|
||||||
|
double hue = hsv.hue;
|
||||||
|
double saturation = hsv.saturation;
|
||||||
|
double brightness = hsv.value;
|
||||||
|
|
||||||
|
// Increase brightness to ensure higher contrast
|
||||||
|
brightness = brightness > 0.5 ? brightness - 0.5 : brightness + 0.5;
|
||||||
|
|
||||||
|
return HSVColor.fromAHSV(1.0, hue, saturation, brightness).toColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ColorUtilExtension on Color {
|
||||||
|
Color get highlight => ColorUtil.getSelfContrastColor(this);
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
/// [Base]
|
/// [Base]
|
||||||
|
library;
|
||||||
|
|
||||||
export 'widgets/page.dart';
|
export 'widgets/page.dart';
|
||||||
export 'widgets/component.dart';
|
export 'widgets/component.dart';
|
||||||
export 'widgets/screen.dart';
|
export 'widgets/screen.dart';
|
||||||
|
|
|
@ -2,70 +2,106 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:hub/flutter_flow/index.dart';
|
import 'package:hub/flutter_flow/index.dart';
|
||||||
import 'package:hub/shared/utils.dart';
|
import 'package:hub/shared/utils.dart';
|
||||||
|
|
||||||
class EnhancedCarouselView<T> extends StatelessWidget {
|
class EnhancedCarouselView<T> extends StatefulWidget {
|
||||||
final Future<List<T?>> Function() dataProvider;
|
final Future<List<T?>> Function() dataProvider;
|
||||||
final void Function(T, BuildContext) filter;
|
final void Function(T, BuildContext) filter;
|
||||||
final Widget Function<T>(T? item) itemBuilder;
|
final Widget Function<T>(T? item, bool isSelected) itemBuilder;
|
||||||
|
final bool showIndicator;
|
||||||
|
|
||||||
const EnhancedCarouselView({
|
const EnhancedCarouselView({
|
||||||
super.key,
|
super.key,
|
||||||
required this.dataProvider,
|
required this.dataProvider,
|
||||||
required this.filter,
|
required this.filter,
|
||||||
required this.itemBuilder,
|
required this.itemBuilder,
|
||||||
|
this.showIndicator = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_EnhancedCarouselViewState<T> createState() =>
|
||||||
|
_EnhancedCarouselViewState<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EnhancedCarouselViewState<T> extends State<EnhancedCarouselView<T>> {
|
||||||
|
T? selectedCategory;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = FlutterFlowTheme.of(context);
|
final theme = FlutterFlowTheme.of(context);
|
||||||
final backgroundColor = theme.primary;
|
final backgroundColor = theme.primary;
|
||||||
final overlayColor = WidgetStateProperty.all(Colors.transparent);
|
final overlayColor = WidgetStateProperty.all(Colors.transparent);
|
||||||
|
|
||||||
return Column(
|
return Stack(
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
spacing: 20,
|
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Column(
|
||||||
padding: const EdgeInsets.fromLTRB(15, 0, 50, 0),
|
mainAxisSize: MainAxisSize.max,
|
||||||
child: Text(
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
FFLocalizations.of(context).getVariableText(
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
ptText: 'Suas Categorias',
|
children: [
|
||||||
enText: 'Your Categories',
|
Padding(
|
||||||
),
|
padding: const EdgeInsets.fromLTRB(15, 0, 50, 0),
|
||||||
style: TextStyle(
|
child: Text(
|
||||||
color: FlutterFlowTheme.of(context).primaryText,
|
FFLocalizations.of(context).getVariableText(
|
||||||
fontSize: LimitedFontSizeUtil.getHeaderFontSize(context),
|
ptText: 'Suas Categorias',
|
||||||
),
|
enText: 'Your Categories',
|
||||||
),
|
|
||||||
),
|
|
||||||
FutureBuilder<List<T?>>(
|
|
||||||
future: dataProvider(),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (!snapshot.hasData) return SizedBox();
|
|
||||||
final items =
|
|
||||||
snapshot.data!.map((item) => itemBuilder(item)).toList();
|
|
||||||
return SizedBox(
|
|
||||||
height: 130, // Set a specific height
|
|
||||||
child: CarouselView(
|
|
||||||
itemExtent: 140,
|
|
||||||
enableSplash: true,
|
|
||||||
itemSnapping: true,
|
|
||||||
controller: CarouselController(initialItem: 1),
|
|
||||||
backgroundColor: backgroundColor,
|
|
||||||
overlayColor: overlayColor,
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
elevation: 0,
|
|
||||||
reverse: true,
|
|
||||||
shrinkExtent: 10,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
onTap: (index) => filter(snapshot.data![index] as T, context),
|
|
||||||
children: items,
|
|
||||||
),
|
),
|
||||||
);
|
style: TextStyle(
|
||||||
}),
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: LimitedFontSizeUtil.getHeaderFontSize(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FutureBuilder<List<T?>>(
|
||||||
|
future: widget.dataProvider(),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (!snapshot.hasData) return SizedBox();
|
||||||
|
final items = snapshot.data!
|
||||||
|
.map((item) =>
|
||||||
|
widget.itemBuilder(item, item == selectedCategory))
|
||||||
|
.toList();
|
||||||
|
return SizedBox(
|
||||||
|
height: 130, // Set a specific height
|
||||||
|
child: CarouselView(
|
||||||
|
itemExtent: 140,
|
||||||
|
enableSplash: true,
|
||||||
|
itemSnapping: true,
|
||||||
|
controller: CarouselController(initialItem: 1),
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
overlayColor: overlayColor,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
elevation: 0,
|
||||||
|
reverse: true,
|
||||||
|
shrinkExtent: 10,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
onTap: (index) {
|
||||||
|
setState(() {
|
||||||
|
if (selectedCategory == snapshot.data![index])
|
||||||
|
selectedCategory = null;
|
||||||
|
else
|
||||||
|
selectedCategory = snapshot.data![index] as T;
|
||||||
|
});
|
||||||
|
widget.filter(snapshot.data![index] as T, context);
|
||||||
|
},
|
||||||
|
children: items,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (widget.showIndicator)
|
||||||
|
Positioned(
|
||||||
|
left: 0,
|
||||||
|
top: 50,
|
||||||
|
child: Icon(Icons.arrow_left, size: 30, color: Colors.grey),
|
||||||
|
),
|
||||||
|
if (widget.showIndicator)
|
||||||
|
Positioned(
|
||||||
|
right: 0,
|
||||||
|
top: 50,
|
||||||
|
child: Icon(Icons.arrow_right, size: 30, color: Colors.grey),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hub/flutter_flow/index.dart';
|
||||||
import 'package:rx_bloc/rx_bloc.dart';
|
import 'package:rx_bloc/rx_bloc.dart';
|
||||||
import 'package:rx_bloc_list/rx_bloc_list.dart';
|
import 'package:rx_bloc_list/rx_bloc_list.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
@ -211,6 +212,10 @@ class EnhancedListViewState<ItemType, HeaderType, FooterType, QueryType>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final String defaultMessage = FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Nenhum item encontrado',
|
||||||
|
enText: 'No items found',
|
||||||
|
);
|
||||||
final header = StreamBuilder<List<HeaderType>>(
|
final header = StreamBuilder<List<HeaderType>>(
|
||||||
stream: bloc.states.headerItems.cast<List<HeaderType>>(),
|
stream: bloc.states.headerItems.cast<List<HeaderType>>(),
|
||||||
builder: (context, headerSnapshot) {
|
builder: (context, headerSnapshot) {
|
||||||
|
@ -250,7 +255,9 @@ class EnhancedListViewState<ItemType, HeaderType, FooterType, QueryType>
|
||||||
} else if (bodySnapshot.hasError) {
|
} else if (bodySnapshot.hasError) {
|
||||||
return EnhancedErrorWidget(error: bodySnapshot.error);
|
return EnhancedErrorWidget(error: bodySnapshot.error);
|
||||||
} else if (!bodySnapshot.hasData || bodySnapshot.data!.isEmpty) {
|
} else if (!bodySnapshot.hasData || bodySnapshot.data!.isEmpty) {
|
||||||
return const SizedBox.shrink();
|
return Center(
|
||||||
|
child: Text(defaultMessage),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
itemCount: bodySnapshot.data?.length ?? 0,
|
itemCount: bodySnapshot.data?.length ?? 0,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hub/features/backend/index.dart';
|
// Removed unnecessary import
|
||||||
import 'package:hub/flutter_flow/index.dart';
|
import 'package:hub/flutter_flow/index.dart';
|
||||||
import 'package:hub/shared/utils/dialog_util.dart';
|
import 'package:hub/shared/utils/dialog_util.dart';
|
||||||
import 'package:hub/shared/widgets.dart';
|
import 'package:hub/shared/widgets.dart';
|
||||||
|
@ -32,9 +32,11 @@ abstract interface class Viewer extends StatelessComponent {
|
||||||
class ReadView extends StatefulWidget {
|
class ReadView extends StatefulWidget {
|
||||||
final String url;
|
final String url;
|
||||||
final String title;
|
final String title;
|
||||||
|
final VoidCallback onError;
|
||||||
|
|
||||||
const ReadView({
|
const ReadView({
|
||||||
super.key,
|
super.key,
|
||||||
|
required this.onError,
|
||||||
required this.url,
|
required this.url,
|
||||||
required this.title,
|
required this.title,
|
||||||
});
|
});
|
||||||
|
@ -50,8 +52,12 @@ class ReadViewState extends State<ReadView> {
|
||||||
final Future<DocumentType> document = DocumentType.openFile(file.path);
|
final Future<DocumentType> document = DocumentType.openFile(file.path);
|
||||||
return ReadViewController(document: document);
|
return ReadViewController(document: document);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError('Erro ao baixar o PDF', e);
|
final message = FFLocalizations.of(context).getVariableText(
|
||||||
return Future.error(e);
|
ptText: 'Erro ao baixar o PDF',
|
||||||
|
enText: 'Error downloading PDF',
|
||||||
|
);
|
||||||
|
|
||||||
|
return Future.error(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,14 +74,19 @@ class ReadViewState extends State<ReadView> {
|
||||||
throw Exception('Falha ao baixar o PDF');
|
throw Exception('Falha ao baixar o PDF');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError('Erro ao baixar o PDF', e);
|
final message = FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Erro ao baixar o PDF',
|
||||||
|
enText: 'Error downloading PDF',
|
||||||
|
);
|
||||||
|
await throwError(message, e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void logError(String message, dynamic error) {
|
Future<void> throwError(String message, dynamic error) async {
|
||||||
log('$message: $error');
|
log('$message: $error');
|
||||||
DialogUtil.error(context, message);
|
await DialogUtil.error(context, message)
|
||||||
|
.whenComplete(() => widget.onError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -104,7 +115,7 @@ class ReadViewState extends State<ReadView> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onShare() async {
|
Future<void> onShare() async {
|
||||||
try {
|
try {
|
||||||
final Uri uri = Uri.parse(widget.url);
|
final Uri uri = Uri.parse(widget.url);
|
||||||
final response = await http.get(uri);
|
final response = await http.get(uri);
|
||||||
|
@ -113,10 +124,15 @@ class ReadViewState extends State<ReadView> {
|
||||||
name: '${widget.title}.pdf', mimeType: 'application/pdf');
|
name: '${widget.title}.pdf', mimeType: 'application/pdf');
|
||||||
await Share.shareXFiles([xfile], text: 'Confira este PDF!');
|
await Share.shareXFiles([xfile], text: 'Confira este PDF!');
|
||||||
} else {
|
} else {
|
||||||
throw Exception('Erro ao compartilhar o arquivo: ${response.statusCode}');
|
throw Exception(
|
||||||
|
'Erro ao compartilhar o arquivo: ${response.statusCode}');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError('Erro ao compartilhar o arquivo', e);
|
final message = FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Erro ao compartilhar o arquivo',
|
||||||
|
enText: 'Error sharing file',
|
||||||
|
);
|
||||||
|
await throwError(message, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue