changed everything from filcnaplo to refilc finally

This commit is contained in:
Kima
2024-02-24 20:12:25 +01:00
parent 0d1c7b7143
commit 1171e3aaaf
655 changed files with 38728 additions and 44967 deletions

View File

@@ -0,0 +1,85 @@
import 'dart:io';
import 'package:refilc_kreta_api/models/attachment.dart';
import 'package:refilc/helpers/attachment_helper.dart';
import 'package:refilc_mobile_ui/common/widgets/message/image_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
class AttachmentTile extends StatelessWidget {
const AttachmentTile(this.attachment, {super.key});
final Attachment attachment;
Widget buildImage(BuildContext context) {
return FutureBuilder<String>(
future: attachment.download(context),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(12.0),
child: Material(
child: InkWell(
onTap: () {
showModalBottomSheet(
useRootNavigator: true,
isScrollControlled: true,
context: context,
builder: (context) {
return ImageView(snapshot.data!);
},
);
},
borderRadius: BorderRadius.circular(12.0),
child: Ink.image(
image: FileImage(File(snapshot.data ?? "")),
height: 200.0,
width: double.infinity,
fit: BoxFit.cover,
),
),
),
),
);
} else {
return Center(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary),
));
}
},
);
}
@override
Widget build(BuildContext context) {
if (attachment.isImage) return buildImage(context);
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: InkWell(
borderRadius: BorderRadius.circular(12.0),
onTap: () {
attachment.open(context);
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(children: [
const Icon(FeatherIcons.paperclip),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Text(attachment.name,
maxLines: 2, overflow: TextOverflow.ellipsis),
),
),
]),
),
),
);
}
}

View File

@@ -0,0 +1,47 @@
import 'dart:io';
import 'package:refilc/helpers/share_helper.dart';
import 'package:refilc/theme/colors/colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:photo_view/photo_view.dart';
class ImageView extends StatelessWidget {
const ImageView(this.path, {super.key});
final String path;
@override
Widget build(BuildContext context) {
return Material(
color: Theme.of(context).scaffoldBackgroundColor,
child: SafeArea(
minimum: const EdgeInsets.only(top: 24.0),
child: Scaffold(
appBar: AppBar(
leading: BackButton(color: AppColors.of(context).text),
actions: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: IconButton(
onPressed: () => ShareHelper.shareFile(path),
icon: Icon(FeatherIcons.share2,
color: AppColors.of(context).text),
splashRadius: 24.0,
),
),
],
),
body: PhotoView(
imageProvider: FileImage(File(path)),
maxScale: 4.0,
minScale: PhotoViewComputedScale.contained,
backgroundDecoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
),
),
),
),
);
}
}

View File

@@ -0,0 +1,54 @@
import 'package:refilc/theme/colors/colors.dart';
import 'package:refilc_kreta_api/models/message.dart';
import 'package:refilc_mobile_ui/common/widgets/message/message_view_tile.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class MessageView extends StatefulWidget {
const MessageView(this.messages, {super.key});
final List<Message> messages;
static show(List<Message> messages, {required BuildContext context}) =>
Navigator.of(context, rootNavigator: true).push(
CupertinoPageRoute(builder: (context) => MessageView(messages)));
@override
MessageViewState createState() => MessageViewState();
}
class MessageViewState extends State<MessageView> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leadingWidth: 64.0,
leading: BackButton(color: AppColors.of(context).text),
elevation: 0,
actions: const [
// Padding(
// padding: EdgeInsets.only(right: 8.0),
// child: IconButton(
// onPressed: () {},
// icon: Icon(FeatherIcons.archive, color: AppColors.of(context).text),
// splashRadius: 32.0,
// ),
// ),
],
),
body: SafeArea(
child: ListView.builder(
padding: EdgeInsets.zero,
physics: const BouncingScrollPhysics(),
itemCount: widget.messages.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: MessageViewTile(widget.messages[index]),
);
},
),
),
);
}
}

View File

