diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 08dfbc7..5281a01 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,12 @@ on: push: pull_request: schedule: - - cron: "0 8 * * *" + - cron: "0 4 * * *" + +env: + JAVA_VERSION: 12.x + FLUTTER_CHANNEL: stable + FLUTTER_VERSION: 1.17.x jobs: install: @@ -17,11 +22,12 @@ jobs: - name: Install Java uses: actions/setup-java@v1 with: - java-version: "12.x" - - name: Install Flutter (beta) + java-version: ${{ env.JAVA_VERSION }} + - name: Install Flutter (stable) uses: subosito/flutter-action@v1 with: - flutter-version: 1.12.13+hotfix.9 + channel: ${{ env.FLUTTER_CHANNEL }} + version: ${{ env.FLUTTER_VERSION }} - name: Install dependencies run: flutter pub get @@ -62,11 +68,12 @@ jobs: - name: Install Java uses: actions/setup-java@v1 with: - java-version: "12.x" + java-version: ${{ env.JAVA_VERSION }} - name: Install Flutter (stable) uses: subosito/flutter-action@v1 with: - flutter-version: 1.12.13+hotfix.9 + channel: ${{ env.FLUTTER_CHANNEL }} + version: ${{ env.FLUTTER_VERSION }} - name: Checkout source uses: actions/download-artifact@v1 @@ -74,6 +81,9 @@ jobs: name: source path: . + - name: Install dependencies + run: flutter pub get + - name: Run linter run: flutter analyze > flutter_analyze_report.txt continue-on-error: true @@ -105,11 +115,12 @@ jobs: - name: Install Java uses: actions/setup-java@v1 with: - java-version: "12.x" + java-version: ${{ env.JAVA_VERSION }} - name: Install Flutter (stable) uses: subosito/flutter-action@v1 with: - flutter-version: 1.12.13+hotfix.9 + channel: ${{ env.FLUTTER_CHANNEL }} + version: ${{ env.FLUTTER_VERSION }} - name: Checkout source uses: actions/download-artifact@v1 @@ -117,10 +128,13 @@ jobs: name: source path: . + - name: Install dependencies + run: flutter pub get + - run: flutter build apk --release - name: Upload APK as artifact - uses: actions/upload-artifact@v2-preview + uses: actions/upload-artifact@v2 with: name: apk path: build/app/outputs/apk/release/app-release.apk diff --git a/lib/app/routing.dart b/lib/app/routing.dart index e4c1d84..16a4984 100644 --- a/lib/app/routing.dart +++ b/lib/app/routing.dart @@ -1,5 +1,4 @@ import 'package:flutter_deep_linking/flutter_deep_linking.dart'; -import 'package:hpi_flutter/course/course.dart'; import 'package:hpi_flutter/food/food.dart'; import 'package:hpi_flutter/myhpi/myhpi.dart'; import 'package:hpi_flutter/news/news.dart'; @@ -28,7 +27,6 @@ final router = Router( Route( matcher: Matcher.webHost(mdHost, isOptional: true), routes: [ - courseRoutes, Route( matcher: Matcher.path('dashboard'), materialBuilder: (_, __) => DashboardPage(), diff --git a/lib/app/widgets/app_bar.dart b/lib/app/widgets/app_bar.dart index 998c238..7b92792 100644 --- a/lib/app/widgets/app_bar.dart +++ b/lib/app/widgets/app_bar.dart @@ -272,8 +272,11 @@ class _HpiFlexibleSpaceBarState extends State { switch (theme.platform) { case TargetPlatform.android: case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: return false; case TargetPlatform.iOS: + case TargetPlatform.macOS: return true; } // ignore: avoid_returning_null @@ -284,7 +287,7 @@ class _HpiFlexibleSpaceBarState extends State { if (effectiveCenterTitle) { return Alignment.bottomCenter; } - final TextDirection textDirection = context.directionality; + final textDirection = context.directionality; assert(textDirection != null); switch (textDirection) { case TextDirection.rtl: @@ -302,7 +305,7 @@ class _HpiFlexibleSpaceBarState extends State { case CollapseMode.none: return 0; case CollapseMode.parallax: - final double deltaExtent = settings.maxExtent - settings.minExtent; + final deltaExtent = settings.maxExtent - settings.minExtent; return -Tween(begin: 0, end: deltaExtent / 4.0).transform(t); } // ignore: avoid_returning_null @@ -311,14 +314,14 @@ class _HpiFlexibleSpaceBarState extends State { @override Widget build(BuildContext context) { - final FlexibleSpaceBarSettings settings = + final settings = context.dependOnInheritedWidgetOfExactType(); assert(settings != null, 'A HpiFlexibleSpaceBar must be wrapped in the widget returned by HpiFlexibleSpaceBar.createSettings().'); - final List children = []; + final children = []; - final double deltaExtent = settings.maxExtent - settings.minExtent; + final deltaExtent = settings.maxExtent - settings.minExtent; // 0.0 -> Expanded // 1.0 -> Collapsed to toolbar @@ -329,10 +332,10 @@ class _HpiFlexibleSpaceBarState extends State { // background image if (widget.background != null) { - final double fadeStart = math.max(0, 1.0 - kToolbarHeight / deltaExtent); - const double fadeEnd = 1; + final fadeStart = math.max(0, 1.0 - kToolbarHeight / deltaExtent); + const fadeEnd = 1.0; assert(fadeStart <= fadeEnd); - final double opacity = 1.0 - Interval(fadeStart, fadeEnd).transform(t); + final opacity = 1.0 - Interval(fadeStart, fadeEnd).transform(t); if (opacity > 0.0) { children.add(Positioned( top: _getCollapsePadding(t, settings), @@ -348,28 +351,31 @@ class _HpiFlexibleSpaceBarState extends State { } if (widget.title != null) { - final ThemeData theme = context.theme; + final theme = context.theme; Widget title; switch (theme.platform) { case TargetPlatform.iOS: + case TargetPlatform.macOS: title = widget.title; break; - case TargetPlatform.fuchsia: case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: title = Semantics( namesRoute: true, child: widget.title, ); } - final double opacity = settings.toolbarOpacity; + final opacity = settings.toolbarOpacity; if (opacity > 0.0) { - TextStyle titleStyle = theme.primaryTextTheme.title; + var titleStyle = theme.primaryTextTheme.headline6; titleStyle = titleStyle.copyWith(color: titleStyle.color.withOpacity(opacity)); - final bool effectiveCenterTitle = _getEffectiveCenterTitle(theme); - final EdgeInsetsGeometry padding = widget.titlePadding ?? + final effectiveCenterTitle = _getEffectiveCenterTitle(theme); + final padding = widget.titlePadding ?? EdgeInsetsDirectional.only( start: effectiveCenterTitle ? 0.0 @@ -377,12 +383,10 @@ class _HpiFlexibleSpaceBarState extends State { end: 32, bottom: Tween(begin: 16, end: 0).transform(t), ); - final double scaleValue = - Tween(begin: 1.5, end: 1).transform(t); - final Matrix4 scaleTransform = Matrix4.identity() + final scaleValue = Tween(begin: 1.5, end: 1).transform(t); + final scaleTransform = Matrix4.identity() ..scale(scaleValue, scaleValue, 1); - final Alignment titleAlignment = - _getTitleAlignment(t, effectiveCenterTitle); + final titleAlignment = _getTitleAlignment(t, effectiveCenterTitle); children.add( SafeArea( child: Container( diff --git a/lib/app/widgets/dashboard_page.dart b/lib/app/widgets/dashboard_page.dart index fdb67b7..ce964c8 100644 --- a/lib/app/widgets/dashboard_page.dart +++ b/lib/app/widgets/dashboard_page.dart @@ -73,7 +73,7 @@ class DashboardFragment extends StatelessWidget { child: Padding( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: DefaultTextStyle( - style: context.textTheme.title, + style: context.textTheme.headline6, child: title, ), ), diff --git a/lib/app/widgets/theme.dart b/lib/app/widgets/theme.dart index 7cb626a..cdf7dce 100644 --- a/lib/app/widgets/theme.dart +++ b/lib/app/widgets/theme.dart @@ -39,7 +39,7 @@ const _brandColorYellow = 0xFFF6A804; ThemeData buildTheme(Brightness brightness) { final isDark = brightness == Brightness.dark; - ThemeData theme = ThemeData( + var theme = ThemeData( brightness: brightness, applyElevationOverlayColor: isDark, primarySwatch: _brandColorRedSwatch, @@ -54,16 +54,17 @@ ThemeData buildTheme(Brightness brightness) { ); theme = theme.copyWith( textTheme: theme.textTheme.copyWith( - overline: theme.textTheme.overline.copyWith( - color: isDark ? Colors.white60 : Colors.black.withOpacity(0.6), - fontWeight: FontWeight.w500, - fontSize: 10, - letterSpacing: 1.5, - height: 1.6, - ), - headline: theme.textTheme.headline.copyWith( - fontFamily: 'Neo Sans', - )), + headline5: theme.textTheme.headline5.copyWith( + fontFamily: 'Neo Sans', + ), + overline: theme.textTheme.overline.copyWith( + color: isDark ? Colors.white60 : Colors.black.withOpacity(0.6), + fontWeight: FontWeight.w500, + fontSize: 10, + letterSpacing: 1.5, + height: 1.6, + ), + ), ); var localizedTheme = ThemeData.localize( theme, diff --git a/lib/app/widgets/utils.dart b/lib/app/widgets/utils.dart index c08ef53..55edefd 100644 --- a/lib/app/widgets/utils.dart +++ b/lib/app/widgets/utils.dart @@ -19,7 +19,7 @@ Widget buildAppBarTitle({ crossAxisAlignment: CrossAxisAlignment.start, children: [ DefaultTextStyle( - style: context.textTheme.title.copyWith( + style: context.textTheme.headline6.copyWith( color: Colors.black87, ), maxLines: 1, @@ -27,7 +27,7 @@ Widget buildAppBarTitle({ child: title, ), DefaultTextStyle( - style: context.textTheme.subhead, + style: context.textTheme.subtitle1, maxLines: 1, overflow: TextOverflow.ellipsis, child: subtitle, diff --git a/lib/core/widgets/preview_box.dart b/lib/core/widgets/preview_box.dart index b38d24a..ac1d2b7 100644 --- a/lib/core/widgets/preview_box.dart +++ b/lib/core/widgets/preview_box.dart @@ -53,7 +53,7 @@ class PreviewBox extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ DefaultTextStyle( - style: context.textTheme.body1.copyWith(color: Colors.white), + style: context.textTheme.bodyText2.copyWith(color: Colors.white), maxLines: 3, overflow: TextOverflow.ellipsis, child: title, diff --git a/lib/course/bloc.dart b/lib/course/bloc.dart deleted file mode 100644 index 76351b9..0000000 --- a/lib/course/bloc.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:grpc/grpc.dart'; -import 'package:hpi_flutter/app/app.dart'; -import 'package:hpi_flutter/core/core.dart'; -import 'package:hpi_flutter/hpi_cloud_apis/hpi/cloud/course/v1test/course_service.pbgrpc.dart'; - -import 'data.dart'; - -@immutable -class CourseBloc { - CourseBloc() - : _client = CourseServiceClient( - ClientChannel( - services.get().toString(), - port: 50062, - options: ChannelOptions( - credentials: ChannelCredentials.insecure(), - ), - ), - options: createCallOptions(), - ); - - final CourseServiceClient _client; - - Stream> getAllCourseSeries({ - int pageSize, - String pageToken, - }) { - final request = ListCourseSeriesRequest() - ..pageSize = pageSize ?? 0 - ..pageToken = pageToken ?? ''; - return Stream.fromFuture(_client.listCourseSeries(request)) - .map((r) => PaginationResponse( - r.courseSeries.map((a) => CourseSeries.fromProto(a)).toList(), - r.nextPageToken, - )); - } - - Stream getCourseSeries(String id) { - assert(id != null); - return Stream.fromFuture( - _client.getCourseSeries(GetCourseSeriesRequest()..id = id)) - .map((c) => CourseSeries.fromProto(c)); - } - - Stream getSemester(String id) { - assert(id != null); - return Stream.fromFuture(_client.getSemester(GetSemesterRequest()..id = id)) - .map((c) => Semester.fromProto(c)); - } - - Stream> getCourses({ - int pageSize, - String pageToken, - }) { - final request = ListCoursesRequest() - ..pageSize = pageSize ?? 0 - ..pageToken = pageToken ?? ''; - return Stream.fromFuture(_client.listCourses(request)) - .map((r) => PaginationResponse( - r.courses.map((a) => Course.fromProto(a)).toList(), - r.nextPageToken, - )); - } - - Stream getCourse(String id) { - assert(id != null); - return Stream.fromFuture(_client.getCourse(GetCourseRequest()..id = id)) - .map((c) => Course.fromProto(c)); - } - - Stream getCourseDetail(String courseId) { - assert(courseId != null); - return Stream.fromFuture(_client - .getCourseDetail(GetCourseDetailRequest()..courseId = courseId)) - .map((c) => CourseDetail.fromProto(c)); - } -} diff --git a/lib/course/course.dart b/lib/course/course.dart deleted file mode 100644 index 3de7569..0000000 --- a/lib/course/course.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'bloc.dart'; -export 'routes.dart'; diff --git a/lib/course/data.dart b/lib/course/data.dart deleted file mode 100644 index 9b89f3f..0000000 --- a/lib/course/data.dart +++ /dev/null @@ -1,675 +0,0 @@ -import 'package:hpi_flutter/hpi_cloud_apis/google/protobuf/wrappers.pb.dart' - as proto; -import 'package:hpi_flutter/hpi_cloud_apis/google/type/date.pb.dart' as proto; -import 'package:hpi_flutter/hpi_cloud_apis/hpi/cloud/course/v1test/course.pb.dart' - as proto; -import 'package:immutable_proto/immutable_proto.dart'; -import 'package:meta/meta.dart'; - -@immutable -class UInt32Value { - const UInt32Value({this.value}); - - UInt32Value.fromProto(proto.UInt32Value uInt32Value) - : this(value: uInt32Value.hasValue() ? uInt32Value.value : null); - - final int value; - - proto.UInt32Value toProto() { - final uInt32Value = proto.UInt32Value(); - if (value != null) { - uInt32Value.value = value; - } - return uInt32Value; - } - - @override - bool operator ==(Object other) { - return other is UInt32Value && value == other.value; - } - - @override - int get hashCode => hashList([value]); - - UInt32Value copy({ - int value, - }) => - UInt32Value( - value: value ?? this.value, - ); - - @override - String toString() { - return 'UInt32Value(value: $value)'; - } -} - -@immutable -class Date { - const Date({ - @required this.year, - @required this.month, - @required this.day, - }); - - Date.fromProto(proto.Date date) - : this( - year: date.hasYear() ? date.year : null, - month: date.hasMonth() ? date.month : null, - day: date.hasDay() ? date.day : null, - ); - - final int year; - final int month; - final int day; - - proto.Date toProto() { - final date = proto.Date(); - if (year != null) { - date.year = year; - } - if (month != null) { - date.month = month; - } - if (day != null) { - date.day = day; - } - return date; - } - - @override - bool operator ==(Object other) { - return other is Date && - year == other.year && - month == other.month && - day == other.day; - } - - @override - int get hashCode => hashList([ - year, - month, - day, - ]); - Date copy({ - int year, - int month, - int day, - }) => - Date( - year: year ?? this.year, - month: month ?? this.month, - day: day ?? this.day, - ); - - @override - String toString() { - return 'Date(year: $year, month: $month, day: $day)'; - } -} - -enum CourseSeriesCompulsory { compulsory, bridge, nonCompulsory } - -enum CourseSeriesType { seminar, blockSeminar, exercise, project, lecture } - -@immutable -class CourseSeries { - const CourseSeries({ - this.id, - this.title, - this.shortTitle, - this.abbreviation, - this.ects, - this.hoursPerWeek, - @required this.compulsory, - this.language, - @required this.types, - }) : assert(compulsory != null), - assert(types != null); - - CourseSeries.fromProto(proto.CourseSeries courseSeries) - : this( - id: courseSeries.hasId() ? courseSeries.id : null, - title: courseSeries.hasTitle() ? courseSeries.title : null, - shortTitle: - courseSeries.hasShortTitle() ? courseSeries.shortTitle : null, - abbreviation: - courseSeries.hasAbbreviation() ? courseSeries.abbreviation : null, - ects: courseSeries.hasEcts() ? courseSeries.ects : null, - hoursPerWeek: - courseSeries.hasHoursPerWeek() ? courseSeries.hoursPerWeek : null, - compulsory: courseSeriesCompulsoryFromProto(courseSeries.compulsory), - language: courseSeries.hasLanguage() ? courseSeries.language : null, - types: courseSeries.types.map(courseSeriesTypeFromProto).toList(), - ); - - final String id; - final String title; - final String shortTitle; - final String abbreviation; - final int ects; - final int hoursPerWeek; - @required - final CourseSeriesCompulsory compulsory; - final String language; - @required - final List types; - - proto.CourseSeries toProto() { - final courseSeries = proto.CourseSeries(); - if (id != null) { - courseSeries.id = id; - } - if (title != null) { - courseSeries.title = title; - } - if (shortTitle != null) { - courseSeries.shortTitle = shortTitle; - } - if (abbreviation != null) { - courseSeries.abbreviation = abbreviation; - } - if (ects != null) { - courseSeries.ects = ects; - } - if (hoursPerWeek != null) { - courseSeries.hoursPerWeek = hoursPerWeek; - } - courseSeries.compulsory = courseSeriesCompulsoryToProto(compulsory); - if (language != null) { - courseSeries.language = language; - } - courseSeries.types.addAll(types.map(courseSeriesTypeToProto)); - return courseSeries; - } - - @override - bool operator ==(Object other) { - return other is CourseSeries && - id == other.id && - title == other.title && - shortTitle == other.shortTitle && - abbreviation == other.abbreviation && - ects == other.ects && - hoursPerWeek == other.hoursPerWeek && - compulsory == other.compulsory && - language == other.language && - types == other.types; - } - - @override - int get hashCode => hashList([ - id, - title, - shortTitle, - abbreviation, - ects, - hoursPerWeek, - compulsory, - language, - types, - ]); - CourseSeries copy({ - String id, - String title, - String shortTitle, - String abbreviation, - int ects, - int hoursPerWeek, - CourseSeriesCompulsory compulsory, - String language, - List types, - }) => - CourseSeries( - id: id ?? this.id, - title: title ?? this.title, - shortTitle: shortTitle ?? this.shortTitle, - abbreviation: abbreviation ?? this.abbreviation, - ects: ects ?? this.ects, - hoursPerWeek: hoursPerWeek ?? this.hoursPerWeek, - compulsory: compulsory ?? this.compulsory, - language: language ?? this.language, - types: types ?? this.types, - ); - - @override - String toString() { - return 'CourseSeries(id: $id, title: $title, shortTitle: $shortTitle, abbreviation: $abbreviation, ects: $ects, hoursPerWeek: $hoursPerWeek, compulsory: $compulsory, language: $language, types: $types)'; - } - - static CourseSeriesCompulsory courseSeriesCompulsoryFromProto( - proto.CourseSeries_Compulsory courseSeriesCompulsory) { - switch (courseSeriesCompulsory) { - case proto.CourseSeries_Compulsory.COMPULSORY: - return CourseSeriesCompulsory.compulsory; - case proto.CourseSeries_Compulsory.BRIDGE: - return CourseSeriesCompulsory.bridge; - case proto.CourseSeries_Compulsory.NON_COMPULSORY: - default: - return CourseSeriesCompulsory.nonCompulsory; - } - } - - static proto.CourseSeries_Compulsory courseSeriesCompulsoryToProto( - CourseSeriesCompulsory courseSeriesCompulsory) { - switch (courseSeriesCompulsory) { - case CourseSeriesCompulsory.compulsory: - return proto.CourseSeries_Compulsory.COMPULSORY; - case CourseSeriesCompulsory.bridge: - return proto.CourseSeries_Compulsory.BRIDGE; - case CourseSeriesCompulsory.nonCompulsory: - default: - return proto.CourseSeries_Compulsory.NON_COMPULSORY; - } - } - - static CourseSeriesType courseSeriesTypeFromProto( - proto.CourseSeries_Type courseSeriesType) { - switch (courseSeriesType) { - case proto.CourseSeries_Type.SEMINAR: - return CourseSeriesType.seminar; - case proto.CourseSeries_Type.BLOCK_SEMINAR: - return CourseSeriesType.blockSeminar; - case proto.CourseSeries_Type.EXERCISE: - return CourseSeriesType.exercise; - case proto.CourseSeries_Type.PROJECT: - return CourseSeriesType.project; - case proto.CourseSeries_Type.LECTURE: - default: - return CourseSeriesType.lecture; - } - } - - static proto.CourseSeries_Type courseSeriesTypeToProto( - CourseSeriesType courseSeriesType) { - switch (courseSeriesType) { - case CourseSeriesType.seminar: - return proto.CourseSeries_Type.SEMINAR; - case CourseSeriesType.blockSeminar: - return proto.CourseSeries_Type.BLOCK_SEMINAR; - case CourseSeriesType.exercise: - return proto.CourseSeries_Type.EXERCISE; - case CourseSeriesType.project: - return proto.CourseSeries_Type.PROJECT; - case CourseSeriesType.lecture: - default: - return proto.CourseSeries_Type.LECTURE; - } - } -} - -@immutable -class Semester { - const Semester({ - this.id, - @required this.term, - this.year, - }) : assert(term != null); - - Semester.fromProto(proto.Semester semester) - : this( - id: semester.hasId() ? semester.id : null, - term: semesterTermFromProto(semester.term), - year: semester.hasYear() ? semester.year : null, - ); - - final String id; - @required - final SemesterTerm term; - final int year; - - proto.Semester toProto() { - final semester = proto.Semester(); - if (id != null) { - semester.id = id; - } - semester.term = semesterTermToProto(term); - if (year != null) { - semester.year = year; - } - return semester; - } - - @override - bool operator ==(Object other) { - return other is Semester && - id == other.id && - term == other.term && - year == other.year; - } - - @override - int get hashCode => hashList([ - id, - term, - year, - ]); - Semester copy({ - String id, - SemesterTerm term, - int year, - }) => - Semester( - id: id ?? this.id, - term: term ?? this.term, - year: year ?? this.year, - ); - - @override - String toString() => 'Semester(id: $id, term: $term, year: $year)'; - - static SemesterTerm semesterTermFromProto(proto.Semester_Term semesterTerm) { - switch (semesterTerm) { - case proto.Semester_Term.SUMMER: - return SemesterTerm.summer; - case proto.Semester_Term.WINTER: - default: - return SemesterTerm.winter; - } - } - - static proto.Semester_Term semesterTermToProto(SemesterTerm semesterTerm) { - switch (semesterTerm) { - case SemesterTerm.summer: - return proto.Semester_Term.SUMMER; - case SemesterTerm.winter: - default: - return proto.Semester_Term.WINTER; - } - } -} - -enum SemesterTerm { winter, summer } - -@immutable -class Course { - const Course({ - this.id, - this.courseSeriesId, - this.semesterId, - @required this.lecturers, - @required this.assistants, - this.website, - this.attendance, - this.enrollmentDeadline, - }) : assert(lecturers != null), - assert(assistants != null); - - Course.fromProto(proto.Course course) - : this( - id: course.hasId() ? course.id : null, - courseSeriesId: - course.hasCourseSeriesId() ? course.courseSeriesId : null, - semesterId: course.hasSemesterId() ? course.semesterId : null, - lecturers: course.lecturers, - assistants: course.assistants, - website: course.hasWebsite() ? course.website : null, - attendance: course.hasAttendance() - ? UInt32Value.fromProto(course.attendance) - : null, - enrollmentDeadline: course.hasEnrollmentDeadline() - ? Date.fromProto(course.enrollmentDeadline) - : null, - ); - - final String id; - final String courseSeriesId; - final String semesterId; - @required - final List lecturers; - @required - final List assistants; - final String website; - final UInt32Value attendance; - final Date enrollmentDeadline; - - proto.Course toProto() { - final course = proto.Course(); - if (id != null) { - course.id = id; - } - if (courseSeriesId != null) { - course.courseSeriesId = courseSeriesId; - } - if (semesterId != null) { - course.semesterId = semesterId; - } - course.lecturers.addAll(lecturers); - course.assistants.addAll(assistants); - if (website != null) { - course.website = website; - } - if (attendance != null) { - course.attendance = attendance.toProto(); - } - if (enrollmentDeadline != null) { - course.enrollmentDeadline = enrollmentDeadline.toProto(); - } - return course; - } - - @override - bool operator ==(Object other) { - return other is Course && - id == other.id && - courseSeriesId == other.courseSeriesId && - semesterId == other.semesterId && - lecturers == other.lecturers && - assistants == other.assistants && - website == other.website && - attendance == other.attendance && - enrollmentDeadline == other.enrollmentDeadline; - } - - @override - int get hashCode => hashList([ - id, - courseSeriesId, - semesterId, - lecturers, - assistants, - website, - attendance, - enrollmentDeadline, - ]); - Course copy({ - String id, - String courseSeriesId, - String semesterId, - List lecturers, - List assistants, - String website, - UInt32Value attendance, - Date enrollmentDeadline, - }) => - Course( - id: id ?? this.id, - courseSeriesId: courseSeriesId ?? this.courseSeriesId, - semesterId: semesterId ?? this.semesterId, - lecturers: lecturers ?? this.lecturers, - assistants: assistants ?? this.assistants, - website: website ?? this.website, - attendance: attendance ?? this.attendance, - enrollmentDeadline: enrollmentDeadline ?? this.enrollmentDeadline, - ); - - @override - String toString() { - return 'Course(id: $id, courseSeriesId: $courseSeriesId, semesterId: $semesterId, lecturers: $lecturers, assistants: $assistants, website: $website, attendance: $attendance, enrollmentDeadline: $enrollmentDeadline)'; - } -} - -@immutable -class CourseDetail { - const CourseDetail({ - this.courseId, - this.teletask, - this.programs, - this.description, - this.requirements, - this.learning, - this.examination, - this.dates, - this.literature, - }); - - CourseDetail.fromProto(proto.CourseDetail courseDetail) - : this( - courseId: courseDetail.hasCourseId() ? courseDetail.courseId : null, - teletask: courseDetail.hasTeletask() ? courseDetail.teletask : null, - programs: { - for (var entry in courseDetail.programs.entries) - entry.key: CourseDetailProgramList.fromProto(entry.value), - }, - description: - courseDetail.hasDescription() ? courseDetail.description : null, - requirements: - courseDetail.hasRequirements() ? courseDetail.requirements : null, - learning: courseDetail.hasLearning() ? courseDetail.learning : null, - examination: - courseDetail.hasExamination() ? courseDetail.examination : null, - dates: courseDetail.hasDates() ? courseDetail.dates : null, - literature: - courseDetail.hasLiterature() ? courseDetail.literature : null, - ); - - final String courseId; - final String teletask; - final Map programs; - final String description; - final String requirements; - final String learning; - final String examination; - final String dates; - final String literature; - - proto.CourseDetail toProto() { - final courseDetail = proto.CourseDetail(); - if (courseId != null) { - courseDetail.courseId = courseId; - } - if (teletask != null) { - courseDetail.teletask = teletask; - } - if (programs != null) { - courseDetail.programs - ..clear() - ..addAll({ - for (var entry in programs.entries) entry.key: entry.value.toProto() - }); - } - if (description != null) { - courseDetail.description = description; - } - if (requirements != null) { - courseDetail.requirements = requirements; - } - if (learning != null) { - courseDetail.learning = learning; - } - if (examination != null) { - courseDetail.examination = examination; - } - if (dates != null) { - courseDetail.dates = dates; - } - if (literature != null) { - courseDetail.literature = literature; - } - return courseDetail; - } - - @override - bool operator ==(Object other) { - return other is CourseDetail && - courseId == other.courseId && - teletask == other.teletask && - programs == other.programs && - description == other.description && - requirements == other.requirements && - learning == other.learning && - examination == other.examination && - dates == other.dates && - literature == other.literature; - } - - @override - int get hashCode => hashList([ - courseId, - teletask, - programs, - description, - requirements, - learning, - examination, - dates, - literature, - ]); - CourseDetail copy({ - String courseId, - String teletask, - Map programs, - String description, - String requirements, - String learning, - String examination, - String dates, - String literature, - }) => - CourseDetail( - courseId: courseId ?? this.courseId, - teletask: teletask ?? this.teletask, - programs: programs ?? this.programs, - description: description ?? this.description, - requirements: requirements ?? this.requirements, - learning: learning ?? this.learning, - examination: examination ?? this.examination, - dates: dates ?? this.dates, - literature: literature ?? this.literature, - ); - - @override - String toString() { - return 'CourseDetail(courseId: $courseId, teletask: $teletask, programs: $programs, description: $description, requirements: $requirements, learning: $learning, examination: $examination, dates: $dates, literature: $literature)'; - } -} - -@immutable -class CourseDetailProgramList { - const CourseDetailProgramList({ - @required this.programs, - }) : assert(programs != null); - - CourseDetailProgramList.fromProto( - proto.CourseDetail_ProgramList courseDetailProgramList) - : this( - programs: List.from(courseDetailProgramList.programs), - ); - proto.CourseDetail_ProgramList toProto() { - final courseDetailProgramList = proto.CourseDetail_ProgramList(); - courseDetailProgramList.programs.addAll(programs); - return courseDetailProgramList; - } - - @required - final List programs; - - @override - bool operator ==(Object other) { - return other is CourseDetailProgramList && programs == other.programs; - } - - @override - int get hashCode => hashList([ - programs, - ]); - CourseDetailProgramList copy({ - List programs, - }) => - CourseDetailProgramList( - programs: programs ?? this.programs, - ); - - @override - String toString() => 'CourseDetailProgramList(programs: $programs)'; -} diff --git a/lib/course/routes.dart b/lib/course/routes.dart deleted file mode 100644 index efa13c3..0000000 --- a/lib/course/routes.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:flutter_deep_linking/flutter_deep_linking.dart'; - -import 'widgets/course_detail_page.dart'; -import 'widgets/course_page.dart'; - -final courseRoutes = Route( - matcher: Matcher.path('courses'), - materialBuilder: (_, __) => CoursePage(), - routes: [ - Route( - matcher: Matcher.path('{courseId}'), - materialBuilder: (_, result) => CourseDetailPage(result['courseId']), - ), - ], -); diff --git a/lib/course/utils.dart b/lib/course/utils.dart deleted file mode 100644 index ba50157..0000000 --- a/lib/course/utils.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:dartx/dartx.dart'; - -import 'data.dart'; - -String buildProgramInfo(CourseDetail courseDetail) { - return courseDetail.programs.entries.map((entry) { - final modulesList = entry.value.programs.joinToString( - separator: '\n', - transform: (p) => '\t\t\t\t$p', - ); - - return '${entry.key}\v$modulesList'; - }).join('\n'); -} diff --git a/lib/course/widgets/course_detail_page.dart b/lib/course/widgets/course_detail_page.dart deleted file mode 100644 index 9b58da5..0000000 --- a/lib/course/widgets/course_detail_page.dart +++ /dev/null @@ -1,240 +0,0 @@ -import 'package:dartx/dartx.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_html/flutter_html.dart'; -import 'package:hpi_flutter/app/app.dart'; -import 'package:hpi_flutter/core/core.dart'; -import 'package:hpi_flutter/feedback/feedback.dart'; -import 'package:kt_dart/kt.dart'; -import 'package:outline_material_icons/outline_material_icons.dart'; -import 'package:rxdart/rxdart.dart'; -import 'package:share/share.dart'; - -import '../bloc.dart'; -import '../data.dart'; -import '../utils.dart'; -import 'elevated_expansion_tile.dart'; - -class CourseDetailPage extends StatelessWidget { - const CourseDetailPage(this.courseId) : assert(courseId != null); - - final String courseId; - - @override - Widget build(BuildContext context) { - final s = context.s; - final bloc = services.get(); - final stream = Observable.combineLatest2, - CourseDetail, KtTriple>( - Observable(bloc.getCourse(courseId)).switchMap( - (c) => bloc - .getCourseSeries(c.courseSeriesId) - .map((cs) => KtPair(c, cs)), - ), - bloc.getCourseDetail(courseId), - (ccs, detail) => KtTriple( - ccs.first, ccs.second, detail), - ); - - return StreamBuilder>( - stream: stream, - builder: (context, snapshot) { - if (!snapshot.hasData) { - return buildLoadingErrorScaffold( - context, - snapshot, - appBarElevated: true, - loadingTitle: s.course_course_loading, - ); - } - - final course = snapshot.data.first; - final courseSeries = snapshot.data.second; - final courseDetail = snapshot.data.third; - - return MainScaffold( - body: CustomScrollView( - slivers: [ - HpiSliverAppBar( - floating: true, - backgroundColor: context.theme.cardColor, - title: buildAppBarTitle( - context: context, - title: Text(courseSeries.title), - subtitle: StreamBuilder( - stream: bloc.getSemester(course.semesterId), - builder: (context, snapshot) { - final semester = snapshot.data; - - return Text( - semester != null - ? s.course_semester(semester.term, semester.year) - : course.semesterId, - ); - }, - ), - ), - actions: [ - IconButton( - icon: Icon(OMIcons.share), - onPressed: () => Share.share(course.website), - ), - ], - overflowActions: [ - PopupMenuItem( - value: 'openInBrowser', - child: Text(s.general_openInBrowser), - ), - ], - overflowActionHandler: (value) async { - if (value == 'openInBrowser') { - await tryLaunch(course.website); - } - }, - ), - SliverList( - delegate: SliverChildListDelegate( - _buildCourseDetails( - context, - course: course, - courseSeries: courseSeries, - courseDetail: courseDetail, - ), - ), - ), - ], - ), - ); - }, - ); - } - - List _buildCourseDetails( - BuildContext context, { - @required Course course, - @required CourseSeries courseSeries, - @required CourseDetail courseDetail, - }) { - assert(context != null); - assert(course != null); - assert(courseSeries != null); - assert(courseDetail != null); - - final s = context.s; - return [ - _buildElevatedTile( - context, - leading: OMIcons.info, - title: s.course_course_details( - courseSeries.ects, courseSeries.hoursPerWeek), - subtitle: courseSeries.types - .sortedBy((t) => t.index) - .joinToString(separator: ' · ', transform: s.course_course_type), - ), - if (courseDetail.teletask != null) - _buildElevatedTile( - context, - leading: OMIcons.videocam, - title: s.course_course_teleTask, - trailing: OMIcons.openInNew, - onTap: () async { - await tryLaunch(courseDetail.teletask); - }, - ), - _buildElevatedTile( - context, - leading: OMIcons.personOutline, - title: course.lecturers.joinToString(), - subtitle: course.assistants.joinToString(), - ), - _buildElevatedTile( - context, - leading: OMIcons.language, - title: context.s.general_language(courseSeries.language), - ), - _buildElevatedTile( - context, - leading: OMIcons.viewModule, - title: s.course_course_programsModules, - subtitle: buildProgramInfo(courseDetail), - ), - _buildCourseInfoTile(context, OMIcons.subject, - context.s.course_course_description, courseDetail.description), - _buildCourseInfoTile(context, OMIcons.check, - context.s.course_course_requirements, courseDetail.requirements), - _buildCourseInfoTile(context, OMIcons.school, - context.s.course_course_learning, courseDetail.learning), - _buildCourseInfoTile(context, OMIcons.formatListNumbered, - context.s.course_course_examination, courseDetail.examination), - _buildCourseInfoTile(context, OMIcons.calendarToday, - context.s.course_course_dates, courseDetail.dates), - _buildCourseInfoTile(context, OMIcons.book, - context.s.course_course_literature, courseDetail.literature), - SizedBox(height: 16), - Text( - s.course_course_noGuarantee, - style: context.textTheme.body1 - .copyWith(color: Colors.black.withOpacity(0.6)), - textAlign: TextAlign.center, - ), - Center( - child: FlatButton( - onPressed: () => FeedbackDialog.show( - context, - title: s.course_course_reportError, - feedbackType: 'course.data.error', - ), - child: Text(s.course_course_reportError), - ), - ), - SizedBox(height: 16) - ].where((w) => w != null).toList(); - } - - Widget _buildElevatedTile( - BuildContext context, { - IconData leading, - String title, - String subtitle, - IconData trailing, - VoidCallback onTap, - }) { - assert(context != null); - - return Material( - color: context.theme.cardColor, - child: ListTile( - leading: leading != null ? Icon(leading) : null, - title: title != null ? Text(title) : null, - subtitle: subtitle != null ? Text(subtitle) : null, - trailing: trailing != null ? Icon(trailing) : null, - onTap: onTap, - ), - ); - } - - Widget _buildCourseInfoTile( - BuildContext context, - IconData icon, - String title, - String content, - ) { - assert(context != null); - assert(IconData != null); - assert(title != null); - - if (isNullOrBlank(content)) { - return null; - } - return ElevatedExpansionTile( - leading: Icon(icon), - title: Text(title, style: context.textTheme.subhead), - children: [ - Html( - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - data: content, - onLinkTap: tryLaunch, - ) - ], - ); - } -} diff --git a/lib/course/widgets/course_page.dart b/lib/course/widgets/course_page.dart deleted file mode 100644 index 7f9877c..0000000 --- a/lib/course/widgets/course_page.dart +++ /dev/null @@ -1,134 +0,0 @@ -import 'package:dartx/dartx.dart'; -import 'package:flutter/material.dart' hide Route; -import 'package:hpi_flutter/app/app.dart'; -import 'package:hpi_flutter/core/core.dart'; -import 'package:outline_material_icons/outline_material_icons.dart'; - -import '../bloc.dart'; -import '../data.dart'; - -class CoursePage extends StatelessWidget { - @override - Widget build(BuildContext context) { - final s = context.s; - - return MainScaffold( - body: DefaultTabController( - length: 2, - child: NestedScrollView( - headerSliverBuilder: (context, innerBoxIsScrolled) => [ - SliverOverlapAbsorber( - handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), - child: HpiSliverAppBar( - floating: true, - pinned: true, - forceElevated: innerBoxIsScrolled, - title: Text(s.course), - bottom: TabBar( - indicatorColor: context.theme.primaryColor, - labelColor: context.theme.primaryColor, - unselectedLabelColor: - context.textTheme.body2.color.withOpacity(0.7), - tabs: [ - Tab(text: s.course_tab_current), - Tab(text: s.course_tab_all), - ], - ), - ), - ) - ], - body: TabBarView( - children: { - 'tab:course': CourseList(), - 'tab:courseSeries': CourseSeriesList(), - } - .entries - .mapIndexed((index, tab) => SafeArea( - top: false, - bottom: false, - child: Builder( - builder: (context) => CustomScrollView( - key: PageStorageKey(tab.key), - slivers: [ - SliverOverlapInjector( - handle: NestedScrollView - .sliverOverlapAbsorberHandleFor(context), - ), - tab.value, - ], - ), - ), - )) - .toList(), - ), - ), - ), - ); - } -} - -class CourseList extends StatelessWidget { - @override - Widget build(BuildContext context) { - return PaginatedSliverList( - dataLoader: services.get().getCourses, - itemBuilder: (context, course, __) => Builder( - builder: (context) => StreamBuilder( - stream: - services.get().getCourseSeries(course.courseSeriesId), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return ListTile( - title: Text( - snapshot.error?.toString() ?? context.s.general_loading), - ); - } - - return ListTile( - onTap: () => context.navigator.pushNamed('/courses/${course.id}'), - title: Text(snapshot.data.title), - subtitle: Text( - course.lecturers.joinToString(), - maxLines: 1, - ), - ); - }, - ), - ), - ); - } -} - -class CourseSeriesList extends StatelessWidget { - @override - Widget build(BuildContext context) { - final s = context.s; - - return PaginatedSliverList( - dataLoader: services.get().getAllCourseSeries, - itemBuilder: (context, courseSeries, __) => ExpansionTile( - key: PageStorageKey(courseSeries.id), - title: Text(courseSeries.title), - children: [ - ListTile( - leading: Icon(OMIcons.info), - title: Text( - s.course_course_details( - courseSeries.ects, courseSeries.hoursPerWeek), - ), - subtitle: Text( - courseSeries.types.joinToString( - separator: ' · ', - transform: s.course_course_type, - ), - ), - ), - ListTile( - leading: Icon(OMIcons.language), - title: Text(context.s.general_language(courseSeries.language)), - ), - ], - ), - ); - } -} diff --git a/lib/course/widgets/elevated_expansion_tile.dart b/lib/course/widgets/elevated_expansion_tile.dart deleted file mode 100644 index b17efcc..0000000 --- a/lib/course/widgets/elevated_expansion_tile.dart +++ /dev/null @@ -1,204 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:hpi_flutter/core/core.dart'; -import 'package:outline_material_icons/outline_material_icons.dart'; - -const Duration _kExpand = Duration(milliseconds: 200); - -/// Originally taken from: https://github.com/flutter/flutter/blob/20e59316b8/packages/flutter/lib/src/material/expansion_tile.dart -/// -/// A single-line [ListTile] with a trailing button that expands or collapses -/// the tile to reveal or hide the [children]. -/// -/// This widget is typically used with [ListView] to create an -/// "expand / collapse" list entry. When used with scrolling widgets like -/// [ListView], a unique [PageStorageKey] must be specified to enable the -/// [ElevatedExpansionTile] to save and restore its expanded state when it is scrolled -/// in and out of view. -/// -/// See also: -/// -/// * [ListTile], useful for creating expansion tile [children] when the -/// expansion tile represents a sublist. -/// * The "Expand/collapse" section of -/// . -class ElevatedExpansionTile extends StatefulWidget { - /// Creates a single-line [ListTile] with a trailing button that expands or collapses - /// the tile to reveal or hide the [children]. The [initiallyExpanded] property must - /// be non-null. - const ElevatedExpansionTile({ - Key key, - this.leading, - @required this.title, - this.backgroundColor, - this.onExpansionChanged, - this.children = const [], - this.trailing, - this.initiallyExpanded = false, - }) : assert(initiallyExpanded != null), - super(key: key); - - /// A widget to display before the title. - /// - /// Typically a [CircleAvatar] widget. - final Widget leading; - - /// The primary content of the list item. - /// - /// Typically a [Text] widget. - final Widget title; - - /// Called when the tile expands or collapses. - /// - /// When the tile starts expanding, this function is called with the value - /// true. When the tile starts collapsing, this function is called with - /// the value false. - final ValueChanged onExpansionChanged; - - /// The widgets that are displayed when the tile expands. - /// - /// Typically [ListTile] widgets. - final List children; - - /// The color to display behind the sublist when expanded. - final Color backgroundColor; - - /// A widget to display instead of a rotating arrow icon. - final Widget trailing; - - /// Specifies if the list tile is initially expanded (true) or collapsed (false, the default). - final bool initiallyExpanded; - - @override - _ElevatedExpansionTileState createState() => _ElevatedExpansionTileState(); -} - -class _ElevatedExpansionTileState extends State - with SingleTickerProviderStateMixin { - static final Animatable _easeInTween = - CurveTween(curve: Curves.easeIn); - static final Animatable _halfTween = - Tween(begin: 0, end: 0.5); - - final ColorTween _borderColorTween = ColorTween(); - final ColorTween _headerColorTween = ColorTween(); - final ColorTween _iconColorTween = ColorTween(); - final ColorTween _backgroundColorTween = ColorTween(); - - AnimationController _controller; - Animation _iconTurns; - Animation _heightFactor; - Animation _headerColor; - Animation _iconColor; - - bool _isExpanded = false; - - @override - void initState() { - super.initState(); - _controller = AnimationController(duration: _kExpand, vsync: this); - _heightFactor = _controller.drive(_easeInTween); - _iconTurns = _controller.drive(_halfTween.chain(_easeInTween)); - _headerColor = _controller.drive(_headerColorTween.chain(_easeInTween)); - _iconColor = _controller.drive(_iconColorTween.chain(_easeInTween)); - - _isExpanded = (context.pageStorage?.readState(context) as bool) ?? - widget.initiallyExpanded; - if (_isExpanded) { - _controller.value = 1; - } - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - void _handleTap() { - setState(() { - _isExpanded = !_isExpanded; - if (_isExpanded) { - _controller.forward(); - } else { - _controller.reverse().then((_) { - if (!mounted) { - return; - } - setState(() { - // Rebuild without widget.children. - }); - }); - } - context.pageStorage?.writeState(context, _isExpanded); - }); - if (widget.onExpansionChanged != null) { - widget.onExpansionChanged(_isExpanded); - } - } - - Widget _buildChildren(BuildContext context, Widget child) { - return Container( - /*decoration: BoxDecoration( - color: _backgroundColor.value ?? Colors.transparent, - border: Border( - top: BorderSide(color: borderSideColor), - bottom: BorderSide(color: borderSideColor), - ), - ),*/ - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ListTileTheme.merge( - iconColor: _iconColor.value, - textColor: _headerColor.value, - child: Material( - elevation: 1, - color: Colors.white, - child: ListTile( - onTap: _handleTap, - leading: widget.leading, - title: widget.title, - trailing: widget.trailing ?? - RotationTransition( - turns: _iconTurns, - child: const Icon(OMIcons.expandMore), - ), - ), - ), - ), - ClipRect( - child: Align( - heightFactor: _heightFactor.value, - child: child, - ), - ), - ], - ), - ); - } - - @override - void didChangeDependencies() { - final ThemeData theme = context.theme; - _borderColorTween.end = theme.dividerColor; - _headerColorTween - ..begin = theme.textTheme.subhead.color - ..end = theme.accentColor; - _iconColorTween - ..begin = theme.unselectedWidgetColor - ..end = theme.accentColor; - _backgroundColorTween.end = widget.backgroundColor; - super.didChangeDependencies(); - } - - @override - Widget build(BuildContext context) { - final bool closed = !_isExpanded && _controller.isDismissed; - return AnimatedBuilder( - animation: _controller.view, - builder: _buildChildren, - child: closed ? null : Column(children: widget.children), - ); - } -} diff --git a/lib/crashreporting/utils.dart b/lib/crashreporting/utils.dart index cab4ba6..54c14e5 100644 --- a/lib/crashreporting/utils.dart +++ b/lib/crashreporting/utils.dart @@ -25,10 +25,9 @@ Future runWithCrashReporting(Future Function() body) async { }; // run in custom zone for catching errors - await runZoned>( + await runZonedGuarded>( body, - // ignore: avoid_types_on_closure_parameters - onError: (error, StackTrace stackTrace) async { + (error, stackTrace) async { await reportError(error, stackTrace); }, ); @@ -36,7 +35,7 @@ Future runWithCrashReporting(Future Function() body) async { bool get isInDebugMode { // Assume you're in production mode. - bool inDebugMode = false; + var inDebugMode = false; // Assert expressions are only evaluated during development. assert(inDebugMode = true); return inDebugMode; diff --git a/lib/feedback/data.dart b/lib/feedback/data.dart index f273871..5fa7b4c 100644 --- a/lib/feedback/data.dart +++ b/lib/feedback/data.dart @@ -56,7 +56,7 @@ class Feedback { } } - Feedback f = Feedback( + return Feedback( id: '', message: message, screenUri: screenUri, @@ -64,8 +64,6 @@ class Feedback { screenshot: screenshot, log: log, ); - - return f; } proto.Feedback toProto() { diff --git a/lib/feedback/widgets/feedback_dialog.dart b/lib/feedback/widgets/feedback_dialog.dart index 047f8c9..ca1112a 100644 --- a/lib/feedback/widgets/feedback_dialog.dart +++ b/lib/feedback/widgets/feedback_dialog.dart @@ -82,7 +82,7 @@ class _FeedbackDialogState extends State return [ Text( widget.title, - style: context.textTheme.display1, + style: context.textTheme.headline4, ), SizedBox(height: 16), TextFormField( @@ -143,7 +143,7 @@ class _FeedbackDialogState extends State setState(() { isSending = true; - Uri screenUri = + final screenUri = Uri.parse(mdWebUrl(services.get().lastKnownRoute)); Feedback.create( message.trim(), diff --git a/lib/food/widgets/menu_item.dart b/lib/food/widgets/menu_item.dart index e841395..62c7aea 100644 --- a/lib/food/widgets/menu_item.dart +++ b/lib/food/widgets/menu_item.dart @@ -40,7 +40,7 @@ class MenuItemView extends StatelessWidget { ), ), Expanded( - child: Text(item.title, style: context.textTheme.body1), + child: Text(item.title, style: context.textTheme.bodyText2), ), SizedBox(width: 8), // Currently, label icons aren't sent by the server. @@ -123,11 +123,11 @@ class MenuItemDetails extends StatelessWidget { children: [ Text( s.food_offer(item.counter), - style: context.textTheme.headline, + style: context.textTheme.headline5, ), Text( item.title, - style: context.textTheme.subhead, + style: context.textTheme.subtitle1, ), ChipGroup( children: [ diff --git a/lib/main.dart b/lib/main.dart index 7b5248c..096d43a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart' hide Route; import 'package:flutter/services.dart'; import 'package:grpc/grpc.dart'; import 'package:hpi_flutter/app/app.dart'; -import 'package:hpi_flutter/course/course.dart'; import 'package:hpi_flutter/crashreporting/crashreporting.dart'; import 'package:hpi_flutter/feedback/feedback.dart'; import 'package:hpi_flutter/food/food.dart'; @@ -86,7 +85,6 @@ void main() async { // Most BLoCs require a reference to the current locale to retrieve // localized information from HPI Cloud. By registering them as factories, // we can adapt to locale changes during runtime. - ..registerFactory(() => CourseBloc()) ..registerFactory(() => CrashReportingBloc()) ..registerFactory(() => FeedbackBloc()) ..registerFactory(() => FoodBloc()) diff --git a/lib/myhpi/widgets/infobit_card.dart b/lib/myhpi/widgets/infobit_card.dart index 357783e..351fddb 100644 --- a/lib/myhpi/widgets/infobit_card.dart +++ b/lib/myhpi/widgets/infobit_card.dart @@ -39,12 +39,12 @@ class InfoBitCard extends StatelessWidget { final title = [ Text( infoBit.title, - style: context.textTheme.headline, + style: context.textTheme.headline5, ), if (infoBit.subtitle != null) Text( infoBit.subtitle, - style: context.textTheme.subhead, + style: context.textTheme.subtitle1, ), ]; @@ -83,7 +83,7 @@ class InfoBitCard extends StatelessWidget { if (infoBit.description != null) Text( infoBit.description, - style: context.textTheme.body1 + style: context.textTheme.bodyText2 .copyWith(color: Colors.black.withOpacity(0.6)), ), ], diff --git a/lib/news/utils.dart b/lib/news/utils.dart index 6df7da2..b1e1333 100644 --- a/lib/news/utils.dart +++ b/lib/news/utils.dart @@ -5,7 +5,7 @@ import 'data.dart'; String formatSourcePublishDate(Article article, Source source) { assert(article != null); - String sourceName = source?.name ?? article.sourceId; + final sourceName = source?.name ?? article.sourceId; return (sourceName.isNotEmpty ? '$sourceName · ' : '') + timeago.format(article.publishDate.toDateTimeLocal()); } diff --git a/lib/news/widgets/article_page.dart b/lib/news/widgets/article_page.dart index 6a7a5be..9c3d1af 100644 --- a/lib/news/widgets/article_page.dart +++ b/lib/news/widgets/article_page.dart @@ -84,7 +84,7 @@ class ArticleView extends StatelessWidget { [ Text( article.title, - style: context.textTheme.headline, + style: context.textTheme.headline5, ), SizedBox(height: 8), _buildCaption(context), diff --git a/lib/news/widgets/article_preview.dart b/lib/news/widgets/article_preview.dart index 39ad469..eaf4841 100644 --- a/lib/news/widgets/article_preview.dart +++ b/lib/news/widgets/article_preview.dart @@ -27,12 +27,12 @@ class ArticlePreview extends StatelessWidget { children: [ Text( article.title, - style: context.textTheme.subhead, + style: context.textTheme.subtitle1, ), SizedBox(height: 8), Text( article.teaser, - style: context.textTheme.body1, + style: context.textTheme.bodyText2, ), SizedBox(height: 4), StreamBuilder( diff --git a/lib/onboarding/widgets/about_myself.dart b/lib/onboarding/widgets/about_myself.dart index 01be3e4..01ca2f2 100644 --- a/lib/onboarding/widgets/about_myself.dart +++ b/lib/onboarding/widgets/about_myself.dart @@ -93,7 +93,7 @@ class _AboutMyselfState extends State { } return DefaultTextStyle( - style: context.textTheme.headline.copyWith( + style: context.textTheme.headline5.copyWith( fontSize: 30, height: 1.4, color: Colors.white, @@ -213,7 +213,7 @@ class _InlineDropdownButton extends StatelessWidget { key: item.key, value: item.value, child: DefaultTextStyle( - style: context.textTheme.body1, + style: context.textTheme.bodyText2, child: item.child, ), ), diff --git a/lib/onboarding/widgets/onboarding_page.dart b/lib/onboarding/widgets/onboarding_page.dart index 3dd24df..8bbad88 100644 --- a/lib/onboarding/widgets/onboarding_page.dart +++ b/lib/onboarding/widgets/onboarding_page.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart' hide Route; +import 'package:flutter/material.dart' hide Page, Route; import 'package:hpi_flutter/app/app.dart'; import 'package:hpi_flutter/core/core.dart' hide Image; import 'package:hpi_flutter/settings/settings.dart'; @@ -64,7 +64,7 @@ class _OnboardingPageState extends State { SizedBox(height: 96), Text( s.onboarding_start_title, - style: context.textTheme.display1.copyWith( + style: context.textTheme.headline4.copyWith( fontSize: 30, color: Colors.white, ), @@ -72,7 +72,7 @@ class _OnboardingPageState extends State { SizedBox(height: 32), Text( s.onboarding_start_subtitle, - style: context.textTheme.subtitle.copyWith(color: Colors.white), + style: context.textTheme.subtitle2.copyWith(color: Colors.white), ), ], ), @@ -93,7 +93,7 @@ class _OnboardingPageState extends State { onPressed: () => PrivacyPolicyPage.showBottomSheet(context), child: Text( s.settings_about_privacyPolicy, - style: context.textTheme.subhead + style: context.textTheme.subtitle1 .copyWith(color: context.hpiTheme.tertiary), ), ), @@ -101,7 +101,7 @@ class _OnboardingPageState extends State { TextSpan(text: s.onboarding_privacyPolicy_suffix), ], ), - style: context.textTheme.subhead.copyWith(color: Colors.white), + style: context.textTheme.subtitle1.copyWith(color: Colors.white), textAlign: TextAlign.left, ); @@ -209,7 +209,7 @@ class _OnboardingPageState extends State { children: [ Text( context.s.onboarding_aboutMyself_title, - style: context.textTheme.title.copyWith(color: Colors.white), + style: context.textTheme.headline6.copyWith(color: Colors.white), ), SizedBox(height: 32), FutureBuilder( diff --git a/lib/openhpi/widgets/course_preview.dart b/lib/openhpi/widgets/course_preview.dart index d8ed4aa..b6d4170 100644 --- a/lib/openhpi/widgets/course_preview.dart +++ b/lib/openhpi/widgets/course_preview.dart @@ -27,8 +27,8 @@ class OpenHpiCoursePreview extends StatelessWidget { children: [ Text( course.title, - style: - context.textTheme.body1.copyWith(color: Colors.white), + style: context.textTheme.bodyText2 + .copyWith(color: Colors.white), maxLines: 3, ), Text( diff --git a/lib/settings/widgets/scrollable_markdown.dart b/lib/settings/widgets/scrollable_markdown.dart deleted file mode 100644 index 1a4c0c4..0000000 --- a/lib/settings/widgets/scrollable_markdown.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/material.dart'; -import 'package:flutter_markdown/flutter_markdown.dart'; - -/// Almost identical to [Markdown], but this widget allows you to set a custom -/// [ScrollableMarkdown.scrollController]. -class ScrollableMarkdown extends MarkdownWidget { - const ScrollableMarkdown({ - Key key, - String data, - MarkdownStyleSheet styleSheet, - SyntaxHighlighter syntaxHighlighter, - MarkdownTapLinkCallback onTapLink, - Directory imageDirectory, - this.padding = const EdgeInsets.all(16), - this.scrollController, - }) : super( - key: key, - data: data, - styleSheet: styleSheet, - syntaxHighlighter: syntaxHighlighter, - onTapLink: onTapLink, - imageDirectory: imageDirectory, - ); - - /// The amount of space by which to inset the children. - final EdgeInsets padding; - final ScrollController scrollController; - - @override - Widget build(BuildContext context, List children) { - return ListView( - padding: padding, - controller: scrollController, - children: children, - ); - } -} diff --git a/lib/settings/widgets/settings_page.dart b/lib/settings/widgets/settings_page.dart index 18c0b4f..3b99597 100644 --- a/lib/settings/widgets/settings_page.dart +++ b/lib/settings/widgets/settings_page.dart @@ -1,7 +1,7 @@ +import 'package:black_hole_flutter/black_hole_flutter.dart'; import 'package:flutter/material.dart' hide Route; import 'package:flutter/services.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; -import 'package:black_hole_flutter/black_hole_flutter.dart'; import 'package:hpi_flutter/app/app.dart'; import 'package:hpi_flutter/core/core.dart' hide Image; import 'package:hpi_flutter/feedback/feedback.dart'; @@ -9,8 +9,6 @@ import 'package:hpi_flutter/onboarding/onboarding.dart'; import 'package:outline_material_icons/outline_material_icons.dart'; import 'package:package_info/package_info.dart'; -import 'scrollable_markdown.dart'; - class SettingsPage extends StatelessWidget { @override Widget build(BuildContext context) { @@ -65,7 +63,7 @@ class _MobileDevAd extends StatelessWidget { padding: const EdgeInsets.only(right: 16), child: Text( s.settings_ad_title, - style: theme.textTheme.headline.copyWith(color: onPrimary), + style: theme.textTheme.headline5.copyWith(color: onPrimary), ), ), Row( @@ -77,7 +75,8 @@ class _MobileDevAd extends StatelessWidget { children: [ Text( s.settings_ad_text, - style: theme.textTheme.body1.copyWith(color: onPrimary), + style: theme.textTheme.bodyText2 + .copyWith(color: onPrimary), ), SizedBox(height: 16), OutlineButton( @@ -116,7 +115,7 @@ class _MobileDevAd extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: Text( context.s.settings_ad_title_nonStudent, - style: theme.textTheme.subhead.copyWith(color: onPrimary), + style: theme.textTheme.subtitle1.copyWith(color: onPrimary), textAlign: TextAlign.center, ), ); @@ -138,7 +137,7 @@ class _AboutSection extends StatelessWidget { children: [ Text( context.s.settings_about_imprint_desc, - style: textTheme.body1, + style: textTheme.bodyText2, ), ], ), @@ -207,7 +206,7 @@ class _AboutSection extends StatelessWidget { onPressed: () => context.navigator.pushNamed('/settings/privacyPolicy'), child: Text(s.settings_about_privacyPolicy), ), - Text('⋅', style: context.textTheme.headline), + Text('⋅', style: context.textTheme.headline5), FlatButton( onPressed: () { PackageInfo.fromPlatform() @@ -229,7 +228,7 @@ class _AboutSection extends StatelessWidget { }, child: Text(s.settings_about_licenses), ), - Text('⋅', style: context.textTheme.headline), + Text('⋅', style: context.textTheme.headline5), FlatButton( onPressed: () { FeedbackDialog.show(context); @@ -256,9 +255,9 @@ class PrivacyPolicyPage extends StatelessWidget { return buildLoadingError(snapshot); } - return ScrollableMarkdown( - scrollController: scrollController, + return Markdown( data: snapshot.data, + controller: scrollController, onTapLink: tryLaunch, ); }, diff --git a/lib/tools/widgets/timer_page.dart b/lib/tools/widgets/timer_page.dart index 59d471b..5faebbf 100644 --- a/lib/tools/widgets/timer_page.dart +++ b/lib/tools/widgets/timer_page.dart @@ -192,13 +192,13 @@ class _CountdownTimerWidgetState extends State { onRadialDragUpdate: (coords) { // _lastCoords ??= coords; // normalize in case we change from -pi to pi - double difference = + var difference = (coords.angle - _lastCoords.angle + pi) % (2 * pi) - pi; if (difference < -pi) { difference += 2 * pi; } - Duration additional = Duration( + var additional = Duration( microseconds: (total.inMicroseconds * difference / (2 * pi)).round(), ); if (widget.timer.remaining + additional > total) { @@ -235,10 +235,10 @@ class CountdownTimerPainter extends CustomPainter { assert(total != null), _areaPaint = Paint()..color = context.theme.primaryColor, _tickSmallPaint = Paint() - ..color = context.textTheme.body1.color + ..color = context.textTheme.bodyText2.color ..strokeWidth = 1.5, _tickLargePaint = Paint() - ..color = context.textTheme.body1.color + ..color = context.textTheme.bodyText2.color ..strokeWidth = 3, _labelPainter = TextPainter( textAlign: TextAlign.center, @@ -296,7 +296,7 @@ class CountdownTimerPainter extends CustomPainter { _labelPainter ..text = TextSpan( text: (i * _tickSmallDistance.inMinutes).toString(), - style: theme.textTheme.display1, + style: theme.textTheme.headline4, ) ..layout() ..paint( diff --git a/pubspec.lock b/pubspec.lock index 20ce31b..96e13ad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -28,21 +28,21 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.0.13" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.5.2" + version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "2.4.1" black_hole_flutter: dependency: "direct main" description: @@ -56,7 +56,7 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "2.0.0" build: dependency: transitive description: @@ -70,35 +70,35 @@ packages: name: build_config url: "https://pub.dartlang.org" source: hosted - version: "0.4.1+1" + version: "0.4.2" build_daemon: dependency: transitive description: name: build_daemon url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.4" build_resolvers: dependency: transitive description: name: build_resolvers url: "https://pub.dartlang.org" source: hosted - version: "1.3.1" + version: "1.3.3" build_runner: dependency: "direct dev" description: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "1.7.3" + version: "1.9.0" build_runner_core: dependency: transitive description: name: build_runner_core url: "https://pub.dartlang.org" source: hosted - version: "4.3.0" + version: "5.1.0" built_collection: dependency: transitive description: @@ -112,14 +112,14 @@ packages: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "7.0.8" + version: "7.1.0" cached_network_image: dependency: "direct main" description: name: cached_network_image url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.2.0+1" characters: dependency: "direct main" description: @@ -133,7 +133,7 @@ packages: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.1.3" checked_yaml: dependency: transitive description: @@ -141,6 +141,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + chewie: + dependency: transitive + description: + name: chewie + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.10" + chewie_audio: + dependency: transitive + description: + name: chewie_audio + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0+1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" code_builder: dependency: transitive description: @@ -154,7 +175,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" + version: "1.14.12" convert: dependency: transitive description: @@ -168,7 +189,14 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.4" + css_colors: + dependency: transitive + description: + name: css_colors + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" csslib: dependency: transitive description: @@ -196,7 +224,7 @@ packages: name: device_info url: "https://pub.dartlang.org" source: hosted - version: "0.4.1+4" + version: "0.4.2+4" enum_to_string: dependency: "direct main" description: @@ -204,6 +232,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.9" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0" fixnum: dependency: transitive description: @@ -222,28 +257,28 @@ packages: name: flutter_cache_manager url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.2.2" flutter_deep_linking: dependency: "direct main" description: name: flutter_deep_linking url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "0.1.2" flutter_html: dependency: "direct main" description: name: flutter_html url: "https://pub.dartlang.org" source: hosted - version: "0.10.4" + version: "1.0.0" flutter_launcher_icons: dependency: "direct dev" description: name: flutter_launcher_icons url: "https://pub.dartlang.org" source: hosted - version: "0.7.4" + version: "0.7.5" flutter_localizations: dependency: "direct main" description: flutter @@ -255,7 +290,7 @@ packages: name: flutter_markdown url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.3.5" flutter_pagewise: dependency: "direct main" description: @@ -269,7 +304,14 @@ packages: name: flutter_ringtone_player url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "2.0.0" + flutter_svg: + dependency: transitive + description: + name: flutter_svg + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.4" flutter_test: dependency: "direct dev" description: flutter @@ -286,7 +328,7 @@ packages: name: get_it url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "4.0.2" glob: dependency: transitive description: @@ -328,7 +370,7 @@ packages: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.12.0+4" + version: "0.12.1" http2: dependency: transitive description: @@ -342,21 +384,21 @@ packages: name: http_multi_server url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.2.0" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.3" + version: "3.1.4" image: dependency: transitive description: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.12" immutable_proto: dependency: "direct main" description: @@ -377,7 +419,7 @@ packages: name: intl url: "https://pub.dartlang.org" source: hosted - version: "0.16.0" + version: "0.16.1" intl_translation: dependency: transitive description: @@ -391,14 +433,14 @@ packages: name: intl_utils url: "https://pub.dartlang.org" source: hosted - version: "1.2.2" + version: "1.5.0" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.3" + version: "0.3.4" js: dependency: transitive description: @@ -477,14 +519,21 @@ packages: name: node_interop url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.1.1" node_io: dependency: transitive description: name: node_io url: "https://pub.dartlang.org" source: hosted - version: "1.0.1+2" + version: "1.1.1" + open_iconic_flutter: + dependency: transitive + description: + name: open_iconic_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" outline_material_icons: dependency: "direct main" description: @@ -498,14 +547,14 @@ packages: name: package_config url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.9.3" package_info: dependency: "direct main" description: name: package_info url: "https://pub.dartlang.org" source: hosted - version: "0.4.0+13" + version: "0.4.0+18" package_resolver: dependency: transitive description: @@ -520,20 +569,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.6.4" + path_drawing: + dependency: transitive + description: + name: path_drawing + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" path_provider: dependency: "direct main" description: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.5.1" + version: "1.6.8" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+2" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" pedantic: dependency: "direct main" description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.8.0+1" + version: "1.9.0" petitparser: dependency: transitive description: @@ -554,7 +631,7 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" pool: dependency: transitive description: @@ -575,7 +652,7 @@ packages: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.4.2" + version: "1.4.4" pubspec_parse: dependency: transitive description: @@ -589,7 +666,7 @@ packages: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.1.3" resource: dependency: transitive description: @@ -603,7 +680,14 @@ packages: name: rxdart url: "https://pub.dartlang.org" source: hosted - version: "0.22.6" + version: "0.24.0" + screen: + dependency: transitive + description: + name: screen + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.5" screenshot: dependency: "direct main" description: @@ -617,35 +701,35 @@ packages: name: share url: "https://pub.dartlang.org" source: hosted - version: "0.6.2+3" + version: "0.6.4+2" shared_preferences: dependency: "direct main" description: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "0.5.6" + version: "0.5.7+2" shared_preferences_macos: dependency: transitive description: name: shared_preferences_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+4" + version: "0.0.1+8" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.4" shared_preferences_web: dependency: transitive description: name: shared_preferences_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.2+3" + version: "0.1.2+5" shelf: dependency: transitive description: @@ -671,14 +755,14 @@ packages: name: source_gen url: "https://pub.dartlang.org" source: hosted - version: "0.9.4+7" + version: "0.9.5" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.7.0" sprintf: dependency: "direct main" description: @@ -692,7 +776,14 @@ packages: name: sqflite url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.0+1" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" stack_trace: dependency: transitive description: @@ -713,7 +804,7 @@ packages: name: stream_transform url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" string_scanner: dependency: transitive description: @@ -741,7 +832,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.11" + version: "0.2.15" time: dependency: transitive description: @@ -762,7 +853,7 @@ packages: name: timeago url: "https://pub.dartlang.org" source: hosted - version: "2.0.25" + version: "2.0.26" timing: dependency: transitive description: @@ -783,28 +874,28 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "5.4.1" + version: "5.4.7" url_launcher_macos: dependency: transitive description: name: url_launcher_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+2" + version: "0.0.1+5" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.7" url_launcher_web: dependency: transitive description: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.0+2" + version: "0.1.1+5" uuid: dependency: transitive description: @@ -819,13 +910,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.8" + video_player: + dependency: transitive + description: + name: video_player + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.11" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + video_player_web: + dependency: transitive + description: + name: video_player_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + wakelock: + dependency: transitive + description: + name: wakelock + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4+1" watcher: dependency: transitive description: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+13" + version: "0.9.7+15" web_socket_channel: dependency: transitive description: @@ -833,20 +952,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + webview_flutter: + dependency: transitive + description: + name: webview_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.21" xml: dependency: transitive description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.5.0" + version: "3.6.1" yaml: dependency: "direct main" description: name: yaml url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.2.1" sdks: dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4 <2.0.0" + flutter: ">=1.17.0 <1.18.0" diff --git a/pubspec.yaml b/pubspec.yaml index 9c64a1a..20c4398 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,6 +5,7 @@ version: 1.0.0+1 environment: sdk: ">=2.7.0 <3.0.0" + flutter: ">=1.17.0 <1.18.0" dependencies: flutter: @@ -18,12 +19,12 @@ dependencies: device_info: ^0.4.1+4 enum_to_string: ^1.0.9 flutter_deep_linking: ^0.1.1 - flutter_html: ^0.10.4 + flutter_html: ^1.0.0 flutter_localizations: sdk: flutter - flutter_markdown: ^0.2.0 + flutter_markdown: ^0.3.5 flutter_pagewise: ^1.2.3 - flutter_ringtone_player: ^1.0.3 + flutter_ringtone_player: ^2.0.0 get_it: ^4.0.1 grpc: ^2.1.2 http: ^0.12.0+2 @@ -39,7 +40,7 @@ dependencies: path_provider: ^1.3.0 pedantic: ^1.8.0+1 protobuf: ^1.0.0 - rxdart: ^0.22.1+1 + rxdart: ^0.24.0 screenshot: ^0.1.1 share: ^0.6.2+3 shared_preferences: ^0.5.6