changed everything from filcnaplo to refilc finally
This commit is contained in:
358
refilc/lib/ui/widgets/grade/grade_tile.dart
Normal file
358
refilc/lib/ui/widgets/grade/grade_tile.dart
Normal file
@@ -0,0 +1,358 @@
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc/theme/colors/colors.dart';
|
||||
import 'package:refilc_kreta_api/models/grade.dart';
|
||||
import 'package:refilc/helpers/subject.dart';
|
||||
import 'package:refilc/utils/format.dart';
|
||||
import 'package:refilc_mobile_ui/pages/grades/calculator/grade_calculator_provider.dart';
|
||||
import 'package:refilc_mobile_ui/pages/grades/subject_grades_container.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GradeTile extends StatelessWidget {
|
||||
const GradeTile(
|
||||
this.grade, {
|
||||
super.key,
|
||||
this.onTap,
|
||||
this.padding,
|
||||
this.censored = false,
|
||||
this.viewOverride = false,
|
||||
});
|
||||
|
||||
final Grade grade;
|
||||
final void Function()? onTap;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
final bool censored;
|
||||
final bool viewOverride;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String title;
|
||||
String subtitle;
|
||||
bool isTitleItalic = false;
|
||||
bool isSubtitleItalic = false;
|
||||
// EdgeInsets leadingPadding = EdgeInsets.zero;
|
||||
bool isSubjectView =
|
||||
SubjectGradesContainer.of(context) != null || viewOverride;
|
||||
String subjectName =
|
||||
grade.subject.renamedTo ?? grade.subject.name.escapeHtml().capital();
|
||||
String modeDescription = grade.mode.description.escapeHtml().capital();
|
||||
String description = grade.description.escapeHtml().capital();
|
||||
|
||||
GradeCalculatorProvider calculatorProvider =
|
||||
Provider.of<GradeCalculatorProvider>(context, listen: false);
|
||||
SettingsProvider settingsProvider = Provider.of<SettingsProvider>(context);
|
||||
// Test order:
|
||||
// description
|
||||
// mode
|
||||
// value name
|
||||
if (grade.type == GradeType.midYear || grade.type == GradeType.ghost) {
|
||||
if (grade.description != "") {
|
||||
title = description;
|
||||
} else {
|
||||
title = modeDescription != ""
|
||||
? modeDescription
|
||||
: grade.value.valueName.split("(")[0];
|
||||
}
|
||||
} else {
|
||||
title = subjectName;
|
||||
isTitleItalic =
|
||||
grade.subject.isRenamed && settingsProvider.renamedSubjectsItalics;
|
||||
}
|
||||
|
||||
// Test order:
|
||||
// subject name
|
||||
// mode + weight != 100
|
||||
if (grade.type == GradeType.midYear) {
|
||||
subtitle = isSubjectView
|
||||
? description != ""
|
||||
? modeDescription
|
||||
: ""
|
||||
: subjectName;
|
||||
isSubtitleItalic = isSubjectView
|
||||
? false
|
||||
: grade.subject.isRenamed && settingsProvider.renamedSubjectsItalics;
|
||||
} else {
|
||||
subtitle = grade.value.valueName.split("(")[0];
|
||||
}
|
||||
|
||||
// if (subtitle != "") leadingPadding = const EdgeInsets.only(top: 2.0);
|
||||
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Padding(
|
||||
padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: ListTile(
|
||||
visualDensity: VisualDensity.compact,
|
||||
contentPadding: isSubjectView
|
||||
? grade.type != GradeType.ghost
|
||||
? const EdgeInsets.symmetric(horizontal: 12.0)
|
||||
: const EdgeInsets.only(left: 12.0, right: 4.0)
|
||||
: const EdgeInsets.only(left: 8.0, right: 12.0),
|
||||
onTap: onTap,
|
||||
// onLongPress: kDebugMode ? () => log(jsonEncode(grade.json)) : null,
|
||||
shape:
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
||||
leading: isSubjectView
|
||||
? GradeValueWidget(grade.value)
|
||||
: GradeValueWidget(
|
||||
grade.value,
|
||||
fill: true,
|
||||
size: 27.5,
|
||||
),
|
||||
// leading: isSubjectView
|
||||
// ? GradeValueWidget(grade.value)
|
||||
// : SizedBox(
|
||||
// width: 44,
|
||||
// height: 44,
|
||||
// child: censored
|
||||
// ? Container(
|
||||
// decoration: BoxDecoration(
|
||||
// color: AppColors.of(context).text,
|
||||
// borderRadius: BorderRadius.circular(60.0),
|
||||
// ),
|
||||
// )
|
||||
// : Center(
|
||||
// child: Padding(
|
||||
// padding: leadingPadding,
|
||||
// child: Icon(
|
||||
// SubjectIcon.resolveVariant(
|
||||
// subject: grade.subject, context: context),
|
||||
// size: 28.0,
|
||||
// color: AppColors.of(context).text,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
title: censored
|
||||
? Wrap(
|
||||
children: [
|
||||
Container(
|
||||
width: 110,
|
||||
height: 15,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.of(context).text,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Text(
|
||||
title,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontStyle: isTitleItalic ? FontStyle.italic : null),
|
||||
),
|
||||
subtitle: subtitle != ""
|
||||
? censored
|
||||
? Wrap(
|
||||
children: [
|
||||
Container(
|
||||
width: 50,
|
||||
height: 10,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.of(context).text,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Text(
|
||||
subtitle,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontStyle:
|
||||
isSubtitleItalic ? FontStyle.italic : null),
|
||||
)
|
||||
: null,
|
||||
trailing: isSubjectView
|
||||
? grade.type != GradeType.ghost
|
||||
? Text(grade.date.format(context),
|
||||
style: const TextStyle(fontWeight: FontWeight.w500))
|
||||
: IconButton(
|
||||
splashRadius: 24.0,
|
||||
icon: Icon(FeatherIcons.trash2,
|
||||
color: AppColors.of(context).red),
|
||||
onPressed: () {
|
||||
calculatorProvider.removeGrade(grade);
|
||||
},
|
||||
)
|
||||
: censored
|
||||
? Container(
|
||||
width: 15,
|
||||
height: 15,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.of(context).text,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
)
|
||||
// : GradeValueWidget(grade.value),
|
||||
: Icon(
|
||||
SubjectIcon.resolveVariant(
|
||||
context: context, subject: grade.subject),
|
||||
color: AppColors.of(context).text.withOpacity(.5),
|
||||
),
|
||||
minLeadingWidth: isSubjectView ? 32.0 : 0,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GradeValueWidget extends StatelessWidget {
|
||||
const GradeValueWidget(
|
||||
this.value, {
|
||||
super.key,
|
||||
this.size = 38.0,
|
||||
this.fill = false,
|
||||
this.contrast = false,
|
||||
this.shadow = false,
|
||||
this.outline = false,
|
||||
this.complemented = false,
|
||||
this.nocolor = false,
|
||||
this.color,
|
||||
});
|
||||
|
||||
final GradeValue value;
|
||||
final double size;
|
||||
final bool fill;
|
||||
final bool contrast;
|
||||
final bool shadow;
|
||||
final bool outline;
|
||||
final bool complemented;
|
||||
final bool nocolor;
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
GradeValue value = this.value;
|
||||
bool isSubjectView = SubjectGradesContainer.of(context) != null;
|
||||
|
||||
Color color = this.color ??
|
||||
gradeColor(context: context, value: value.value, nocolor: nocolor);
|
||||
Widget valueText;
|
||||
final percentage = value.percentage;
|
||||
|
||||
if (percentage) {
|
||||
double multiplier = 1.0;
|
||||
|
||||
if (isSubjectView) multiplier = 0.75;
|
||||
|
||||
valueText = Text.rich(
|
||||
TextSpan(
|
||||
text: value.value.toString(),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: "\n%",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: size / 2.5 * multiplier,
|
||||
height: 0.7),
|
||||
),
|
||||
],
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: size / (isSubjectView ? 1 : 1.5) * multiplier,
|
||||
height: 1),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
);
|
||||
} else if (value.valueName.toLowerCase().specialChars() == 'nem irt') {
|
||||
valueText = const Icon(FeatherIcons.slash);
|
||||
} else {
|
||||
valueText = Stack(alignment: Alignment.topRight, children: [
|
||||
Transform.translate(
|
||||
offset: (value.weight >= 200) ? const Offset(1.0, 0.2) : Offset.zero,
|
||||
child: Text(
|
||||
value.value.toString(),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontWeight:
|
||||
value.weight == 50 ? FontWeight.w500 : FontWeight.bold,
|
||||
fontSize: size,
|
||||
color: contrast ? Colors.white : color,
|
||||
shadows: [
|
||||
if (value.weight >= 200)
|
||||
Shadow(
|
||||
color: (contrast ? Colors.white : color).withOpacity(.4),
|
||||
offset: const Offset(-4, -3),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (complemented)
|
||||
Transform.translate(
|
||||
offset: const Offset(9, 1),
|
||||
child: Text(
|
||||
"*",
|
||||
style:
|
||||
TextStyle(fontSize: size / 1.6, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
return fill
|
||||
? Container(
|
||||
width: size * 1.4,
|
||||
height: size * 1.4,
|
||||
decoration: BoxDecoration(
|
||||
color: color.withOpacity(contrast ? 1.0 : .25),
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [
|
||||
if (shadow &&
|
||||
Provider.of<SettingsProvider>(context, listen: false)
|
||||
.shadowEffect)
|
||||
BoxShadow(
|
||||
color: color,
|
||||
blurRadius: 62.0,
|
||||
)
|
||||
],
|
||||
),
|
||||
child: Center(child: valueText),
|
||||
)
|
||||
: valueText;
|
||||
}
|
||||
}
|
||||
|
||||
Color gradeColor(
|
||||
{required BuildContext context, required num value, bool nocolor = false}) {
|
||||
int valueInt = 0;
|
||||
|
||||
var settings = Provider.of<SettingsProvider>(context, listen: false);
|
||||
|
||||
try {
|
||||
if (value < 2.0) {
|
||||
valueInt = 1;
|
||||
} else {
|
||||
if (value >= value.floor() + settings.rounding / 10) {
|
||||
valueInt = value.ceil();
|
||||
} else {
|
||||
valueInt = value.floor();
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
if (nocolor) return AppColors.of(context).text;
|
||||
|
||||
switch (valueInt) {
|
||||
case 5:
|
||||
return settings.gradeColors[4];
|
||||
case 4:
|
||||
return settings.gradeColors[3];
|
||||
case 3:
|
||||
return settings.gradeColors[2];
|
||||
case 2:
|
||||
return settings.gradeColors[1];
|
||||
case 1:
|
||||
return settings.gradeColors[0];
|
||||
default:
|
||||
return AppColors.of(context).text;
|
||||
}
|
||||
}
|
||||
451
refilc/lib/ui/widgets/lesson/lesson_tile.dart
Normal file
451
refilc/lib/ui/widgets/lesson/lesson_tile.dart
Normal file
@@ -0,0 +1,451 @@
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc_kreta_api/providers/exam_provider.dart';
|
||||
import 'package:refilc_kreta_api/providers/homework_provider.dart';
|
||||
import 'package:refilc/theme/colors/colors.dart';
|
||||
import 'package:refilc_kreta_api/models/exam.dart';
|
||||
import 'package:refilc_kreta_api/models/homework.dart';
|
||||
import 'package:refilc_kreta_api/models/lesson.dart';
|
||||
import 'package:refilc/utils/format.dart';
|
||||
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
||||
import 'package:refilc_mobile_ui/common/round_border_icon.dart';
|
||||
import 'package:refilc_mobile_ui/common/widgets/exam/exam_view.dart';
|
||||
import 'package:refilc_mobile_ui/common/widgets/homework/homework_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'lesson_tile.i18n.dart';
|
||||
|
||||
class LessonTile extends StatelessWidget {
|
||||
const LessonTile(this.lesson, {super.key, this.onTap, this.swapDesc = false});
|
||||
|
||||
final Lesson lesson;
|
||||
final bool swapDesc;
|
||||
final void Function()? onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> subtiles = [];
|
||||
|
||||
Color accent = Theme.of(context).colorScheme.secondary;
|
||||
bool fill = false;
|
||||
bool fillLeading = false;
|
||||
String lessonIndexTrailing = "";
|
||||
|
||||
SettingsProvider settingsProvider = Provider.of<SettingsProvider>(context);
|
||||
|
||||
// Only put a trailing . if its a digit
|
||||
if (RegExp(r'\d').hasMatch(lesson.lessonIndex)) lessonIndexTrailing = ".";
|
||||
|
||||
var now = DateTime.now();
|
||||
if (lesson.start.isBefore(now) &&
|
||||
lesson.end.isAfter(now) &&
|
||||
lesson.status?.name != "Elmaradt") {
|
||||
fillLeading = true;
|
||||
}
|
||||
|
||||
if (lesson.substituteTeacher != null &&
|
||||
lesson.substituteTeacher?.name != "") {
|
||||
fill = true;
|
||||
accent = AppColors.of(context).yellow;
|
||||
}
|
||||
|
||||
if (lesson.status?.name == "Elmaradt") {
|
||||
fill = true;
|
||||
accent = AppColors.of(context).red;
|
||||
}
|
||||
|
||||
if (lesson.isEmpty) {
|
||||
accent = AppColors.of(context).text.withOpacity(0.6);
|
||||
}
|
||||
|
||||
if (!lesson.studentPresence) {
|
||||
subtiles.add(LessonSubtile(
|
||||
type: LessonSubtileType.absence,
|
||||
title: "absence".i18n,
|
||||
));
|
||||
}
|
||||
|
||||
if (lesson.homeworkId != "") {
|
||||
Homework homework = Provider.of<HomeworkProvider>(context, listen: false)
|
||||
.homework
|
||||
.firstWhere((h) => h.id == lesson.homeworkId,
|
||||
orElse: () => Homework.fromJson({}));
|
||||
|
||||
if (homework.id != "") {
|
||||
subtiles.add(LessonSubtile(
|
||||
type: LessonSubtileType.homework,
|
||||
title: homework.content,
|
||||
onPressed: () => HomeworkView.show(homework, context: context),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (lesson.exam != "") {
|
||||
Exam exam = Provider.of<ExamProvider>(context, listen: false)
|
||||
.exams
|
||||
.firstWhere((t) => t.id == lesson.exam,
|
||||
orElse: () => Exam.fromJson({}));
|
||||
if (exam.id != "") {
|
||||
subtiles.add(LessonSubtile(
|
||||
type: LessonSubtileType.exam,
|
||||
title: exam.description != ""
|
||||
? exam.description
|
||||
: exam.mode?.description ?? "exam".i18n,
|
||||
onPressed: () => ExamView.show(exam, context: context),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// String description = '';
|
||||
// String room = '';
|
||||
|
||||
final cleanDesc = lesson.description
|
||||
.replaceAll(lesson.subject.name.specialChars().toLowerCase(), '');
|
||||
|
||||
// if (!swapDesc) {
|
||||
// if (cleanDesc != "") {
|
||||
// description = lesson.description;
|
||||
// }
|
||||
|
||||
// // Changed lesson Description
|
||||
// if (lesson.isChanged) {
|
||||
// if (lesson.status?.name == "Elmaradt") {
|
||||
// description = 'cancelled'.i18n;
|
||||
// } else if (lesson.substituteTeacher?.name != "") {
|
||||
// description = 'substitution'.i18n;
|
||||
// }
|
||||
// }
|
||||
|
||||
// room = lesson.room.replaceAll("_", " ");
|
||||
// } else {
|
||||
// description = lesson.room.replaceAll("_", " ");
|
||||
// }
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 4.0, top: 7.0),
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
child: Visibility(
|
||||
visible: lesson.subject.id != '' || lesson.isEmpty,
|
||||
replacement: Padding(
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
child: PanelTitle(title: Text(lesson.name)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(bottom: subtiles.isEmpty ? 0.0 : 12.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
minVerticalPadding: cleanDesc == '' ? 12.0 : 0.0,
|
||||
dense: true,
|
||||
onTap: onTap,
|
||||
// onLongPress: kDebugMode ? () => log(jsonEncode(lesson.json)) : null,
|
||||
visualDensity: VisualDensity.compact,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0)),
|
||||
title: Text(
|
||||
!lesson.isEmpty
|
||||
? lesson.subject.renamedTo ??
|
||||
lesson.subject.name.capital()
|
||||
: "empty".i18n,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16.5,
|
||||
color: fill
|
||||
? accent
|
||||
: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(!lesson.isEmpty ? 1.0 : 0.5),
|
||||
fontStyle: lesson.subject.isRenamed &&
|
||||
settingsProvider.renamedSubjectsItalics
|
||||
? FontStyle.italic
|
||||
: null),
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Row(
|
||||
// children: [
|
||||
// Container(
|
||||
// padding: const EdgeInsets.symmetric(
|
||||
// horizontal: 6.0, vertical: 3.5),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Theme.of(context)
|
||||
// .colorScheme
|
||||
// .secondary
|
||||
// .withOpacity(.15),
|
||||
// borderRadius: BorderRadius.circular(10.0),
|
||||
// ),
|
||||
// child: Text(
|
||||
// lesson.room,
|
||||
// style: TextStyle(
|
||||
// height: 1.1,
|
||||
// fontSize: 12.5,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Theme.of(context)
|
||||
// .colorScheme
|
||||
// .secondary
|
||||
// .withOpacity(.9),
|
||||
// ),
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// if (cleanDesc != '')
|
||||
// const SizedBox(
|
||||
// height: 10.0,
|
||||
// ),
|
||||
if (cleanDesc != '')
|
||||
Text(
|
||||
cleanDesc,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: fill ? accent.withOpacity(0.5) : null,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// subtitle: description != ""
|
||||
// ? Text(
|
||||
// description,
|
||||
// style: const TextStyle(
|
||||
// fontWeight: FontWeight.w500,
|
||||
// fontSize: 14.0,
|
||||
// ),
|
||||
// maxLines: 1,
|
||||
// softWrap: false,
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// )
|
||||
// : null,
|
||||
minLeadingWidth: 34.0,
|
||||
leading: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: Center(
|
||||
child: Stack(
|
||||
children: [
|
||||
RoundBorderIcon(
|
||||
color: fill ? accent : AppColors.of(context).text,
|
||||
width: 1.0,
|
||||
icon: SizedBox(
|
||||
width: 25,
|
||||
height: 25,
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 3.0),
|
||||
child: Text(
|
||||
lesson.lessonIndex + lessonIndexTrailing,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 17.5,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: fill ? accent : null,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// lesson.lessonIndex + lessonIndexTrailing,
|
||||
// textAlign: TextAlign.center,
|
||||
// style: TextStyle(
|
||||
// fontSize: 30.0,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: accent,
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// Current lesson indicator
|
||||
Transform.translate(
|
||||
offset: const Offset(-22.0, -1.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: fillLeading
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.secondary
|
||||
.withOpacity(.3)
|
||||
: const Color(0x00000000),
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
boxShadow: [
|
||||
if (fillLeading)
|
||||
BoxShadow(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.secondary
|
||||
.withOpacity(.25),
|
||||
blurRadius: 6.0,
|
||||
)
|
||||
],
|
||||
),
|
||||
margin: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
width: 4.0,
|
||||
height: double.infinity,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing: !lesson.isEmpty
|
||||
? Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// if (!swapDesc)
|
||||
// SizedBox(
|
||||
// width: 52.0,
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.only(right: 6.0),
|
||||
// child: Text(
|
||||
// room,
|
||||
// textAlign: TextAlign.center,
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// maxLines: 2,
|
||||
// style: TextStyle(
|
||||
// fontWeight: FontWeight.w500,
|
||||
// color: AppColors.of(context)
|
||||
// .text
|
||||
// .withOpacity(.75),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 6.0, vertical: 3.5),
|
||||
decoration: BoxDecoration(
|
||||
color: fill
|
||||
? accent.withOpacity(.15)
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.secondary
|
||||
.withOpacity(.15),
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
child: Text(
|
||||
lesson.room,
|
||||
style: TextStyle(
|
||||
height: 1.1,
|
||||
fontSize: 12.5,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: fill
|
||||
? accent.withOpacity(0.9)
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.secondary
|
||||
.withOpacity(.9),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
// xix alignment hack :p
|
||||
const Opacity(opacity: 0, child: Text("EE:EE")),
|
||||
Text(
|
||||
"${DateFormat("H:mm").format(lesson.start)}\n${DateFormat("H:mm").format(lesson.end)}",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: fill
|
||||
? accent.withOpacity(.9)
|
||||
: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(.9),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
),
|
||||
|
||||
// Homework & Exams
|
||||
...subtiles,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum LessonSubtileType { homework, exam, absence }
|
||||
|
||||
class LessonSubtile extends StatelessWidget {
|
||||
const LessonSubtile(
|
||||
{super.key, this.onPressed, required this.title, required this.type});
|
||||
|
||||
final Function()? onPressed;
|
||||
final String title;
|
||||
final LessonSubtileType type;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
IconData icon;
|
||||
Color iconColor = AppColors.of(context).text;
|
||||
|
||||
switch (type) {
|
||||
case LessonSubtileType.absence:
|
||||
icon = FeatherIcons.slash;
|
||||
iconColor = AppColors.of(context).red;
|
||||
break;
|
||||
case LessonSubtileType.exam:
|
||||
icon = FeatherIcons.file;
|
||||
break;
|
||||
case LessonSubtileType.homework:
|
||||
icon = FeatherIcons.home;
|
||||
break;
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: InkWell(
|
||||
onTap: onPressed,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: 30.0,
|
||||
child:
|
||||
Icon(icon, color: iconColor.withOpacity(.75), size: 20.0),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 10.0, top: 2.0),
|
||||
child: Text(
|
||||
title.escapeHtml(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.of(context).text.withOpacity(.65)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
33
refilc/lib/ui/widgets/lesson/lesson_tile.i18n.dart
Normal file
33
refilc/lib/ui/widgets/lesson/lesson_tile.i18n.dart
Normal file
@@ -0,0 +1,33 @@
|
||||
import 'package:i18n_extension/i18n_extension.dart';
|
||||
|
||||
extension Localization on String {
|
||||
static final _t = Translations.byLocale("hu_hu") +
|
||||
{
|
||||
"en_en": {
|
||||
"empty": "Free period",
|
||||
"cancelled": "Cancelled",
|
||||
"substitution": "Substituted",
|
||||
"absence": "You were absent on this lesson",
|
||||
"exam": "Exam"
|
||||
},
|
||||
"hu_hu": {
|
||||
"empty": "Lyukasóra",
|
||||
"cancelled": "Elmarad",
|
||||
"substitution": "Helyettesítés",
|
||||
"absence": "Hiányoztál ezen az órán",
|
||||
"exam": "Dolgozat"
|
||||
},
|
||||
"de_de": {
|
||||
"empty": "Springstunde",
|
||||
"cancelled": "Abgesagte",
|
||||
"substitution": "Vertretene",
|
||||
"absence": "Sie waren in dieser Lektion nicht anwesend",
|
||||
"exam": "Prüfung"
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
130
refilc/lib/ui/widgets/message/message_tile.dart
Normal file
130
refilc/lib/ui/widgets/message/message_tile.dart
Normal file
@@ -0,0 +1,130 @@
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc/theme/colors/colors.dart';
|
||||
import 'package:refilc/utils/format.dart';
|
||||
import 'package:refilc_kreta_api/models/message.dart';
|
||||
import 'package:refilc_mobile_ui/common/profile_image/profile_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class MessageTile extends StatelessWidget {
|
||||
const MessageTile(
|
||||
this.message, {
|
||||
super.key,
|
||||
this.messages,
|
||||
this.padding,
|
||||
this.onTap,
|
||||
this.censored = false,
|
||||
});
|
||||
|
||||
final Message message;
|
||||
final List<Message>? messages;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
final Function()? onTap;
|
||||
final bool censored;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Padding(
|
||||
padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: ListTile(
|
||||
onTap: onTap,
|
||||
visualDensity: VisualDensity.compact,
|
||||
contentPadding: const EdgeInsets.only(left: 8.0, right: 4.0),
|
||||
shape:
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
||||
leading: !Provider.of<SettingsProvider>(context, listen: false)
|
||||
.presentationMode
|
||||
? ProfileImage(
|
||||
name: message.author,
|
||||
radius: 19.2,
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
censored: censored,
|
||||
isNotePfp: true,
|
||||
)
|
||||
: ProfileImage(
|
||||
name: "Béla",
|
||||
radius: 19.2,
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
censored: censored,
|
||||
isNotePfp: true,
|
||||
),
|
||||
title: censored
|
||||
? Wrap(
|
||||
children: [
|
||||
Container(
|
||||
width: 105,
|
||||
height: 15,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.of(context).text.withOpacity(.85),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
!Provider.of<SettingsProvider>(context, listen: false)
|
||||
.presentationMode
|
||||
? message.author
|
||||
: "Béla",
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600, fontSize: 15.5),
|
||||
),
|
||||
),
|
||||
if (message.attachments.isNotEmpty)
|
||||
const Icon(FeatherIcons.paperclip, size: 16.0)
|
||||
],
|
||||
),
|
||||
subtitle: censored
|
||||
? Wrap(
|
||||
children: [
|
||||
Container(
|
||||
width: 150,
|
||||
height: 10,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.of(context).text.withOpacity(.45),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Text(
|
||||
message.subject,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500, fontSize: 14.0),
|
||||
),
|
||||
trailing: censored
|
||||
? Wrap(
|
||||
children: [
|
||||
Container(
|
||||
width: 35,
|
||||
height: 15,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.of(context).text.withOpacity(.45),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Text(
|
||||
message.date.format(context),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14.0,
|
||||
color: AppColors.of(context).text.withOpacity(.75),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user