mirror of
https://github.com/Iconica-Development/flutter_timetable.git
synced 2025-05-19 11:43:45 +02:00
Compare commits
No commits in common. "master" and "1.3.0" have entirely different histories.
51 changed files with 53 additions and 792 deletions
23
.github/dependabot.yml
vendored
23
.github/dependabot.yml
vendored
|
@ -1,23 +0,0 @@
|
||||||
version: 2
|
|
||||||
|
|
||||||
updates:
|
|
||||||
# - package-ecosystem: "pub"
|
|
||||||
# directory: "/packages/flutter_timetable"
|
|
||||||
# schedule:
|
|
||||||
# interval: "weekly"
|
|
||||||
|
|
||||||
- package-ecosystem: "pub"
|
|
||||||
directory: "/packages/flutter_timetable_interface"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
|
|
||||||
- package-ecosystem: "pub"
|
|
||||||
directory: "/packages/flutter_timetable_firebase"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
|
|
||||||
- package-ecosystem: "pub"
|
|
||||||
directory: "/packages/flutter_timetable_view"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
|
|
14
.github/workflows/component-documentation.yml
vendored
14
.github/workflows/component-documentation.yml
vendored
|
@ -1,14 +0,0 @@
|
||||||
name: Iconica Standard Component Documentation Workflow
|
|
||||||
# Workflow Caller version: 1.0.0
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
call-iconica-component-documentation-workflow:
|
|
||||||
uses: Iconica-Development/.github/.github/workflows/component-documentation.yml@master
|
|
||||||
secrets: inherit
|
|
||||||
permissions: write-all
|
|
12
.github/workflows/flutter.yml
vendored
Normal file
12
.github/workflows/flutter.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
name: Iconica Standard Component CI Workflow
|
||||||
|
# Workflow Caller version: 1.0.0
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
call-global-iconica-workflow:
|
||||||
|
uses: Iconica-Development/.github/.github/workflows/component-ci.yml@master
|
||||||
|
secrets: inherit
|
||||||
|
permissions: write-all
|
14
.github/workflows/melos-ci.yml
vendored
14
.github/workflows/melos-ci.yml
vendored
|
@ -1,14 +0,0 @@
|
||||||
name: Iconica Standard Melos CI Workflow
|
|
||||||
# Workflow Caller version: 1.0.0
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
call-global-iconica-workflow:
|
|
||||||
uses: Iconica-Development/.github/.github/workflows/melos-ci.yml@master
|
|
||||||
secrets: inherit
|
|
||||||
permissions: write-all
|
|
||||||
with:
|
|
||||||
subfolder: '.' # add optional subfolder to run workflow in
|
|
17
.gitignore
vendored
17
.gitignore
vendored
|
@ -23,23 +23,12 @@ migrate_working_dir/
|
||||||
|
|
||||||
# Flutter/Dart/Pub related
|
# Flutter/Dart/Pub related
|
||||||
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||||
pubspec.lock
|
/pubspec.lock
|
||||||
**/doc/api/
|
**/doc/api/
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.packages
|
.packages
|
||||||
build/
|
build/
|
||||||
.metadata
|
.metadata
|
||||||
.flutter-plugins
|
|
||||||
.flutter-plugins-dependencies
|
|
||||||
|
|
||||||
android/
|
|
||||||
ios/
|
|
||||||
web/
|
|
||||||
linux/
|
|
||||||
macos/
|
|
||||||
windows/
|
|
||||||
|
|
||||||
pubspec_overrides.yaml
|
|
||||||
|
|
||||||
example/android/
|
example/android/
|
||||||
example/ios/
|
example/ios/
|
||||||
|
@ -47,7 +36,3 @@ example/web/
|
||||||
example/linux/
|
example/linux/
|
||||||
example/macos/
|
example/macos/
|
||||||
example/windows/
|
example/windows/
|
||||||
|
|
||||||
# FVM Version Cache
|
|
||||||
.fvm/
|
|
||||||
.fvmrc
|
|
||||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -26,17 +26,3 @@
|
||||||
## [1.3.0] - 8 November 2023
|
## [1.3.0] - 8 November 2023
|
||||||
|
|
||||||
* Add the option for setting an offset for the hours so that the first hour is not 00:00 but 08:00 for example and the last hour can be after 24:00.
|
* Add the option for setting an offset for the hours so that the first hour is not 00:00 but 08:00 for example and the last hour can be after 24:00.
|
||||||
|
|
||||||
## [1.4.0] - 13 November 2023
|
|
||||||
|
|
||||||
* Add the option for sorting the blocks by their id.
|
|
||||||
|
|
||||||
## [2.0.0] - 03 December 2023
|
|
||||||
|
|
||||||
* Create Melos variant of the component where there are multiple packages in the same repository.
|
|
||||||
|
|
||||||
* Added the option to sort on the starttime of an event.
|
|
||||||
|
|
||||||
## [3.0.0] - 11 July 2024
|
|
||||||
|
|
||||||
* Rename main entry point to flutter_timetable
|
|
||||||
|
|
198
CONTRIBUTING.md
198
CONTRIBUTING.md
|
@ -1,198 +0,0 @@
|
||||||
# Contributing
|
|
||||||
|
|
||||||
First off, thanks for taking the time to contribute! ❤️
|
|
||||||
|
|
||||||
All types of contributions are encouraged and valued.
|
|
||||||
See the [Table of Contents](#table-of-contents) for different ways to help and details about how we handle them.
|
|
||||||
Please make sure to read the relevant section before making your contribution.
|
|
||||||
It will make it a lot easier for us maintainers and smooth out the experience for all involved.
|
|
||||||
Iconica looks forward to your contributions. 🎉
|
|
||||||
|
|
||||||
## Table of contents
|
|
||||||
|
|
||||||
- [Code of conduct](#code-of-conduct)
|
|
||||||
- [I Have a Question](#i-have-a-question)
|
|
||||||
- [I Want To Contribute](#i-want-to-contribute)
|
|
||||||
- [Reporting Bugs](#reporting-bugs)
|
|
||||||
- [Contributing code](#contributing-code)
|
|
||||||
|
|
||||||
## Code of conduct
|
|
||||||
|
|
||||||
### Legal notice
|
|
||||||
|
|
||||||
When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
|
|
||||||
All accepted pull requests and other additions to this project will be considered intellectual property of Iconica.
|
|
||||||
|
|
||||||
All repositories should be kept clean of jokes, easter eggs and other unnecessary additions.
|
|
||||||
|
|
||||||
## I have a question
|
|
||||||
|
|
||||||
If you want to ask a question, we assume that you have read the available documentation found within the code.
|
|
||||||
Before you ask a question, it is best to search for existing issues that might help you.
|
|
||||||
In case you have found a suitable issue but still need clarification, you can ask your question
|
|
||||||
It is also advisable to search the internet for answers first.
|
|
||||||
|
|
||||||
If you then still feel the need to ask a question and need clarification, we recommend the following:
|
|
||||||
|
|
||||||
- Open an issue.
|
|
||||||
- Provide as much context as you can about what you're running into.
|
|
||||||
|
|
||||||
We will then take care of the issue as soon as possible.
|
|
||||||
|
|
||||||
## I want to contribute
|
|
||||||
|
|
||||||
### Reporting bugs
|
|
||||||
|
|
||||||
<!-- omit in toc -->
|
|
||||||
|
|
||||||
**Before submitting a bug report**
|
|
||||||
|
|
||||||
A good bug report shouldn't leave others needing to chase you up for more information.
|
|
||||||
Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report.
|
|
||||||
Please complete the following steps in advance to help us fix any potential bug as fast as possible.
|
|
||||||
|
|
||||||
- Make sure that you are using the latest version.
|
|
||||||
- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (If you are looking for support, you might want to check [this section](#i-have-a-question)).
|
|
||||||
- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error.
|
|
||||||
- Also make sure to search the internet (including Stack Overflow) to see if users outside of Iconica have discussed the issue.
|
|
||||||
- Collect information about the bug:
|
|
||||||
- Stack trace (Traceback)
|
|
||||||
- OS, Platform and Version (Windows, Linux, macOS, x86, ARM)
|
|
||||||
- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
|
|
||||||
- Time and date of occurance
|
|
||||||
- Describe the expected result and actual result
|
|
||||||
- Can you reliably reproduce the issue? And can you also reproduce it with older versions? Describe all steps that lead to the bug.
|
|
||||||
|
|
||||||
Once it's filed:
|
|
||||||
|
|
||||||
- The project team will label the issue accordingly.
|
|
||||||
- A team member will try to reproduce the issue with your provided steps.
|
|
||||||
If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for additional information.
|
|
||||||
- If the team is able to reproduce the issue, it will be moved into the backlog, as well as marked with a priority, and the issue will be left to be [implemented by someone](#contributing-code).
|
|
||||||
|
|
||||||
### Contributing code
|
|
||||||
|
|
||||||
When you start working on your contribution, make sure you are aware of the relevant documentation and the functionality of the component you are working on.
|
|
||||||
|
|
||||||
When writing code, follow the style guidelines set by Dart: [Effective Dart](https://Dart.dev/guides/language/effective-Dart). This contains most information you will need to write clean Dart code that is well documented.
|
|
||||||
|
|
||||||
**Documentation**
|
|
||||||
|
|
||||||
As Effective Dart indicates, documenting your public methods with Dart doc comments is recommended.
|
|
||||||
Aside from Effective Dart, we require specific information in the documentation of a method:
|
|
||||||
|
|
||||||
At the very least, your documentation should first name what the code does, then followed below by requirements for calling the method, the result of the method.
|
|
||||||
Any references to internal variables or other methods should be done through [var] to indicate a reference.
|
|
||||||
|
|
||||||
If the method or class is complex enough (determined by the reviewers) an example is required.
|
|
||||||
If unsure, add an example in the docs using code blocks.
|
|
||||||
|
|
||||||
For classes and methods, document the individual parameters with their implications.
|
|
||||||
|
|
||||||
> Tip: Remember that the shortest documentation can be written by having good descriptive names in the first place.
|
|
||||||
|
|
||||||
An example:
|
|
||||||
|
|
||||||
````Dart
|
|
||||||
library iconica_utilities.bidirectional_sorter;
|
|
||||||
|
|
||||||
part 'sorter.Dart';
|
|
||||||
part 'enum.Dart';
|
|
||||||
|
|
||||||
/// Generic sort method, allow sorting of list with primitives or complex types.
|
|
||||||
/// Uses [SortDirection] to determine the direction, either Ascending or Descending,
|
|
||||||
/// Gets called on [List] toSort of type [T] which cannot be shorter than 2.
|
|
||||||
/// Optionally for complex types a [Comparable] [Function] can be given to compare complex types.
|
|
||||||
/// ```
|
|
||||||
/// List<TestObject> objects = [];
|
|
||||||
/// for (int i = 0; i < 10; i++) {
|
|
||||||
/// objects.add(TestObject(name: "name", id: i));
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// sort<TestObject>(
|
|
||||||
/// SortDirection.descending, objects, (object) => object.id);
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// In the above example a list of TestObjects is created, and then sorted in descending order.
|
|
||||||
/// If the implementation of TestObject is as following:
|
|
||||||
/// ```
|
|
||||||
/// class TestObject {
|
|
||||||
/// final String name;
|
|
||||||
/// final int id;
|
|
||||||
///
|
|
||||||
/// TestObject({required this.name, required this.id});
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
/// And the list is logged to the console, the following will appear:
|
|
||||||
/// ```
|
|
||||||
/// [name9, name8, name7, name6, name5, name4, name3, name2, name1, name0]
|
|
||||||
/// ```
|
|
||||||
|
|
||||||
void sort<T>(
|
|
||||||
/// Determines the sorting direction, can be either Ascending or Descending
|
|
||||||
SortDirection sortDirection,
|
|
||||||
|
|
||||||
/// Incoming list, which gets sorted
|
|
||||||
List<T> toSort, [
|
|
||||||
|
|
||||||
/// Optional comparable, which is only necessary for complex types
|
|
||||||
SortFieldGetter<T>? sortValueCallback,
|
|
||||||
]) {
|
|
||||||
if (toSort.length < 2) return;
|
|
||||||
assert(
|
|
||||||
toSort.whereType<Comparable>().isNotEmpty || sortValueCallback != null);
|
|
||||||
BidirectionalSorter<T>(
|
|
||||||
sortInstructions: <SortInstruction<T>>[
|
|
||||||
SortInstruction(
|
|
||||||
sortValueCallback ?? (t) => t as Comparable, sortDirection),
|
|
||||||
],
|
|
||||||
).sort(toSort);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// same functionality as [sort] but with the added functionality
|
|
||||||
/// of sorting multiple values
|
|
||||||
void sortMulti<T>(
|
|
||||||
/// Incoming list, which gets sorted
|
|
||||||
List<T> toSort,
|
|
||||||
|
|
||||||
/// list of comparables to sort multiple values at once,
|
|
||||||
/// priority based on index
|
|
||||||
List<SortInstruction<T>> sortValueCallbacks,
|
|
||||||
) {
|
|
||||||
if (toSort.length < 2) return;
|
|
||||||
assert(sortValueCallbacks.isNotEmpty);
|
|
||||||
BidirectionalSorter<T>(
|
|
||||||
sortInstructions: sortValueCallbacks,
|
|
||||||
).sort(toSort);
|
|
||||||
}
|
|
||||||
|
|
||||||
````
|
|
||||||
|
|
||||||
**Tests**
|
|
||||||
|
|
||||||
For each public method that was created, excluding widgets, which contains any form of logic (e.g. Calculations, predicates or major side-effects) tests are required.
|
|
||||||
|
|
||||||
A set of tests is written for each method, covering at least each path within the method. For example:
|
|
||||||
|
|
||||||
```Dart
|
|
||||||
void foo() {
|
|
||||||
try {
|
|
||||||
var bar = doSomething();
|
|
||||||
if (bar) {
|
|
||||||
doSomethingElse();
|
|
||||||
} else {
|
|
||||||
doSomethingCool();
|
|
||||||
}
|
|
||||||
} catch (_) {
|
|
||||||
displayError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The method above should result in 3 tests:
|
|
||||||
|
|
||||||
1. A test for the path leading to displayError by the cause of an exception
|
|
||||||
2. A test for if bar is true, resulting in doSomethingElse()
|
|
||||||
3. A test for if bar is false, resulting in the doSomethingCool() method being called.
|
|
||||||
|
|
||||||
This means that we require 100% coverage of each method you test.
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2023 Iconica, All rights reserved.
|
Copyright (c) 2022 Iconica, All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ Please file any issues, bugs or feature request as an issue on our [GitHub](http
|
||||||
|
|
||||||
## Want to contribute
|
## Want to contribute
|
||||||
|
|
||||||
If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug or adding a cool new feature), please carefully review our [contribution guide](./CONTRIBUTING.md) and send us your [pull request](https://github.com/Iconica-Development/flutter_date_time_picker/pulls).
|
If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug or adding a cool new feature), please carefully review our [contribution guide](../CONTRIBUTING.md) and send us your [pull request](https://github.com/Iconica-Development/flutter_date_time_picker/pulls).
|
||||||
|
|
||||||
## Author
|
## Author
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_timetable_view/flutter_timetable_view.dart';
|
import 'package:flutter_timetable/timetable.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MaterialApp(home: TimetableDemo()));
|
runApp(const MaterialApp(home: TimetableDemo()));
|
||||||
|
@ -34,7 +34,7 @@ class _TimetableDemoState extends State<TimetableDemo> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
id: 3,
|
id: 1,
|
||||||
),
|
),
|
||||||
TimeBlock(
|
TimeBlock(
|
||||||
start: const TimeOfDay(hour: 10, minute: 0),
|
start: const TimeOfDay(hour: 10, minute: 0),
|
||||||
|
@ -50,7 +50,7 @@ class _TimetableDemoState extends State<TimetableDemo> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
childDimension: 300,
|
childDimension: 300,
|
||||||
id: 1,
|
id: 3,
|
||||||
),
|
),
|
||||||
TimeBlock(
|
TimeBlock(
|
||||||
start: const TimeOfDay(hour: 14, minute: 0),
|
start: const TimeOfDay(hour: 14, minute: 0),
|
||||||
|
@ -150,7 +150,6 @@ class _TimetableDemoState extends State<TimetableDemo> {
|
||||||
onOverScroll: () {},
|
onOverScroll: () {},
|
||||||
onUnderScroll: () {},
|
onUnderScroll: () {},
|
||||||
hoursOffset: 6,
|
hoursOffset: 6,
|
||||||
sortByIdAscending: true,
|
|
||||||
size: Size(size.width, size.height * 0.64),
|
size: Size(size.width, size.height * 0.64),
|
||||||
tableDirection: _horizontal ? Axis.horizontal : Axis.vertical,
|
tableDirection: _horizontal ? Axis.horizontal : Axis.vertical,
|
||||||
startHour: 0,
|
startHour: 0,
|
|
@ -1,4 +1,4 @@
|
||||||
name: flutter_timetable_view_example
|
name: timetable_example
|
||||||
description: Timetable Widget
|
description: Timetable Widget
|
||||||
|
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
@ -13,10 +13,8 @@ dependencies:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
flutter_timetable_view:
|
flutter_timetable:
|
||||||
path: ../
|
path: ../
|
||||||
flutter_timetable_interface:
|
|
||||||
hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
|
@ -3,7 +3,7 @@
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_timetable_view/src/models/time_block.dart';
|
import 'package:flutter_timetable/src/models/time_block.dart';
|
||||||
|
|
||||||
/// Combine blocks that have the same id and the same time.
|
/// Combine blocks that have the same id and the same time.
|
||||||
List<TimeBlock> combineBlocksWithId(List<TimeBlock> blocks) {
|
List<TimeBlock> combineBlocksWithId(List<TimeBlock> blocks) {
|
||||||
|
@ -39,7 +39,6 @@ List<TimeBlock> combineBlocksWithId(List<TimeBlock> blocks) {
|
||||||
return newBlocks;
|
return newBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Combines grouped blocks into one block.
|
|
||||||
void _combineGroupedBlocks(
|
void _combineGroupedBlocks(
|
||||||
List<List<TimeBlock>> groupedBlocks,
|
List<List<TimeBlock>> groupedBlocks,
|
||||||
List<TimeBlock> newBlocks,
|
List<TimeBlock> newBlocks,
|
||||||
|
@ -75,10 +74,6 @@ void _combineGroupedBlocks(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if a block with a certain id exists in the grouped blocks.
|
|
||||||
///
|
|
||||||
/// Returns true if a block with the same id, start time, and end time exists in the grouped blocks list.
|
|
||||||
/// Otherwise, returns false.
|
|
||||||
bool _checkIfBlockWithIdExists(
|
bool _checkIfBlockWithIdExists(
|
||||||
List<List<TimeBlock>> groupedBlocks,
|
List<List<TimeBlock>> groupedBlocks,
|
||||||
TimeBlock block,
|
TimeBlock block,
|
|
@ -6,12 +6,11 @@ import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_timetable_view/src/block_service.dart';
|
import 'package:flutter_timetable/src/block_service.dart';
|
||||||
import 'package:flutter_timetable_view/src/models/table_theme.dart';
|
import 'package:flutter_timetable/src/models/table_theme.dart';
|
||||||
import 'package:flutter_timetable_view/src/models/time_block.dart';
|
import 'package:flutter_timetable/src/models/time_block.dart';
|
||||||
import 'package:flutter_timetable_view/src/widgets/block.dart';
|
import 'package:flutter_timetable/src/widgets/block.dart';
|
||||||
|
import 'package:flutter_timetable/src/widgets/table.dart' as table;
|
||||||
import 'package:flutter_timetable_view/src/widgets/table.dart' as table;
|
|
||||||
|
|
||||||
class Timetable extends StatefulWidget {
|
class Timetable extends StatefulWidget {
|
||||||
/// [Timetable] widget that displays a timetable with [TimeBlock]s.
|
/// [Timetable] widget that displays a timetable with [TimeBlock]s.
|
||||||
|
@ -35,8 +34,6 @@ class Timetable extends StatefulWidget {
|
||||||
this.theme = const TableTheme(),
|
this.theme = const TableTheme(),
|
||||||
this.mergeBlocks = false,
|
this.mergeBlocks = false,
|
||||||
this.combineBlocks = true,
|
this.combineBlocks = true,
|
||||||
this.sortByIdAscending = false,
|
|
||||||
this.sortByStartTime = false,
|
|
||||||
this.onOverScroll,
|
this.onOverScroll,
|
||||||
this.onUnderScroll,
|
this.onUnderScroll,
|
||||||
this.scrollTriggerOffset = 120,
|
this.scrollTriggerOffset = 120,
|
||||||
|
@ -45,12 +42,7 @@ class Timetable extends StatefulWidget {
|
||||||
}) : assert(
|
}) : assert(
|
||||||
scrollTriggerOffset > scrollJumpToOffset,
|
scrollTriggerOffset > scrollJumpToOffset,
|
||||||
'ScrollTriggerOffset cannot be smaller'
|
'ScrollTriggerOffset cannot be smaller'
|
||||||
' then the scrollJumpToOffset.',
|
' then the scrollJumpToOffset.');
|
||||||
),
|
|
||||||
assert(
|
|
||||||
!(mergeBlocks && sortByIdAscending),
|
|
||||||
'mergeBlocks and sortByIdAscending'
|
|
||||||
' cannot be enabled at the same time.');
|
|
||||||
|
|
||||||
/// The Axis in which the table is layed out.
|
/// The Axis in which the table is layed out.
|
||||||
final Axis tableDirection;
|
final Axis tableDirection;
|
||||||
|
@ -100,12 +92,6 @@ class Timetable extends StatefulWidget {
|
||||||
/// If blocks have the same id and time they will be combined into one block.
|
/// If blocks have the same id and time they will be combined into one block.
|
||||||
final bool combineBlocks;
|
final bool combineBlocks;
|
||||||
|
|
||||||
/// Whether or not to sort blocks by their ID in ascending order.
|
|
||||||
final bool sortByIdAscending;
|
|
||||||
|
|
||||||
/// Whether or not to sort blocks by their StartTime.
|
|
||||||
final bool sortByStartTime;
|
|
||||||
|
|
||||||
/// The offset which trigger the jump to either the previous or next page. Can't be lower then [scrollJumpToOffset].
|
/// The offset which trigger the jump to either the previous or next page. Can't be lower then [scrollJumpToOffset].
|
||||||
final double scrollTriggerOffset;
|
final double scrollTriggerOffset;
|
||||||
|
|
||||||
|
@ -161,12 +147,6 @@ class _TimetableState extends State<Timetable> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int compareTimeOfDay(TimeOfDay time1, TimeOfDay time2) {
|
|
||||||
var totalMinutes1 = time1.hour * 60 + time1.minute;
|
|
||||||
var totalMinutes2 = time2.hour * 60 + time2.minute;
|
|
||||||
return totalMinutes1.compareTo(totalMinutes2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
if (widget.scrollController == null) {
|
if (widget.scrollController == null) {
|
||||||
|
@ -183,18 +163,6 @@ class _TimetableState extends State<Timetable> {
|
||||||
} else {
|
} else {
|
||||||
blocks = widget.timeBlocks;
|
blocks = widget.timeBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (widget.sortByIdAscending) {
|
|
||||||
// if the id is zero then put it at the end
|
|
||||||
blocks.sort((a, b) => (a.id != 0 ? a.id : double.infinity).compareTo(
|
|
||||||
(b.id != 0 ? b.id : double.infinity),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widget.sortByStartTime) {
|
|
||||||
blocks.sort((a, b) => compareTimeOfDay(a.start, b.start));
|
|
||||||
}
|
|
||||||
|
|
||||||
var linePadding = _calculateTableTextSize().width;
|
var linePadding = _calculateTableTextSize().width;
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: widget.size?.width,
|
width: widget.size?.width,
|
||||||
|
@ -375,7 +343,7 @@ class _TimetableState extends State<Timetable> {
|
||||||
widget.theme.timeStyle ?? Theme.of(context).textTheme.bodyLarge,
|
widget.theme.timeStyle ?? Theme.of(context).textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textScaler: MediaQuery.of(context).textScaler,
|
textScaleFactor: MediaQuery.of(context).textScaleFactor,
|
||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
)..layout())
|
)..layout())
|
||||||
.size;
|
.size;
|
|
@ -3,7 +3,7 @@
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_timetable_view/src/models/table_theme.dart';
|
import 'package:flutter_timetable/src/models/table_theme.dart';
|
||||||
|
|
||||||
class Table extends StatelessWidget {
|
class Table extends StatelessWidget {
|
||||||
/// The [Table] to draw an overview of timerange with corresponding hour lines
|
/// The [Table] to draw an overview of timerange with corresponding hour lines
|
|
@ -2,10 +2,10 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
library flutter_timetable;
|
library timetable;
|
||||||
|
|
||||||
export 'src/models/table_theme.dart';
|
export 'src/models/table_theme.dart';
|
||||||
|
export 'src/models/time_block.dart';
|
||||||
export 'src/timetable.dart';
|
export 'src/timetable.dart';
|
||||||
export 'src/widgets/block.dart';
|
export 'src/widgets/block.dart';
|
||||||
export 'src/widgets/table.dart';
|
export 'src/widgets/table.dart';
|
||||||
export 'src/models/time_block.dart';
|
|
38
melos.yaml
38
melos.yaml
|
@ -1,38 +0,0 @@
|
||||||
name: flutter_timetable
|
|
||||||
|
|
||||||
packages:
|
|
||||||
- packages/**
|
|
||||||
|
|
||||||
command:
|
|
||||||
version:
|
|
||||||
branch: master
|
|
||||||
|
|
||||||
scripts:
|
|
||||||
lint:all:
|
|
||||||
run: dart run melos run analyze && dart run melos run format-check
|
|
||||||
description: Run all static analysis checks.
|
|
||||||
|
|
||||||
get:
|
|
||||||
run: |
|
|
||||||
melos exec -c 1 -- "flutter pub get"
|
|
||||||
melos exec --scope="*example*" -c 1 -- "flutter pub get"
|
|
||||||
|
|
||||||
upgrade:
|
|
||||||
run: melos exec -c 1 -- "flutter pub upgrade"
|
|
||||||
|
|
||||||
create:
|
|
||||||
run: melos exec --scope="*example*" -c 1 -- "flutter create ."
|
|
||||||
|
|
||||||
analyze:
|
|
||||||
run: |
|
|
||||||
dart run melos exec -c 1 -- \
|
|
||||||
flutter analyze --fatal-infos
|
|
||||||
description: Run `flutter analyze` for all packages.
|
|
||||||
|
|
||||||
format:
|
|
||||||
run: dart run melos exec dart format .
|
|
||||||
description: Run `dart format` for all packages.
|
|
||||||
|
|
||||||
format-check:
|
|
||||||
run: dart run melos exec dart format . --set-exit-if-changed
|
|
||||||
description: Run `dart format` checks for all packages.
|
|
|
@ -1 +0,0 @@
|
||||||
../../CHANGELOG.md
|
|
|
@ -1 +0,0 @@
|
||||||
../../LICENSE
|
|
|
@ -1 +0,0 @@
|
||||||
../../README.md
|
|
|
@ -1,43 +0,0 @@
|
||||||
# Miscellaneous
|
|
||||||
*.class
|
|
||||||
*.log
|
|
||||||
*.pyc
|
|
||||||
*.swp
|
|
||||||
.DS_Store
|
|
||||||
.atom/
|
|
||||||
.buildlog/
|
|
||||||
.history
|
|
||||||
.svn/
|
|
||||||
migrate_working_dir/
|
|
||||||
|
|
||||||
# IntelliJ related
|
|
||||||
*.iml
|
|
||||||
*.ipr
|
|
||||||
*.iws
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
# The .vscode folder contains launch configuration and tasks you configure in
|
|
||||||
# VS Code which you may wish to be included in version control, so this line
|
|
||||||
# is commented out by default.
|
|
||||||
#.vscode/
|
|
||||||
|
|
||||||
# Flutter/Dart/Pub related
|
|
||||||
**/doc/api/
|
|
||||||
**/ios/Flutter/.last_build_id
|
|
||||||
.dart_tool/
|
|
||||||
.flutter-plugins
|
|
||||||
.flutter-plugins-dependencies
|
|
||||||
.pub-cache/
|
|
||||||
.pub/
|
|
||||||
/build/
|
|
||||||
|
|
||||||
# Symbolication related
|
|
||||||
app.*.symbols
|
|
||||||
|
|
||||||
# Obfuscation related
|
|
||||||
app.*.map.json
|
|
||||||
|
|
||||||
# Android Studio will place build artifacts here
|
|
||||||
/android/app/debug
|
|
||||||
/android/app/profile
|
|
||||||
/android/app/release
|
|
|
@ -1,16 +0,0 @@
|
||||||
# example
|
|
||||||
|
|
||||||
A new Flutter project.
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
|
||||||
|
|
||||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
|
||||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
|
||||||
|
|
||||||
For help getting started with Flutter development, view the
|
|
||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
|
||||||
samples, guidance on mobile development, and a full API reference.
|
|
|
@ -1,28 +0,0 @@
|
||||||
# This file configures the analyzer, which statically analyzes Dart code to
|
|
||||||
# check for errors, warnings, and lints.
|
|
||||||
#
|
|
||||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
|
||||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
|
||||||
# invoked from the command line by running `flutter analyze`.
|
|
||||||
|
|
||||||
# The following line activates a set of recommended lints for Flutter apps,
|
|
||||||
# packages, and plugins designed to encourage good coding practices.
|
|
||||||
include: package:flutter_lints/flutter.yaml
|
|
||||||
|
|
||||||
linter:
|
|
||||||
# The lint rules applied to this project can be customized in the
|
|
||||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
|
||||||
# included above or to enable additional rules. A list of all available lints
|
|
||||||
# and their documentation is published at https://dart.dev/lints.
|
|
||||||
#
|
|
||||||
# Instead of disabling a lint rule for the entire project in the
|
|
||||||
# section below, it can also be suppressed for a single line of code
|
|
||||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
|
||||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
|
||||||
# producing the lint.
|
|
||||||
rules:
|
|
||||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
|
||||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
|
||||||
|
|
||||||
# Additional information about this file can be found at
|
|
||||||
# https://dart.dev/guides/language/analysis-options
|
|
|
@ -1,23 +0,0 @@
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:flutter_timetable_firebase/flutter_timetable_firebase.dart';
|
|
||||||
import 'package:flutter_timetable_interface/flutter_timetable_interface.dart';
|
|
||||||
|
|
||||||
class MyRosterModel extends TimetableEvent {
|
|
||||||
const MyRosterModel({
|
|
||||||
required super.end,
|
|
||||||
required super.start,
|
|
||||||
required super.entityId,
|
|
||||||
required super.eventId,
|
|
||||||
this.isSick = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
final bool isSick;
|
|
||||||
}
|
|
||||||
|
|
||||||
final myRosterServiceProvider = Provider(
|
|
||||||
(ref) => FirebaseTimetableService<MyRosterModel>(
|
|
||||||
options: const FirebaseTimetableOptions(timetableCollectionName: 'roster'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
void main() {}
|
|
|
@ -1,31 +0,0 @@
|
||||||
name: flutter_timetable_firebase_example
|
|
||||||
description: Timetable Widget
|
|
||||||
|
|
||||||
publish_to: 'none'
|
|
||||||
|
|
||||||
version: 1.1.0+2
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: ">=3.0.0 <4.0.0"
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
flutter:
|
|
||||||
sdk: flutter
|
|
||||||
|
|
||||||
cupertino_icons: ^1.0.2
|
|
||||||
flutter_timetable_firebase:
|
|
||||||
path: ../
|
|
||||||
flutter_timetable_interface:
|
|
||||||
hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
|
||||||
version: ^2.0.0
|
|
||||||
hooks_riverpod: ^2.4.9
|
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
|
||||||
flutter_test:
|
|
||||||
sdk: flutter
|
|
||||||
|
|
||||||
flutter_lints: ^2.0.0
|
|
||||||
|
|
||||||
flutter:
|
|
||||||
uses-material-design: true
|
|
|
@ -1,30 +0,0 @@
|
||||||
// This is a basic Flutter widget test.
|
|
||||||
//
|
|
||||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
|
||||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
|
||||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
|
||||||
// tree, read text, and verify that the values of widget properties are correct.
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
import 'package:example/main.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
|
||||||
// Build our app and trigger a frame.
|
|
||||||
await tester.pumpWidget(const MyApp());
|
|
||||||
|
|
||||||
// Verify that our counter starts at 0.
|
|
||||||
expect(find.text('0'), findsOneWidget);
|
|
||||||
expect(find.text('1'), findsNothing);
|
|
||||||
|
|
||||||
// Tap the '+' icon and trigger a frame.
|
|
||||||
await tester.tap(find.byIcon(Icons.add));
|
|
||||||
await tester.pump();
|
|
||||||
|
|
||||||
// Verify that our counter has incremented.
|
|
||||||
expect(find.text('0'), findsNothing);
|
|
||||||
expect(find.text('1'), findsOneWidget);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Iconica
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
library flutter_timetable_firebase;
|
|
||||||
|
|
||||||
export 'src/config/firebase_timetable_options.dart';
|
|
||||||
export 'src/services/firebase_timetable_service.dart';
|
|
|
@ -1,29 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Iconica
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
@immutable
|
|
||||||
class FirebaseTimetableOptions {
|
|
||||||
const FirebaseTimetableOptions({
|
|
||||||
this.timetableCollectionName = 'timetable',
|
|
||||||
this.cachingStrategy = TimetableCachingStrategy.alwaysFetch,
|
|
||||||
});
|
|
||||||
// the collection reference name
|
|
||||||
final String timetableCollectionName;
|
|
||||||
|
|
||||||
/// Changes the Firebase Timetable Service to use different caching approaches
|
|
||||||
final TimetableCachingStrategy cachingStrategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum TimetableCachingStrategy {
|
|
||||||
// Everytime the timetable is requested it will be fetched from the database
|
|
||||||
alwaysFetch,
|
|
||||||
// if you use fetchOnce the timetable events will be fetched only once
|
|
||||||
fetchOnce,
|
|
||||||
// will first be fetched and after that updates will be listened to
|
|
||||||
fetchOnceAndListen,
|
|
||||||
// if you use listen the timetable events will be updated in real time
|
|
||||||
listen,
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_timetable_firebase/src/config/firebase_timetable_options.dart';
|
|
||||||
import 'package:flutter_timetable_interface/flutter_timetable_interface.dart';
|
|
||||||
|
|
||||||
class FirebaseTimetableService<Event extends TimetableEvent>
|
|
||||||
with ChangeNotifier
|
|
||||||
implements TimetableService<Event> {
|
|
||||||
FirebaseTimetableService({
|
|
||||||
FirebaseApp? app,
|
|
||||||
options = const FirebaseTimetableOptions(),
|
|
||||||
}) {
|
|
||||||
var appInstance = app ?? Firebase.app();
|
|
||||||
_db = FirebaseFirestore.instanceFor(app: appInstance);
|
|
||||||
_options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
late FirebaseTimetableOptions _options;
|
|
||||||
late FirebaseFirestore _db;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> addEvent(Event event) async {
|
|
||||||
event.toJson();
|
|
||||||
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> checkForConflict(Event event, DateTime day) async {
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteEvent(Event event) async {
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Event>> fetchEventsForDay(DateTime day,
|
|
||||||
{String? category}) async {
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Event> getEventsForDay(DateTime day, {String? category}) {
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> updateEvent(Event event) async {
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: 2023 Iconica
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
name: flutter_timetable_firebase
|
|
||||||
description: A new Flutter package project.
|
|
||||||
version: 2.0.0
|
|
||||||
repository: https://github.com/Iconica-Development/flutter_timetable
|
|
||||||
|
|
||||||
publish_to: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: ">=3.1.0 <4.0.0"
|
|
||||||
flutter: ">=1.17.0"
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
cloud_firestore: ^4.13.3
|
|
||||||
firebase_core: ^2.24.0
|
|
||||||
flutter:
|
|
||||||
sdk: flutter
|
|
||||||
flutter_timetable_interface:
|
|
||||||
hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
|
||||||
version: ^2.0.0
|
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
|
||||||
flutter_lints: ^2.0.0
|
|
|
@ -1 +0,0 @@
|
||||||
../../CHANGELOG.md
|
|
|
@ -1 +0,0 @@
|
||||||
../../LICENSE
|
|
|
@ -1 +0,0 @@
|
||||||
../../README.md
|
|
|
@ -1,4 +0,0 @@
|
||||||
include: package:flutter_lints/flutter.yaml
|
|
||||||
|
|
||||||
# Additional information about this file can be found at
|
|
||||||
# https://dart.dev/guides/language/analysis-options
|
|
|
@ -1,8 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Iconica
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
library flutter_timetable_interface;
|
|
||||||
|
|
||||||
export 'src/models/timetable_event.dart';
|
|
||||||
export 'src/services/timetable_service.dart';
|
|
|
@ -1,45 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Iconica
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
@immutable
|
|
||||||
class TimetableEvent {
|
|
||||||
/// The model used for a [Block] in a [TimeTable] which can contain a Widget.
|
|
||||||
const TimetableEvent({
|
|
||||||
required this.start,
|
|
||||||
required this.end,
|
|
||||||
required this.entityId,
|
|
||||||
required this.eventId,
|
|
||||||
this.category,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// The date at which the event starts
|
|
||||||
final DateTime start;
|
|
||||||
|
|
||||||
/// The date at which the event ends
|
|
||||||
final DateTime end;
|
|
||||||
|
|
||||||
/// The unique identifier of the event
|
|
||||||
/// This is used to store the events
|
|
||||||
final String eventId;
|
|
||||||
|
|
||||||
/// The identifier of the entity that the event belongs to
|
|
||||||
/// This is used to check for conflicts between entities
|
|
||||||
final String entityId;
|
|
||||||
|
|
||||||
/// This can be used to filter events
|
|
||||||
final String? category;
|
|
||||||
|
|
||||||
// tojson method and a factory fromJson contructor
|
|
||||||
Map<String, dynamic> toJson() => {};
|
|
||||||
|
|
||||||
factory TimetableEvent.fromJson(String eventId, Map<String, dynamic> json) =>
|
|
||||||
TimetableEvent(
|
|
||||||
start: json['start'],
|
|
||||||
end: json['end'],
|
|
||||||
entityId: json[''],
|
|
||||||
eventId: eventId,
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
abstract class TimetableService<Event> with ChangeNotifier {
|
|
||||||
Future<List<Event>> fetchEventsForDay(DateTime day, {String? category});
|
|
||||||
List<Event> getEventsForDay(DateTime day, {String? category});
|
|
||||||
Future<void> addEvent(Event event);
|
|
||||||
Future<void> updateEvent(Event event);
|
|
||||||
Future<void> deleteEvent(Event event);
|
|
||||||
Future<bool> checkForConflict(Event event, DateTime day);
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: 2023 Iconica
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
name: flutter_timetable_interface
|
|
||||||
description: A new Flutter package project.
|
|
||||||
version: 2.0.0
|
|
||||||
repository: https://github.com/Iconica-Development/flutter_timetable
|
|
||||||
|
|
||||||
publish_to: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: ">=3.1.0 <4.0.0"
|
|
||||||
flutter: ">=1.17.0"
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
flutter:
|
|
||||||
sdk: flutter
|
|
||||||
|
|
||||||
dev_dependencies:
|
|
||||||
flutter_lints: ^2.0.0
|
|
|
@ -1 +0,0 @@
|
||||||
../../CHANGELOG.md
|
|
|
@ -1 +0,0 @@
|
||||||
../../LICENSE
|
|
|
@ -1 +0,0 @@
|
||||||
../../README.md
|
|
|
@ -1,22 +0,0 @@
|
||||||
name: flutter_timetable_view
|
|
||||||
description: Flutter package to create a Timetable Widget that display blocks of widgets inside a timetable.
|
|
||||||
version: 2.0.0
|
|
||||||
repository: https://github.com/Iconica-Development/flutter_timetable
|
|
||||||
|
|
||||||
publish_to: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: ">=3.2.0 <4.0.0"
|
|
||||||
flutter: ">=1.17.0"
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
flutter:
|
|
||||||
sdk: flutter
|
|
||||||
flutter_timetable_interface:
|
|
||||||
hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
|
||||||
version: ^2.0.0
|
|
||||||
|
|
||||||
dev_dependencies:
|
|
||||||
flutter_test:
|
|
||||||
sdk: flutter
|
|
||||||
flutter_lints: ^2.0.0
|
|
19
pubspec.yaml
19
pubspec.yaml
|
@ -1,6 +1,19 @@
|
||||||
name: flutter_timetable_workspace
|
name: flutter_timetable
|
||||||
|
description: Flutter package to create a Timetable Widget that display blocks of widgets inside a timetable.
|
||||||
|
version: 1.3.0
|
||||||
|
repository: https://github.com/Iconica-Development/timetable
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.1.0 <4.0.0'
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
|
flutter: ">=1.17.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
melos: ^3.0.1
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
flutter_lints: ^2.0.0
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:flutter_timetable_view/src/block_service.dart';
|
import 'package:flutter_timetable/src/block_service.dart';
|
||||||
import 'package:flutter_timetable_view/src/models/time_block.dart';
|
import 'package:flutter_timetable/timetable.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('test combineBlocksWithId', () {
|
group('test combineBlocksWithId', () {
|
Loading…
Reference in a new issue