fbmobile/lib/ui/views/history_view.dart

192 lines
6.6 KiB
Dart

import 'package:clipboard/clipboard.dart';
import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:provider/provider.dart';
import 'package:share/share.dart';
import '../../core/enums/viewstate.dart';
import '../../core/models/session.dart';
import '../../core/util/formatter_util.dart';
import '../../core/viewmodels/history_model.dart';
import '../../ui/widgets/centered_error_row.dart';
import '../shared/app_colors.dart';
import '../widgets/my_appbar.dart';
import 'base_view.dart';
class HistoryView extends StatelessWidget {
static const routeName = '/history';
@override
Widget build(BuildContext context) {
var url = Provider.of<Session>(context).url;
return BaseView<HistoryModel>(
onModelReady: (model) {
model.init();
return model.getHistory();
},
builder: (context, model, child) => Scaffold(
appBar: MyAppBar(title: Text(translate('titles.history'))),
backgroundColor: backgroundColor,
body: model.state == ViewState.Busy
? Center(child: CircularProgressIndicator())
: (model.errorMessage == null
? Container(
padding: EdgeInsets.all(0),
child: RefreshIndicator(onRefresh: () => model.getHistory(), child: _render(model, url, context)))
: Container(
padding: EdgeInsets.all(25),
child: CenteredErrorRow(
model.errorMessage,
retryCallback: () => model.getHistory(),
)))),
);
}
Widget _render(HistoryModel model, String url, BuildContext context) {
List<Widget> cards = [];
if (model.pastes.length > 0) {
model.pastes.reversed.forEach((paste) {
List<Widget> widgets = [];
var fullPasteUrl = '$url/${paste.id}';
var openInBrowserButton = _renderOpenInBrowser(model, fullPasteUrl);
var dateWidget = ListTile(
title: Text(FormatterUtil.formatEpoch(paste.date.millisecondsSinceEpoch)),
subtitle: Text(translate('history.date')),
);
var linkWidget = ListTile(
title: Text(translate('history.open_link')),
trailing: openInBrowserButton,
);
var copyWidget = ListTile(
title: Text(translate('history.copy_link.description')),
trailing: IconButton(
icon: Icon(Icons.copy, color: Colors.blue, textDirection: TextDirection.ltr),
onPressed: () {
FlutterClipboard.copy(fullPasteUrl).then((value) {
final snackBar = SnackBar(
action: SnackBarAction(
label: translate('history.copy_link.dismiss'),
textColor: Colors.blue,
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
content: Text(translate('history.copy_link.copied')),
duration: Duration(seconds: 10),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
});
}));
var deleteWidget = ListTile(
title: Text(translate('history.delete')),
trailing: IconButton(
icon: Icon(Icons.delete, color: Colors.red),
onPressed: () {
return model.deletePaste(paste.id);
}));
if (!paste.isMulti) {
var titleWidget = ListTile(
title: Text(paste.filename ?? paste.id),
subtitle: Text(translate('history.filename')),
);
var fileSizeWidget = ListTile(
title: Text(FormatterUtil.formatBytes(paste.filesize, 2)),
subtitle: Text(translate('history.filesize')),
);
var idWidget = ListTile(
title: Text(paste.id),
subtitle: Text(translate('history.id')),
);
var mimeTypeWidget = ListTile(
title: Text(paste.mimetype),
subtitle: Text(translate('history.mimetype')),
);
widgets.add(titleWidget);
widgets.add(idWidget);
widgets.add(fileSizeWidget);
widgets.add(mimeTypeWidget);
} else {
paste.items.forEach((element) {
widgets.add(ListTile(
title: Text(element),
subtitle: Text(translate('history.multipaste_element')),
trailing: _renderOpenInBrowser(model, '$url/$element'),
));
});
}
widgets.add(dateWidget);
widgets.add(linkWidget);
widgets.add(copyWidget);
widgets.add(deleteWidget);
var expandable = ExpandableTheme(
data: ExpandableThemeData(
iconPlacement: ExpandablePanelIconPlacement.right,
headerAlignment: ExpandablePanelHeaderAlignment.center,
hasIcon: true,
iconColor: Colors.blue,
tapHeaderToExpand: true),
child: ExpandablePanel(
header: InkWell(
onLongPress: () => model.deletePaste(paste.id),
child: Text(
paste.id,
style: TextStyle(color: Colors.blue),
textAlign: TextAlign.left,
)),
expanded: Column(
mainAxisSize: MainAxisSize.min,
children: widgets,
),
),
);
cards.add(Card(
child: ListTile(
title: expandable,
trailing: Wrap(children: [
openInBrowserButton,
IconButton(
icon: Icon(Icons.share, color: Colors.blue, textDirection: TextDirection.ltr),
onPressed: () {
return Share.share(fullPasteUrl);
})
]),
subtitle: Text(!paste.isMulti ? paste.filename : '', style: TextStyle(fontStyle: FontStyle.italic)),
),
));
});
} else {
cards.add(Card(
child: ListTile(
title: Text(translate('history.no_items')),
),
));
}
return ListView(
padding: const EdgeInsets.all(8),
children: cards,
physics: AlwaysScrollableScrollPhysics(),
);
}
Widget _renderOpenInBrowser(HistoryModel model, String url) {
return IconButton(
icon: Icon(Icons.open_in_new, color: Colors.blue, textDirection: TextDirection.ltr),
onPressed: () {
return model.openLink(url);
});
}
}