@@ -0,0 +1,188 @@
import 'package:refilc/api/providers/user_provider.dart';
import 'package:refilc/theme/colors/colors.dart';
import 'package:refilc_kreta_api/models/message.dart';
import 'package:refilc_mobile_ui/common/panel/panel.dart';
import 'package:refilc_mobile_ui/common/profile_image/profile_image.dart';
import 'package:refilc_mobile_ui/common/widgets/message/attachment_tile.dart';
import 'package:flutter/material.dart';
import 'package:refilc/utils/format.dart';
import 'package:flutter_custom_tabs/flutter_custom_tabs.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
// import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:i18n_extension/i18n_widget.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:share_plus/share_plus.dart';
import 'message_view_tile.i18n.dart';
class MessageViewTile extends StatelessWidget {
const MessageViewTile(this.message, {super.key});
final Message message;
@override
Widget build(BuildContext context) {
UserProvider user = Provider.of<UserProvider>(context, listen: false);
String recipientLabel = "";
if (message.recipients.any((r) => r.name == user.student?.name)) {
recipientLabel = "me".i18n;
}
if (recipientLabel != "" && message.recipients.length > 1) {
recipientLabel += " +";
recipientLabel += message.recipients
.where((r) => r.name != user.student?.name)
.length
.toString();
}
if (recipientLabel == "") {
// note: convertint to set to remove duplicates
recipientLabel +=
message.recipients.map((r) => r.name).toSet().join(", ");
}
List<Widget> attachments = [];
for (var a in message.attachments) {
attachments.add(AttachmentTile(a));
}
return Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// subject
Center(
child: Text(
message.subject,
softWrap: true,
maxLines: 10,
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 24.0,
height: 1.2,
color: Theme.of(context).textTheme.bodySmall?.color,
),
),
),
const SizedBox(height: 8.0),
// date
Center(
child: Text(
DateFormat("yyyy. MM. dd.", I18n.locale.languageCode)
.format(message.date),
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme.bodySmall?.color,
),
),
),
const SizedBox(height: 28.0),
// author
Container(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16.0),
border: Border.all(
color: Theme.of(context).colorScheme.primary.withOpacity(.25),
width: 1.0,
),
),
child: ListTile(
visualDensity: VisualDensity.compact,
contentPadding: EdgeInsets.zero,
leading: ProfileImage(
isNotePfp: true,
name: message.author,
backgroundColor: Theme.of(context).colorScheme.secondary,
radius: 19.0,
),
title: Text(
message.author,
style: TextStyle(
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme.bodySmall?.color,
),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
subtitle: Text(
"${"to".i18n} $recipientLabel",
style: TextStyle(
fontWeight: FontWeight.w500,
height: 1.2,
color: Theme.of(context)
.textTheme
.bodySmall
?.color
?.withOpacity(0.6),
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
// IconButton(
// onPressed: () {},
// icon: Icon(FeatherIcons.cornerUpLeft,
// color: AppColors.of(context).text),
// splashRadius: 24.0,
// highlightColor: Colors.transparent,
// padding: EdgeInsets.zero,
// visualDensity: VisualDensity.compact,
// ),
IconButton(
onPressed: () {
Share.share(
message.content.escapeHtml(),
subject: 'reFilc',
);
},
icon: Icon(
FeatherIcons.share2,
color: AppColors.of(context).text,
size: 20,
),
splashRadius: 20.0,
highlightColor: Colors.transparent,
padding: EdgeInsets.zero,
visualDensity: VisualDensity.compact,
),
],
),
),
),
const SizedBox(height: 10.0),
// content
Panel(
padding: const EdgeInsets.all(12.0),
child: SelectableLinkify(
text: message.content.escapeHtml(),
options: const LinkifyOptions(looseUrl: true, removeWww: true),
onOpen: (link) {
launch(link.url,
customTabsOption: CustomTabsOption(
toolbarColor: Theme.of(context).scaffoldBackgroundColor,
showPageTitle: true,
));
},
style: const TextStyle(fontWeight: FontWeight.w400),
),
),
// Attachments
...attachments,
],
),
);
}
}

View File

@@ -0,0 +1,24 @@
import 'package:i18n_extension/i18n_extension.dart';
extension Localization on String {
static final _t = Translations.byLocale("hu_hu") +
{
"en_en": {
"me": "me",
"to": "to",
},
"hu_hu": {
"me": "én",
"to": "Címzett:",
},
"de_de": {
"me": "mich",
"to": "zu",
}
};
String get i18n => localize(this, _t);
String fill(List<Object> params) => localizeFill(this, params);
String plural(int value) => localizePlural(value, this, _t);
String version(Object modifier) => localizeVersion(modifier, this, _t);
}

View File

@@ -0,0 +1,34 @@
import 'package:animations/animations.dart';
import 'package:refilc_kreta_api/models/message.dart';
import 'package:refilc/ui/widgets/message/message_tile.dart';
import 'package:refilc_mobile_ui/common/widgets/message/message_view.dart';
import 'package:flutter/material.dart';
class MessageViewable extends StatelessWidget {
const MessageViewable(this.message, {super.key});
final Message message;
@override
Widget build(BuildContext context) {
return OpenContainer(
openBuilder: (context, _) {
return MessageView([message]);
},
closedBuilder: (context, VoidCallback openContainer) {
return MessageTile(message);
},
closedElevation: 0,
openShape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
closedShape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
middleColor: Theme.of(context).colorScheme.background,
openColor: Theme.of(context).scaffoldBackgroundColor,
closedColor: Theme.of(context).colorScheme.background,
transitionType: ContainerTransitionType.fadeThrough,
transitionDuration: const Duration(milliseconds: 400),
useRootNavigator: true,
);
}
}