diff --git a/lib/app.dart b/lib/app.dart index 4e85e0e..f270c3f 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,8 +1,10 @@ -import 'package:academia/features/auth/cubit/auth_cubit.dart'; +import 'package:academia/database/database.dart'; +import 'package:academia/features/features.dart'; import 'package:academia/utils/router/router.dart'; import 'package:flutter/material.dart'; import 'package:dynamic_color/dynamic_color.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:get_it/get_it.dart'; import 'package:google_fonts/google_fonts.dart'; class Academia extends StatelessWidget { @@ -14,9 +16,16 @@ class Academia extends StatelessWidget { @override Widget build(BuildContext context) { + // Inject the application database + GetIt.instance.registerSingletonIfAbsent( + () => AppDatabase(), + instanceName: "cacheDB", + ); return MultiBlocProvider( providers: [ BlocProvider(create: (_) => AuthCubit()), + BlocProvider(create: (_) => ProfileCubit()), + BlocProvider(create: (_) => CourseCubit()), ], child: DynamicColorBuilder( builder: (lightscheme, darkscheme) => MaterialApp.router( diff --git a/lib/database/database.dart b/lib/database/database.dart index a3a42fc..adb2caf 100644 --- a/lib/database/database.dart +++ b/lib/database/database.dart @@ -3,6 +3,8 @@ import 'dart:io'; import 'package:academia/features/auth/models/user.dart'; import 'package:academia/features/auth/models/user_credentials.dart'; import 'package:academia/features/auth/models/user_profile.dart'; +import 'package:academia/features/courses/models/course.dart'; +import 'package:academia/features/todo/models/todo.dart'; import 'package:drift/drift.dart'; import 'package:drift/native.dart'; import 'package:drift_flutter/drift_flutter.dart'; @@ -43,7 +45,13 @@ Future _getDatabaseDirectory() async { } } -@DriftDatabase(tables: [User, UserProfile, UserCredential]) +@DriftDatabase(tables: [ + User, + UserProfile, + UserCredential, + Course, + Todo, +]) class AppDatabase extends _$AppDatabase { // After generating code, this class needs to define a schemaVersion getter // and a constructor telling drift where the database should be stored. @@ -61,20 +69,3 @@ class AppDatabase extends _$AppDatabase { return driftDatabase(name: 'academia'); } } - -/// A singleton class to reference the local database. -/// Use this instead of AppDatabase to ensure you always -/// have an initialized instance -final class LocalDatabase { - static final LocalDatabase _instance = LocalDatabase._internal(); - - LocalDatabase._internal(); - - factory LocalDatabase() { - return _instance; - } - - AppDatabase getInstance() { - return AppDatabase(); - } -} diff --git a/lib/database/database.g.dart b/lib/database/database.g.dart index 4083e81..21ecb0c 100644 --- a/lib/database/database.g.dart +++ b/lib/database/database.g.dart @@ -579,15 +579,6 @@ class $UserProfileTable extends UserProfile final GeneratedDatabase attachedDatabase; final String? _alias; $UserProfileTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - hasAutoIncrement: true, - type: DriftSqlType.int, - requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); @override late final GeneratedColumn userId = GeneratedColumn( @@ -660,7 +651,6 @@ class $UserProfileTable extends UserProfile type: DriftSqlType.dateTime, requiredDuringInsert: true); @override List get $columns => [ - id, userId, bio, vibePoints, @@ -682,9 +672,6 @@ class $UserProfileTable extends UserProfile {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } if (data.containsKey('user_id')) { context.handle(_userIdMeta, userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); @@ -743,13 +730,11 @@ class $UserProfileTable extends UserProfile } @override - Set get $primaryKey => {id}; + Set get $primaryKey => {userId}; @override UserProfileData map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; return UserProfileData( - id: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}id'])!, userId: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, bio: attachedDatabase.typeMapping @@ -780,7 +765,6 @@ class $UserProfileTable extends UserProfile } class UserProfileData extends DataClass implements Insertable { - final int id; final String userId; final String? bio; final int vibePoints; @@ -792,8 +776,7 @@ class UserProfileData extends DataClass implements Insertable { final String campus; final DateTime dateOfBirth; const UserProfileData( - {required this.id, - required this.userId, + {required this.userId, this.bio, required this.vibePoints, this.profilePictureUrl, @@ -806,7 +789,6 @@ class UserProfileData extends DataClass implements Insertable { @override Map toColumns(bool nullToAbsent) { final map = {}; - map['id'] = Variable(id); map['user_id'] = Variable(userId); if (!nullToAbsent || bio != null) { map['bio'] = Variable(bio); @@ -828,7 +810,6 @@ class UserProfileData extends DataClass implements Insertable { UserProfileCompanion toCompanion(bool nullToAbsent) { return UserProfileCompanion( - id: Value(id), userId: Value(userId), bio: bio == null && nullToAbsent ? const Value.absent() : Value(bio), vibePoints: Value(vibePoints), @@ -850,7 +831,6 @@ class UserProfileData extends DataClass implements Insertable { {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return UserProfileData( - id: serializer.fromJson(json['id']), userId: serializer.fromJson(json['user_id']), bio: serializer.fromJson(json['bio']), vibePoints: serializer.fromJson(json['vibe_points']), @@ -868,7 +848,6 @@ class UserProfileData extends DataClass implements Insertable { Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'id': serializer.toJson(id), 'user_id': serializer.toJson(userId), 'bio': serializer.toJson(bio), 'vibe_points': serializer.toJson(vibePoints), @@ -883,8 +862,7 @@ class UserProfileData extends DataClass implements Insertable { } UserProfileData copyWith( - {int? id, - String? userId, + {String? userId, Value bio = const Value.absent(), int? vibePoints, Value profilePictureUrl = const Value.absent(), @@ -895,7 +873,6 @@ class UserProfileData extends DataClass implements Insertable { String? campus, DateTime? dateOfBirth}) => UserProfileData( - id: id ?? this.id, userId: userId ?? this.userId, bio: bio.present ? bio.value : this.bio, vibePoints: vibePoints ?? this.vibePoints, @@ -913,7 +890,6 @@ class UserProfileData extends DataClass implements Insertable { ); UserProfileData copyWithCompanion(UserProfileCompanion data) { return UserProfileData( - id: data.id.present ? data.id.value : this.id, userId: data.userId.present ? data.userId.value : this.userId, bio: data.bio.present ? data.bio.value : this.bio, vibePoints: @@ -937,7 +913,6 @@ class UserProfileData extends DataClass implements Insertable { @override String toString() { return (StringBuffer('UserProfileData(') - ..write('id: $id, ') ..write('userId: $userId, ') ..write('bio: $bio, ') ..write('vibePoints: $vibePoints, ') @@ -953,23 +928,12 @@ class UserProfileData extends DataClass implements Insertable { } @override - int get hashCode => Object.hash( - id, - userId, - bio, - vibePoints, - profilePictureUrl, - lastSeen, - createdAt, - modifiedAt, - admissionNumber, - campus, - dateOfBirth); + int get hashCode => Object.hash(userId, bio, vibePoints, profilePictureUrl, + lastSeen, createdAt, modifiedAt, admissionNumber, campus, dateOfBirth); @override bool operator ==(Object other) => identical(this, other) || (other is UserProfileData && - other.id == this.id && other.userId == this.userId && other.bio == this.bio && other.vibePoints == this.vibePoints && @@ -983,7 +947,6 @@ class UserProfileData extends DataClass implements Insertable { } class UserProfileCompanion extends UpdateCompanion { - final Value id; final Value userId; final Value bio; final Value vibePoints; @@ -994,8 +957,8 @@ class UserProfileCompanion extends UpdateCompanion { final Value admissionNumber; final Value campus; final Value dateOfBirth; + final Value rowid; const UserProfileCompanion({ - this.id = const Value.absent(), this.userId = const Value.absent(), this.bio = const Value.absent(), this.vibePoints = const Value.absent(), @@ -1006,9 +969,9 @@ class UserProfileCompanion extends UpdateCompanion { this.admissionNumber = const Value.absent(), this.campus = const Value.absent(), this.dateOfBirth = const Value.absent(), + this.rowid = const Value.absent(), }); UserProfileCompanion.insert({ - this.id = const Value.absent(), required String userId, this.bio = const Value.absent(), this.vibePoints = const Value.absent(), @@ -1019,10 +982,10 @@ class UserProfileCompanion extends UpdateCompanion { this.admissionNumber = const Value.absent(), this.campus = const Value.absent(), required DateTime dateOfBirth, + this.rowid = const Value.absent(), }) : userId = Value(userId), dateOfBirth = Value(dateOfBirth); static Insertable custom({ - Expression? id, Expression? userId, Expression? bio, Expression? vibePoints, @@ -1033,9 +996,9 @@ class UserProfileCompanion extends UpdateCompanion { Expression? admissionNumber, Expression? campus, Expression? dateOfBirth, + Expression? rowid, }) { return RawValuesInsertable({ - if (id != null) 'id': id, if (userId != null) 'user_id': userId, if (bio != null) 'bio': bio, if (vibePoints != null) 'vibe_points': vibePoints, @@ -1046,12 +1009,12 @@ class UserProfileCompanion extends UpdateCompanion { if (admissionNumber != null) 'admission_number': admissionNumber, if (campus != null) 'campus': campus, if (dateOfBirth != null) 'date_of_birth': dateOfBirth, + if (rowid != null) 'rowid': rowid, }); } UserProfileCompanion copyWith( - {Value? id, - Value? userId, + {Value? userId, Value? bio, Value? vibePoints, Value? profilePictureUrl, @@ -1060,9 +1023,9 @@ class UserProfileCompanion extends UpdateCompanion { Value? modifiedAt, Value? admissionNumber, Value? campus, - Value? dateOfBirth}) { + Value? dateOfBirth, + Value? rowid}) { return UserProfileCompanion( - id: id ?? this.id, userId: userId ?? this.userId, bio: bio ?? this.bio, vibePoints: vibePoints ?? this.vibePoints, @@ -1073,15 +1036,13 @@ class UserProfileCompanion extends UpdateCompanion { admissionNumber: admissionNumber ?? this.admissionNumber, campus: campus ?? this.campus, dateOfBirth: dateOfBirth ?? this.dateOfBirth, + rowid: rowid ?? this.rowid, ); } @override Map toColumns(bool nullToAbsent) { final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } if (userId.present) { map['user_id'] = Variable(userId.value); } @@ -1112,13 +1073,15 @@ class UserProfileCompanion extends UpdateCompanion { if (dateOfBirth.present) { map['date_of_birth'] = Variable(dateOfBirth.value); } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } return map; } @override String toString() { return (StringBuffer('UserProfileCompanion(') - ..write('id: $id, ') ..write('userId: $userId, ') ..write('bio: $bio, ') ..write('vibePoints: $vibePoints, ') @@ -1128,7 +1091,8 @@ class UserProfileCompanion extends UpdateCompanion { ..write('modifiedAt: $modifiedAt, ') ..write('admissionNumber: $admissionNumber, ') ..write('campus: $campus, ') - ..write('dateOfBirth: $dateOfBirth') + ..write('dateOfBirth: $dateOfBirth, ') + ..write('rowid: $rowid') ..write(')')) .toString(); } @@ -1532,452 +1496,2630 @@ class UserCredentialCompanion extends UpdateCompanion { } } -abstract class _$AppDatabase extends GeneratedDatabase { - _$AppDatabase(QueryExecutor e) : super(e); - $AppDatabaseManager get managers => $AppDatabaseManager(this); - late final $UserTable user = $UserTable(this); - late final $UserProfileTable userProfile = $UserProfileTable(this); - late final $UserCredentialTable userCredential = $UserCredentialTable(this); +class $CourseTable extends Course with TableInfo<$CourseTable, CourseData> { @override - Iterable> get allTables => - allSchemaEntities.whereType>(); + final GeneratedDatabase attachedDatabase; + final String? _alias; + $CourseTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _unitMeta = const VerificationMeta('unit'); @override - List get allSchemaEntities => - [user, userProfile, userCredential]; + late final GeneratedColumn unit = GeneratedColumn( + 'unit', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _userMeta = const VerificationMeta('user'); @override - DriftDatabaseOptions get options => - const DriftDatabaseOptions(storeDateTimeAsText: true); -} - -typedef $$UserTableCreateCompanionBuilder = UserCompanion Function({ - required String id, - required String username, - required String firstname, - Value othernames, - required String phone, - Value email, - required String gender, - Value active, - required DateTime createdAt, - required DateTime modifiedAt, - required String nationalId, - Value rowid, -}); -typedef $$UserTableUpdateCompanionBuilder = UserCompanion Function({ - Value id, - Value username, - Value firstname, - Value othernames, - Value phone, - Value email, - Value gender, - Value active, - Value createdAt, - Value modifiedAt, - Value nationalId, - Value rowid, -}); - -final class $$UserTableReferences - extends BaseReferences<_$AppDatabase, $UserTable, UserData> { - $$UserTableReferences(super.$_db, super.$_table, super.$_typedResult); - - static MultiTypedResultKey<$UserProfileTable, List> - _userProfileRefsTable(_$AppDatabase db) => MultiTypedResultKey.fromTable( - db.userProfile, - aliasName: $_aliasNameGenerator(db.user.id, db.userProfile.userId)); + late final GeneratedColumn user = GeneratedColumn( + 'user', aliasedName, true, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('REFERENCES user (id)')); + static const VerificationMeta _sectionMeta = + const VerificationMeta('section'); + @override + late final GeneratedColumn section = GeneratedColumn( + 'section', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _weekDayMeta = + const VerificationMeta('weekDay'); + @override + late final GeneratedColumn weekDay = GeneratedColumn( + 'week_day', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _campusMeta = const VerificationMeta('campus'); + @override + late final GeneratedColumn campus = GeneratedColumn( + 'campus', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _roomMeta = const VerificationMeta('room'); + @override + late final GeneratedColumn room = GeneratedColumn( + 'room', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _lecturerMeta = + const VerificationMeta('lecturer'); + @override + late final GeneratedColumn lecturer = GeneratedColumn( + 'lecturer', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _periodMeta = const VerificationMeta('period'); + @override + late final GeneratedColumn period = GeneratedColumn( + 'period', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _colorMeta = const VerificationMeta('color'); + @override + late final GeneratedColumn color = GeneratedColumn( + 'color', aliasedName, true, + type: DriftSqlType.int, requiredDuringInsert: false); + static const VerificationMeta _createdAtMeta = + const VerificationMeta('createdAt'); + @override + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', aliasedName, true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: Constant(DateTime.now())); + @override + List get $columns => [ + unit, + user, + section, + weekDay, + campus, + room, + lecturer, + period, + color, + createdAt + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'course'; + @override + VerificationContext validateIntegrity(Insertable instance, + {bool isInserting = false}) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('unit')) { + context.handle( + _unitMeta, unit.isAcceptableOrUnknown(data['unit']!, _unitMeta)); + } else if (isInserting) { + context.missing(_unitMeta); + } + if (data.containsKey('user')) { + context.handle( + _userMeta, user.isAcceptableOrUnknown(data['user']!, _userMeta)); + } + if (data.containsKey('section')) { + context.handle(_sectionMeta, + section.isAcceptableOrUnknown(data['section']!, _sectionMeta)); + } else if (isInserting) { + context.missing(_sectionMeta); + } + if (data.containsKey('week_day')) { + context.handle(_weekDayMeta, + weekDay.isAcceptableOrUnknown(data['week_day']!, _weekDayMeta)); + } else if (isInserting) { + context.missing(_weekDayMeta); + } + if (data.containsKey('campus')) { + context.handle(_campusMeta, + campus.isAcceptableOrUnknown(data['campus']!, _campusMeta)); + } else if (isInserting) { + context.missing(_campusMeta); + } + if (data.containsKey('room')) { + context.handle( + _roomMeta, room.isAcceptableOrUnknown(data['room']!, _roomMeta)); + } else if (isInserting) { + context.missing(_roomMeta); + } + if (data.containsKey('lecturer')) { + context.handle(_lecturerMeta, + lecturer.isAcceptableOrUnknown(data['lecturer']!, _lecturerMeta)); + } else if (isInserting) { + context.missing(_lecturerMeta); + } + if (data.containsKey('period')) { + context.handle(_periodMeta, + period.isAcceptableOrUnknown(data['period']!, _periodMeta)); + } else if (isInserting) { + context.missing(_periodMeta); + } + if (data.containsKey('color')) { + context.handle( + _colorMeta, color.isAcceptableOrUnknown(data['color']!, _colorMeta)); + } + if (data.containsKey('created_at')) { + context.handle(_createdAtMeta, + createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); + } + return context; + } - $$UserProfileTableProcessedTableManager get userProfileRefs { - final manager = $$UserProfileTableTableManager($_db, $_db.userProfile) - .filter((f) => f.userId.id($_item.id)); + @override + Set get $primaryKey => {unit}; + @override + CourseData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return CourseData( + unit: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}unit'])!, + user: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}user']), + section: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}section'])!, + weekDay: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}week_day'])!, + campus: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}campus'])!, + room: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}room'])!, + lecturer: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}lecturer'])!, + period: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}period'])!, + color: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}color']), + createdAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at']), + ); + } - final cache = $_typedResult.readTableOrNull(_userProfileRefsTable($_db)); - return ProcessedTableManager( - manager.$state.copyWith(prefetchedData: cache)); + @override + $CourseTable createAlias(String alias) { + return $CourseTable(attachedDatabase, alias); } } -class $$UserTableFilterComposer extends Composer<_$AppDatabase, $UserTable> { - $$UserTableFilterComposer({ - required super.$db, - required super.$table, - super.joinBuilder, - super.$addJoinBuilderToRootComposer, - super.$removeJoinBuilderFromRootComposer, - }); - ColumnFilters get id => $composableBuilder( - column: $table.id, builder: (column) => ColumnFilters(column)); - - ColumnFilters get username => $composableBuilder( - column: $table.username, builder: (column) => ColumnFilters(column)); +class CourseData extends DataClass implements Insertable { + final String unit; + final String? user; + final String section; + final String weekDay; + final String campus; + final String room; + final String lecturer; + final String period; + final int? color; + final DateTime? createdAt; + const CourseData( + {required this.unit, + this.user, + required this.section, + required this.weekDay, + required this.campus, + required this.room, + required this.lecturer, + required this.period, + this.color, + this.createdAt}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['unit'] = Variable(unit); + if (!nullToAbsent || user != null) { + map['user'] = Variable(user); + } + map['section'] = Variable(section); + map['week_day'] = Variable(weekDay); + map['campus'] = Variable(campus); + map['room'] = Variable(room); + map['lecturer'] = Variable(lecturer); + map['period'] = Variable(period); + if (!nullToAbsent || color != null) { + map['color'] = Variable(color); + } + if (!nullToAbsent || createdAt != null) { + map['created_at'] = Variable(createdAt); + } + return map; + } - ColumnFilters get firstname => $composableBuilder( - column: $table.firstname, builder: (column) => ColumnFilters(column)); + CourseCompanion toCompanion(bool nullToAbsent) { + return CourseCompanion( + unit: Value(unit), + user: user == null && nullToAbsent ? const Value.absent() : Value(user), + section: Value(section), + weekDay: Value(weekDay), + campus: Value(campus), + room: Value(room), + lecturer: Value(lecturer), + period: Value(period), + color: + color == null && nullToAbsent ? const Value.absent() : Value(color), + createdAt: createdAt == null && nullToAbsent + ? const Value.absent() + : Value(createdAt), + ); + } - ColumnFilters get othernames => $composableBuilder( - column: $table.othernames, builder: (column) => ColumnFilters(column)); + factory CourseData.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return CourseData( + unit: serializer.fromJson(json['unit']), + user: serializer.fromJson(json['user']), + section: serializer.fromJson(json['section']), + weekDay: serializer.fromJson(json['day_of_the_week']), + campus: serializer.fromJson(json['campus']), + room: serializer.fromJson(json['room']), + lecturer: serializer.fromJson(json['lecturer']), + period: serializer.fromJson(json['period']), + color: serializer.fromJson(json['color']), + createdAt: serializer.fromJson(json['created_at']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'unit': serializer.toJson(unit), + 'user': serializer.toJson(user), + 'section': serializer.toJson(section), + 'day_of_the_week': serializer.toJson(weekDay), + 'campus': serializer.toJson(campus), + 'room': serializer.toJson(room), + 'lecturer': serializer.toJson(lecturer), + 'period': serializer.toJson(period), + 'color': serializer.toJson(color), + 'created_at': serializer.toJson(createdAt), + }; + } - ColumnFilters get phone => $composableBuilder( - column: $table.phone, builder: (column) => ColumnFilters(column)); + CourseData copyWith( + {String? unit, + Value user = const Value.absent(), + String? section, + String? weekDay, + String? campus, + String? room, + String? lecturer, + String? period, + Value color = const Value.absent(), + Value createdAt = const Value.absent()}) => + CourseData( + unit: unit ?? this.unit, + user: user.present ? user.value : this.user, + section: section ?? this.section, + weekDay: weekDay ?? this.weekDay, + campus: campus ?? this.campus, + room: room ?? this.room, + lecturer: lecturer ?? this.lecturer, + period: period ?? this.period, + color: color.present ? color.value : this.color, + createdAt: createdAt.present ? createdAt.value : this.createdAt, + ); + CourseData copyWithCompanion(CourseCompanion data) { + return CourseData( + unit: data.unit.present ? data.unit.value : this.unit, + user: data.user.present ? data.user.value : this.user, + section: data.section.present ? data.section.value : this.section, + weekDay: data.weekDay.present ? data.weekDay.value : this.weekDay, + campus: data.campus.present ? data.campus.value : this.campus, + room: data.room.present ? data.room.value : this.room, + lecturer: data.lecturer.present ? data.lecturer.value : this.lecturer, + period: data.period.present ? data.period.value : this.period, + color: data.color.present ? data.color.value : this.color, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } - ColumnFilters get email => $composableBuilder( - column: $table.email, builder: (column) => ColumnFilters(column)); + @override + String toString() { + return (StringBuffer('CourseData(') + ..write('unit: $unit, ') + ..write('user: $user, ') + ..write('section: $section, ') + ..write('weekDay: $weekDay, ') + ..write('campus: $campus, ') + ..write('room: $room, ') + ..write('lecturer: $lecturer, ') + ..write('period: $period, ') + ..write('color: $color, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } - ColumnFilters get gender => $composableBuilder( - column: $table.gender, builder: (column) => ColumnFilters(column)); + @override + int get hashCode => Object.hash(unit, user, section, weekDay, campus, room, + lecturer, period, color, createdAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is CourseData && + other.unit == this.unit && + other.user == this.user && + other.section == this.section && + other.weekDay == this.weekDay && + other.campus == this.campus && + other.room == this.room && + other.lecturer == this.lecturer && + other.period == this.period && + other.color == this.color && + other.createdAt == this.createdAt); +} - ColumnFilters get active => $composableBuilder( - column: $table.active, builder: (column) => ColumnFilters(column)); +class CourseCompanion extends UpdateCompanion { + final Value unit; + final Value user; + final Value section; + final Value weekDay; + final Value campus; + final Value room; + final Value lecturer; + final Value period; + final Value color; + final Value createdAt; + final Value rowid; + const CourseCompanion({ + this.unit = const Value.absent(), + this.user = const Value.absent(), + this.section = const Value.absent(), + this.weekDay = const Value.absent(), + this.campus = const Value.absent(), + this.room = const Value.absent(), + this.lecturer = const Value.absent(), + this.period = const Value.absent(), + this.color = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }); + CourseCompanion.insert({ + required String unit, + this.user = const Value.absent(), + required String section, + required String weekDay, + required String campus, + required String room, + required String lecturer, + required String period, + this.color = const Value.absent(), + this.createdAt = const Value.absent(), + this.rowid = const Value.absent(), + }) : unit = Value(unit), + section = Value(section), + weekDay = Value(weekDay), + campus = Value(campus), + room = Value(room), + lecturer = Value(lecturer), + period = Value(period); + static Insertable custom({ + Expression? unit, + Expression? user, + Expression? section, + Expression? weekDay, + Expression? campus, + Expression? room, + Expression? lecturer, + Expression? period, + Expression? color, + Expression? createdAt, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (unit != null) 'unit': unit, + if (user != null) 'user': user, + if (section != null) 'section': section, + if (weekDay != null) 'week_day': weekDay, + if (campus != null) 'campus': campus, + if (room != null) 'room': room, + if (lecturer != null) 'lecturer': lecturer, + if (period != null) 'period': period, + if (color != null) 'color': color, + if (createdAt != null) 'created_at': createdAt, + if (rowid != null) 'rowid': rowid, + }); + } + + CourseCompanion copyWith( + {Value? unit, + Value? user, + Value? section, + Value? weekDay, + Value? campus, + Value? room, + Value? lecturer, + Value? period, + Value? color, + Value? createdAt, + Value? rowid}) { + return CourseCompanion( + unit: unit ?? this.unit, + user: user ?? this.user, + section: section ?? this.section, + weekDay: weekDay ?? this.weekDay, + campus: campus ?? this.campus, + room: room ?? this.room, + lecturer: lecturer ?? this.lecturer, + period: period ?? this.period, + color: color ?? this.color, + createdAt: createdAt ?? this.createdAt, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (unit.present) { + map['unit'] = Variable(unit.value); + } + if (user.present) { + map['user'] = Variable(user.value); + } + if (section.present) { + map['section'] = Variable(section.value); + } + if (weekDay.present) { + map['week_day'] = Variable(weekDay.value); + } + if (campus.present) { + map['campus'] = Variable(campus.value); + } + if (room.present) { + map['room'] = Variable(room.value); + } + if (lecturer.present) { + map['lecturer'] = Variable(lecturer.value); + } + if (period.present) { + map['period'] = Variable(period.value); + } + if (color.present) { + map['color'] = Variable(color.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('CourseCompanion(') + ..write('unit: $unit, ') + ..write('user: $user, ') + ..write('section: $section, ') + ..write('weekDay: $weekDay, ') + ..write('campus: $campus, ') + ..write('room: $room, ') + ..write('lecturer: $lecturer, ') + ..write('period: $period, ') + ..write('color: $color, ') + ..write('createdAt: $createdAt, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class $TodoTable extends Todo with TableInfo<$TodoTable, TodoData> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $TodoTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, true, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); + @override + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: + GeneratedColumn.constraintIsAlways('REFERENCES user (id)')); + static const VerificationMeta _unitMeta = const VerificationMeta('unit'); + @override + late final GeneratedColumn unit = GeneratedColumn( + 'unit', aliasedName, true, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('REFERENCES course (unit)')); + static const VerificationMeta _titleMeta = const VerificationMeta('title'); + @override + late final GeneratedColumn title = GeneratedColumn( + 'title', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _bodyMeta = const VerificationMeta('body'); + @override + late final GeneratedColumn body = GeneratedColumn( + 'body', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _subtasksMeta = + const VerificationMeta('subtasks'); + @override + late final GeneratedColumn subtasks = GeneratedColumn( + 'subtasks', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _colorMeta = const VerificationMeta('color'); + @override + late final GeneratedColumn color = GeneratedColumn( + 'color', aliasedName, true, + type: DriftSqlType.int, requiredDuringInsert: false); + static const VerificationMeta _notifyMeta = const VerificationMeta('notify'); + @override + late final GeneratedColumn notify = GeneratedColumn( + 'notify', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("notify" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _completeMeta = + const VerificationMeta('complete'); + @override + late final GeneratedColumn complete = GeneratedColumn( + 'complete', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("complete" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _autocompleteMeta = + const VerificationMeta('autocomplete'); + @override + late final GeneratedColumn autocomplete = GeneratedColumn( + 'autocomplete', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("autocomplete" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _notifyAtMeta = + const VerificationMeta('notifyAt'); + @override + late final GeneratedColumn notifyAt = GeneratedColumn( + 'notify_at', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _duedateMeta = + const VerificationMeta('duedate'); + @override + late final GeneratedColumn duedate = GeneratedColumn( + 'duedate', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _dateCreatedMeta = + const VerificationMeta('dateCreated'); + @override + late final GeneratedColumn dateCreated = GeneratedColumn( + 'date_created', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: Constant(DateTime.now())); + static const VerificationMeta _dateModifiedMeta = + const VerificationMeta('dateModified'); + @override + late final GeneratedColumn dateModified = GeneratedColumn( + 'date_modified', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: Constant(DateTime.now())); + static const VerificationMeta _completedAtMeta = + const VerificationMeta('completedAt'); + @override + late final GeneratedColumn completedAt = GeneratedColumn( + 'completed_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: Constant(DateTime.now())); + @override + List get $columns => [ + id, + userId, + unit, + title, + body, + subtasks, + color, + notify, + complete, + autocomplete, + notifyAt, + duedate, + dateCreated, + dateModified, + completedAt + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'todo'; + @override + VerificationContext validateIntegrity(Insertable instance, + {bool isInserting = false}) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + } + if (data.containsKey('user_id')) { + context.handle(_userIdMeta, + userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta)); + } else if (isInserting) { + context.missing(_userIdMeta); + } + if (data.containsKey('unit')) { + context.handle( + _unitMeta, unit.isAcceptableOrUnknown(data['unit']!, _unitMeta)); + } + if (data.containsKey('title')) { + context.handle( + _titleMeta, title.isAcceptableOrUnknown(data['title']!, _titleMeta)); + } else if (isInserting) { + context.missing(_titleMeta); + } + if (data.containsKey('body')) { + context.handle( + _bodyMeta, body.isAcceptableOrUnknown(data['body']!, _bodyMeta)); + } else if (isInserting) { + context.missing(_bodyMeta); + } + if (data.containsKey('subtasks')) { + context.handle(_subtasksMeta, + subtasks.isAcceptableOrUnknown(data['subtasks']!, _subtasksMeta)); + } + if (data.containsKey('color')) { + context.handle( + _colorMeta, color.isAcceptableOrUnknown(data['color']!, _colorMeta)); + } + if (data.containsKey('notify')) { + context.handle(_notifyMeta, + notify.isAcceptableOrUnknown(data['notify']!, _notifyMeta)); + } + if (data.containsKey('complete')) { + context.handle(_completeMeta, + complete.isAcceptableOrUnknown(data['complete']!, _completeMeta)); + } + if (data.containsKey('autocomplete')) { + context.handle( + _autocompleteMeta, + autocomplete.isAcceptableOrUnknown( + data['autocomplete']!, _autocompleteMeta)); + } + if (data.containsKey('notify_at')) { + context.handle(_notifyAtMeta, + notifyAt.isAcceptableOrUnknown(data['notify_at']!, _notifyAtMeta)); + } + if (data.containsKey('duedate')) { + context.handle(_duedateMeta, + duedate.isAcceptableOrUnknown(data['duedate']!, _duedateMeta)); + } + if (data.containsKey('date_created')) { + context.handle( + _dateCreatedMeta, + dateCreated.isAcceptableOrUnknown( + data['date_created']!, _dateCreatedMeta)); + } + if (data.containsKey('date_modified')) { + context.handle( + _dateModifiedMeta, + dateModified.isAcceptableOrUnknown( + data['date_modified']!, _dateModifiedMeta)); + } + if (data.containsKey('completed_at')) { + context.handle( + _completedAtMeta, + completedAt.isAcceptableOrUnknown( + data['completed_at']!, _completedAtMeta)); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + TodoData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return TodoData( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id']), + userId: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!, + unit: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}unit']), + title: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}title'])!, + body: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}body'])!, + subtasks: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}subtasks']), + color: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}color']), + notify: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}notify'])!, + complete: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}complete'])!, + autocomplete: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}autocomplete'])!, + notifyAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}notify_at']), + duedate: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}duedate']), + dateCreated: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}date_created'])!, + dateModified: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, data['${effectivePrefix}date_modified'])!, + completedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}completed_at'])!, + ); + } + + @override + $TodoTable createAlias(String alias) { + return $TodoTable(attachedDatabase, alias); + } +} + +class TodoData extends DataClass implements Insertable { + final int? id; + final String userId; + final String? unit; + final String title; + final String body; + final String? subtasks; + final int? color; + final bool notify; + final bool complete; + final bool autocomplete; + final DateTime? notifyAt; + final DateTime? duedate; + final DateTime dateCreated; + final DateTime dateModified; + final DateTime completedAt; + const TodoData( + {this.id, + required this.userId, + this.unit, + required this.title, + required this.body, + this.subtasks, + this.color, + required this.notify, + required this.complete, + required this.autocomplete, + this.notifyAt, + this.duedate, + required this.dateCreated, + required this.dateModified, + required this.completedAt}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (!nullToAbsent || id != null) { + map['id'] = Variable(id); + } + map['user_id'] = Variable(userId); + if (!nullToAbsent || unit != null) { + map['unit'] = Variable(unit); + } + map['title'] = Variable(title); + map['body'] = Variable(body); + if (!nullToAbsent || subtasks != null) { + map['subtasks'] = Variable(subtasks); + } + if (!nullToAbsent || color != null) { + map['color'] = Variable(color); + } + map['notify'] = Variable(notify); + map['complete'] = Variable(complete); + map['autocomplete'] = Variable(autocomplete); + if (!nullToAbsent || notifyAt != null) { + map['notify_at'] = Variable(notifyAt); + } + if (!nullToAbsent || duedate != null) { + map['duedate'] = Variable(duedate); + } + map['date_created'] = Variable(dateCreated); + map['date_modified'] = Variable(dateModified); + map['completed_at'] = Variable(completedAt); + return map; + } + + TodoCompanion toCompanion(bool nullToAbsent) { + return TodoCompanion( + id: id == null && nullToAbsent ? const Value.absent() : Value(id), + userId: Value(userId), + unit: unit == null && nullToAbsent ? const Value.absent() : Value(unit), + title: Value(title), + body: Value(body), + subtasks: subtasks == null && nullToAbsent + ? const Value.absent() + : Value(subtasks), + color: + color == null && nullToAbsent ? const Value.absent() : Value(color), + notify: Value(notify), + complete: Value(complete), + autocomplete: Value(autocomplete), + notifyAt: notifyAt == null && nullToAbsent + ? const Value.absent() + : Value(notifyAt), + duedate: duedate == null && nullToAbsent + ? const Value.absent() + : Value(duedate), + dateCreated: Value(dateCreated), + dateModified: Value(dateModified), + completedAt: Value(completedAt), + ); + } + + factory TodoData.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return TodoData( + id: serializer.fromJson(json['id']), + userId: serializer.fromJson(json['userId']), + unit: serializer.fromJson(json['unit']), + title: serializer.fromJson(json['title']), + body: serializer.fromJson(json['body']), + subtasks: serializer.fromJson(json['subtasks']), + color: serializer.fromJson(json['color']), + notify: serializer.fromJson(json['notify']), + complete: serializer.fromJson(json['complete']), + autocomplete: serializer.fromJson(json['autocomplete']), + notifyAt: serializer.fromJson(json['notifyAt']), + duedate: serializer.fromJson(json['duedate']), + dateCreated: serializer.fromJson(json['dateCreated']), + dateModified: serializer.fromJson(json['dateModified']), + completedAt: serializer.fromJson(json['completedAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'userId': serializer.toJson(userId), + 'unit': serializer.toJson(unit), + 'title': serializer.toJson(title), + 'body': serializer.toJson(body), + 'subtasks': serializer.toJson(subtasks), + 'color': serializer.toJson(color), + 'notify': serializer.toJson(notify), + 'complete': serializer.toJson(complete), + 'autocomplete': serializer.toJson(autocomplete), + 'notifyAt': serializer.toJson(notifyAt), + 'duedate': serializer.toJson(duedate), + 'dateCreated': serializer.toJson(dateCreated), + 'dateModified': serializer.toJson(dateModified), + 'completedAt': serializer.toJson(completedAt), + }; + } + + TodoData copyWith( + {Value id = const Value.absent(), + String? userId, + Value unit = const Value.absent(), + String? title, + String? body, + Value subtasks = const Value.absent(), + Value color = const Value.absent(), + bool? notify, + bool? complete, + bool? autocomplete, + Value notifyAt = const Value.absent(), + Value duedate = const Value.absent(), + DateTime? dateCreated, + DateTime? dateModified, + DateTime? completedAt}) => + TodoData( + id: id.present ? id.value : this.id, + userId: userId ?? this.userId, + unit: unit.present ? unit.value : this.unit, + title: title ?? this.title, + body: body ?? this.body, + subtasks: subtasks.present ? subtasks.value : this.subtasks, + color: color.present ? color.value : this.color, + notify: notify ?? this.notify, + complete: complete ?? this.complete, + autocomplete: autocomplete ?? this.autocomplete, + notifyAt: notifyAt.present ? notifyAt.value : this.notifyAt, + duedate: duedate.present ? duedate.value : this.duedate, + dateCreated: dateCreated ?? this.dateCreated, + dateModified: dateModified ?? this.dateModified, + completedAt: completedAt ?? this.completedAt, + ); + TodoData copyWithCompanion(TodoCompanion data) { + return TodoData( + id: data.id.present ? data.id.value : this.id, + userId: data.userId.present ? data.userId.value : this.userId, + unit: data.unit.present ? data.unit.value : this.unit, + title: data.title.present ? data.title.value : this.title, + body: data.body.present ? data.body.value : this.body, + subtasks: data.subtasks.present ? data.subtasks.value : this.subtasks, + color: data.color.present ? data.color.value : this.color, + notify: data.notify.present ? data.notify.value : this.notify, + complete: data.complete.present ? data.complete.value : this.complete, + autocomplete: data.autocomplete.present + ? data.autocomplete.value + : this.autocomplete, + notifyAt: data.notifyAt.present ? data.notifyAt.value : this.notifyAt, + duedate: data.duedate.present ? data.duedate.value : this.duedate, + dateCreated: + data.dateCreated.present ? data.dateCreated.value : this.dateCreated, + dateModified: data.dateModified.present + ? data.dateModified.value + : this.dateModified, + completedAt: + data.completedAt.present ? data.completedAt.value : this.completedAt, + ); + } + + @override + String toString() { + return (StringBuffer('TodoData(') + ..write('id: $id, ') + ..write('userId: $userId, ') + ..write('unit: $unit, ') + ..write('title: $title, ') + ..write('body: $body, ') + ..write('subtasks: $subtasks, ') + ..write('color: $color, ') + ..write('notify: $notify, ') + ..write('complete: $complete, ') + ..write('autocomplete: $autocomplete, ') + ..write('notifyAt: $notifyAt, ') + ..write('duedate: $duedate, ') + ..write('dateCreated: $dateCreated, ') + ..write('dateModified: $dateModified, ') + ..write('completedAt: $completedAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + userId, + unit, + title, + body, + subtasks, + color, + notify, + complete, + autocomplete, + notifyAt, + duedate, + dateCreated, + dateModified, + completedAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is TodoData && + other.id == this.id && + other.userId == this.userId && + other.unit == this.unit && + other.title == this.title && + other.body == this.body && + other.subtasks == this.subtasks && + other.color == this.color && + other.notify == this.notify && + other.complete == this.complete && + other.autocomplete == this.autocomplete && + other.notifyAt == this.notifyAt && + other.duedate == this.duedate && + other.dateCreated == this.dateCreated && + other.dateModified == this.dateModified && + other.completedAt == this.completedAt); +} + +class TodoCompanion extends UpdateCompanion { + final Value id; + final Value userId; + final Value unit; + final Value title; + final Value body; + final Value subtasks; + final Value color; + final Value notify; + final Value complete; + final Value autocomplete; + final Value notifyAt; + final Value duedate; + final Value dateCreated; + final Value dateModified; + final Value completedAt; + const TodoCompanion({ + this.id = const Value.absent(), + this.userId = const Value.absent(), + this.unit = const Value.absent(), + this.title = const Value.absent(), + this.body = const Value.absent(), + this.subtasks = const Value.absent(), + this.color = const Value.absent(), + this.notify = const Value.absent(), + this.complete = const Value.absent(), + this.autocomplete = const Value.absent(), + this.notifyAt = const Value.absent(), + this.duedate = const Value.absent(), + this.dateCreated = const Value.absent(), + this.dateModified = const Value.absent(), + this.completedAt = const Value.absent(), + }); + TodoCompanion.insert({ + this.id = const Value.absent(), + required String userId, + this.unit = const Value.absent(), + required String title, + required String body, + this.subtasks = const Value.absent(), + this.color = const Value.absent(), + this.notify = const Value.absent(), + this.complete = const Value.absent(), + this.autocomplete = const Value.absent(), + this.notifyAt = const Value.absent(), + this.duedate = const Value.absent(), + this.dateCreated = const Value.absent(), + this.dateModified = const Value.absent(), + this.completedAt = const Value.absent(), + }) : userId = Value(userId), + title = Value(title), + body = Value(body); + static Insertable custom({ + Expression? id, + Expression? userId, + Expression? unit, + Expression? title, + Expression? body, + Expression? subtasks, + Expression? color, + Expression? notify, + Expression? complete, + Expression? autocomplete, + Expression? notifyAt, + Expression? duedate, + Expression? dateCreated, + Expression? dateModified, + Expression? completedAt, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (userId != null) 'user_id': userId, + if (unit != null) 'unit': unit, + if (title != null) 'title': title, + if (body != null) 'body': body, + if (subtasks != null) 'subtasks': subtasks, + if (color != null) 'color': color, + if (notify != null) 'notify': notify, + if (complete != null) 'complete': complete, + if (autocomplete != null) 'autocomplete': autocomplete, + if (notifyAt != null) 'notify_at': notifyAt, + if (duedate != null) 'duedate': duedate, + if (dateCreated != null) 'date_created': dateCreated, + if (dateModified != null) 'date_modified': dateModified, + if (completedAt != null) 'completed_at': completedAt, + }); + } + + TodoCompanion copyWith( + {Value? id, + Value? userId, + Value? unit, + Value? title, + Value? body, + Value? subtasks, + Value? color, + Value? notify, + Value? complete, + Value? autocomplete, + Value? notifyAt, + Value? duedate, + Value? dateCreated, + Value? dateModified, + Value? completedAt}) { + return TodoCompanion( + id: id ?? this.id, + userId: userId ?? this.userId, + unit: unit ?? this.unit, + title: title ?? this.title, + body: body ?? this.body, + subtasks: subtasks ?? this.subtasks, + color: color ?? this.color, + notify: notify ?? this.notify, + complete: complete ?? this.complete, + autocomplete: autocomplete ?? this.autocomplete, + notifyAt: notifyAt ?? this.notifyAt, + duedate: duedate ?? this.duedate, + dateCreated: dateCreated ?? this.dateCreated, + dateModified: dateModified ?? this.dateModified, + completedAt: completedAt ?? this.completedAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (userId.present) { + map['user_id'] = Variable(userId.value); + } + if (unit.present) { + map['unit'] = Variable(unit.value); + } + if (title.present) { + map['title'] = Variable(title.value); + } + if (body.present) { + map['body'] = Variable(body.value); + } + if (subtasks.present) { + map['subtasks'] = Variable(subtasks.value); + } + if (color.present) { + map['color'] = Variable(color.value); + } + if (notify.present) { + map['notify'] = Variable(notify.value); + } + if (complete.present) { + map['complete'] = Variable(complete.value); + } + if (autocomplete.present) { + map['autocomplete'] = Variable(autocomplete.value); + } + if (notifyAt.present) { + map['notify_at'] = Variable(notifyAt.value); + } + if (duedate.present) { + map['duedate'] = Variable(duedate.value); + } + if (dateCreated.present) { + map['date_created'] = Variable(dateCreated.value); + } + if (dateModified.present) { + map['date_modified'] = Variable(dateModified.value); + } + if (completedAt.present) { + map['completed_at'] = Variable(completedAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('TodoCompanion(') + ..write('id: $id, ') + ..write('userId: $userId, ') + ..write('unit: $unit, ') + ..write('title: $title, ') + ..write('body: $body, ') + ..write('subtasks: $subtasks, ') + ..write('color: $color, ') + ..write('notify: $notify, ') + ..write('complete: $complete, ') + ..write('autocomplete: $autocomplete, ') + ..write('notifyAt: $notifyAt, ') + ..write('duedate: $duedate, ') + ..write('dateCreated: $dateCreated, ') + ..write('dateModified: $dateModified, ') + ..write('completedAt: $completedAt') + ..write(')')) + .toString(); + } +} + +abstract class _$AppDatabase extends GeneratedDatabase { + _$AppDatabase(QueryExecutor e) : super(e); + $AppDatabaseManager get managers => $AppDatabaseManager(this); + late final $UserTable user = $UserTable(this); + late final $UserProfileTable userProfile = $UserProfileTable(this); + late final $UserCredentialTable userCredential = $UserCredentialTable(this); + late final $CourseTable course = $CourseTable(this); + late final $TodoTable todo = $TodoTable(this); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => + [user, userProfile, userCredential, course, todo]; + @override + DriftDatabaseOptions get options => + const DriftDatabaseOptions(storeDateTimeAsText: true); +} + +typedef $$UserTableCreateCompanionBuilder = UserCompanion Function({ + required String id, + required String username, + required String firstname, + Value othernames, + required String phone, + Value email, + required String gender, + Value active, + required DateTime createdAt, + required DateTime modifiedAt, + required String nationalId, + Value rowid, +}); +typedef $$UserTableUpdateCompanionBuilder = UserCompanion Function({ + Value id, + Value username, + Value firstname, + Value othernames, + Value phone, + Value email, + Value gender, + Value active, + Value createdAt, + Value modifiedAt, + Value nationalId, + Value rowid, +}); + +final class $$UserTableReferences + extends BaseReferences<_$AppDatabase, $UserTable, UserData> { + $$UserTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static MultiTypedResultKey<$UserProfileTable, List> + _userProfileRefsTable(_$AppDatabase db) => MultiTypedResultKey.fromTable( + db.userProfile, + aliasName: $_aliasNameGenerator(db.user.id, db.userProfile.userId)); + + $$UserProfileTableProcessedTableManager get userProfileRefs { + final manager = $$UserProfileTableTableManager($_db, $_db.userProfile) + .filter((f) => f.userId.id($_item.id)); + + final cache = $_typedResult.readTableOrNull(_userProfileRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } + + static MultiTypedResultKey<$CourseTable, List> _courseRefsTable( + _$AppDatabase db) => + MultiTypedResultKey.fromTable(db.course, + aliasName: $_aliasNameGenerator(db.user.id, db.course.user)); + + $$CourseTableProcessedTableManager get courseRefs { + final manager = $$CourseTableTableManager($_db, $_db.course) + .filter((f) => f.user.id($_item.id)); + + final cache = $_typedResult.readTableOrNull(_courseRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } + + static MultiTypedResultKey<$TodoTable, List> _todoRefsTable( + _$AppDatabase db) => + MultiTypedResultKey.fromTable(db.todo, + aliasName: $_aliasNameGenerator(db.user.id, db.todo.userId)); + + $$TodoTableProcessedTableManager get todoRefs { + final manager = $$TodoTableTableManager($_db, $_db.todo) + .filter((f) => f.userId.id($_item.id)); + + final cache = $_typedResult.readTableOrNull(_todoRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } +} + +class $$UserTableFilterComposer extends Composer<_$AppDatabase, $UserTable> { + $$UserTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder( + column: $table.id, builder: (column) => ColumnFilters(column)); + + ColumnFilters get username => $composableBuilder( + column: $table.username, builder: (column) => ColumnFilters(column)); + + ColumnFilters get firstname => $composableBuilder( + column: $table.firstname, builder: (column) => ColumnFilters(column)); + + ColumnFilters get othernames => $composableBuilder( + column: $table.othernames, builder: (column) => ColumnFilters(column)); + + ColumnFilters get phone => $composableBuilder( + column: $table.phone, builder: (column) => ColumnFilters(column)); + + ColumnFilters get email => $composableBuilder( + column: $table.email, builder: (column) => ColumnFilters(column)); + + ColumnFilters get gender => $composableBuilder( + column: $table.gender, builder: (column) => ColumnFilters(column)); + + ColumnFilters get active => $composableBuilder( + column: $table.active, builder: (column) => ColumnFilters(column)); + + ColumnFilters get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get modifiedAt => $composableBuilder( + column: $table.modifiedAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get nationalId => $composableBuilder( + column: $table.nationalId, builder: (column) => ColumnFilters(column)); + + Expression userProfileRefs( + Expression Function($$UserProfileTableFilterComposer f) f) { + final $$UserProfileTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.userProfile, + getReferencedColumn: (t) => t.userId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserProfileTableFilterComposer( + $db: $db, + $table: $db.userProfile, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } + + Expression courseRefs( + Expression Function($$CourseTableFilterComposer f) f) { + final $$CourseTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.course, + getReferencedColumn: (t) => t.user, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$CourseTableFilterComposer( + $db: $db, + $table: $db.course, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } + + Expression todoRefs( + Expression Function($$TodoTableFilterComposer f) f) { + final $$TodoTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.todo, + getReferencedColumn: (t) => t.userId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$TodoTableFilterComposer( + $db: $db, + $table: $db.todo, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } +} + +class $$UserTableOrderingComposer extends Composer<_$AppDatabase, $UserTable> { + $$UserTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder( + column: $table.id, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get username => $composableBuilder( + column: $table.username, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get firstname => $composableBuilder( + column: $table.firstname, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get othernames => $composableBuilder( + column: $table.othernames, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get phone => $composableBuilder( + column: $table.phone, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get email => $composableBuilder( + column: $table.email, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get gender => $composableBuilder( + column: $table.gender, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get active => $composableBuilder( + column: $table.active, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get modifiedAt => $composableBuilder( + column: $table.modifiedAt, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get nationalId => $composableBuilder( + column: $table.nationalId, builder: (column) => ColumnOrderings(column)); +} + +class $$UserTableAnnotationComposer + extends Composer<_$AppDatabase, $UserTable> { + $$UserTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get username => + $composableBuilder(column: $table.username, builder: (column) => column); + + GeneratedColumn get firstname => + $composableBuilder(column: $table.firstname, builder: (column) => column); + + GeneratedColumn get othernames => $composableBuilder( + column: $table.othernames, builder: (column) => column); + + GeneratedColumn get phone => + $composableBuilder(column: $table.phone, builder: (column) => column); + + GeneratedColumn get email => + $composableBuilder(column: $table.email, builder: (column) => column); + + GeneratedColumn get gender => + $composableBuilder(column: $table.gender, builder: (column) => column); + + GeneratedColumn get active => + $composableBuilder(column: $table.active, builder: (column) => column); + + GeneratedColumn get createdAt => + $composableBuilder(column: $table.createdAt, builder: (column) => column); + + GeneratedColumn get modifiedAt => $composableBuilder( + column: $table.modifiedAt, builder: (column) => column); + + GeneratedColumn get nationalId => $composableBuilder( + column: $table.nationalId, builder: (column) => column); + + Expression userProfileRefs( + Expression Function($$UserProfileTableAnnotationComposer a) f) { + final $$UserProfileTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.userProfile, + getReferencedColumn: (t) => t.userId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserProfileTableAnnotationComposer( + $db: $db, + $table: $db.userProfile, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } + + Expression courseRefs( + Expression Function($$CourseTableAnnotationComposer a) f) { + final $$CourseTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.course, + getReferencedColumn: (t) => t.user, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$CourseTableAnnotationComposer( + $db: $db, + $table: $db.course, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } + + Expression todoRefs( + Expression Function($$TodoTableAnnotationComposer a) f) { + final $$TodoTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.todo, + getReferencedColumn: (t) => t.userId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$TodoTableAnnotationComposer( + $db: $db, + $table: $db.todo, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } +} + +class $$UserTableTableManager extends RootTableManager< + _$AppDatabase, + $UserTable, + UserData, + $$UserTableFilterComposer, + $$UserTableOrderingComposer, + $$UserTableAnnotationComposer, + $$UserTableCreateCompanionBuilder, + $$UserTableUpdateCompanionBuilder, + (UserData, $$UserTableReferences), + UserData, + PrefetchHooks Function( + {bool userProfileRefs, bool courseRefs, bool todoRefs})> { + $$UserTableTableManager(_$AppDatabase db, $UserTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$UserTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$UserTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$UserTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value username = const Value.absent(), + Value firstname = const Value.absent(), + Value othernames = const Value.absent(), + Value phone = const Value.absent(), + Value email = const Value.absent(), + Value gender = const Value.absent(), + Value active = const Value.absent(), + Value createdAt = const Value.absent(), + Value modifiedAt = const Value.absent(), + Value nationalId = const Value.absent(), + Value rowid = const Value.absent(), + }) => + UserCompanion( + id: id, + username: username, + firstname: firstname, + othernames: othernames, + phone: phone, + email: email, + gender: gender, + active: active, + createdAt: createdAt, + modifiedAt: modifiedAt, + nationalId: nationalId, + rowid: rowid, + ), + createCompanionCallback: ({ + required String id, + required String username, + required String firstname, + Value othernames = const Value.absent(), + required String phone, + Value email = const Value.absent(), + required String gender, + Value active = const Value.absent(), + required DateTime createdAt, + required DateTime modifiedAt, + required String nationalId, + Value rowid = const Value.absent(), + }) => + UserCompanion.insert( + id: id, + username: username, + firstname: firstname, + othernames: othernames, + phone: phone, + email: email, + gender: gender, + active: active, + createdAt: createdAt, + modifiedAt: modifiedAt, + nationalId: nationalId, + rowid: rowid, + ), + withReferenceMapper: (p0) => p0 + .map((e) => + (e.readTable(table), $$UserTableReferences(db, table, e))) + .toList(), + prefetchHooksCallback: ( + {userProfileRefs = false, courseRefs = false, todoRefs = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [ + if (userProfileRefs) db.userProfile, + if (courseRefs) db.course, + if (todoRefs) db.todo + ], + addJoins: null, + getPrefetchedDataCallback: (items) async { + return [ + if (userProfileRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: + $$UserTableReferences._userProfileRefsTable(db), + managerFromTypedResult: (p0) => + $$UserTableReferences(db, table, p0) + .userProfileRefs, + referencedItemsForCurrentItem: (item, + referencedItems) => + referencedItems.where((e) => e.userId == item.id), + typedResults: items), + if (courseRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: + $$UserTableReferences._courseRefsTable(db), + managerFromTypedResult: (p0) => + $$UserTableReferences(db, table, p0).courseRefs, + referencedItemsForCurrentItem: + (item, referencedItems) => + referencedItems.where((e) => e.user == item.id), + typedResults: items), + if (todoRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: + $$UserTableReferences._todoRefsTable(db), + managerFromTypedResult: (p0) => + $$UserTableReferences(db, table, p0).todoRefs, + referencedItemsForCurrentItem: (item, + referencedItems) => + referencedItems.where((e) => e.userId == item.id), + typedResults: items) + ]; + }, + ); + }, + )); +} + +typedef $$UserTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $UserTable, + UserData, + $$UserTableFilterComposer, + $$UserTableOrderingComposer, + $$UserTableAnnotationComposer, + $$UserTableCreateCompanionBuilder, + $$UserTableUpdateCompanionBuilder, + (UserData, $$UserTableReferences), + UserData, + PrefetchHooks Function( + {bool userProfileRefs, bool courseRefs, bool todoRefs})>; +typedef $$UserProfileTableCreateCompanionBuilder = UserProfileCompanion + Function({ + required String userId, + Value bio, + Value vibePoints, + Value profilePictureUrl, + Value lastSeen, + Value createdAt, + Value modifiedAt, + Value admissionNumber, + Value campus, + required DateTime dateOfBirth, + Value rowid, +}); +typedef $$UserProfileTableUpdateCompanionBuilder = UserProfileCompanion + Function({ + Value userId, + Value bio, + Value vibePoints, + Value profilePictureUrl, + Value lastSeen, + Value createdAt, + Value modifiedAt, + Value admissionNumber, + Value campus, + Value dateOfBirth, + Value rowid, +}); + +final class $$UserProfileTableReferences + extends BaseReferences<_$AppDatabase, $UserProfileTable, UserProfileData> { + $$UserProfileTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static $UserTable _userIdTable(_$AppDatabase db) => db.user + .createAlias($_aliasNameGenerator(db.userProfile.userId, db.user.id)); + + $$UserTableProcessedTableManager? get userId { + if ($_item.userId == null) return null; + final manager = $$UserTableTableManager($_db, $_db.user) + .filter((f) => f.id($_item.userId!)); + final item = $_typedResult.readTableOrNull(_userIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + +class $$UserProfileTableFilterComposer + extends Composer<_$AppDatabase, $UserProfileTable> { + $$UserProfileTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get bio => $composableBuilder( + column: $table.bio, builder: (column) => ColumnFilters(column)); + + ColumnFilters get vibePoints => $composableBuilder( + column: $table.vibePoints, builder: (column) => ColumnFilters(column)); + + ColumnFilters get profilePictureUrl => $composableBuilder( + column: $table.profilePictureUrl, + builder: (column) => ColumnFilters(column)); + + ColumnFilters get lastSeen => $composableBuilder( + column: $table.lastSeen, builder: (column) => ColumnFilters(column)); + + ColumnFilters get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get modifiedAt => $composableBuilder( + column: $table.modifiedAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get admissionNumber => $composableBuilder( + column: $table.admissionNumber, + builder: (column) => ColumnFilters(column)); + + ColumnFilters get campus => $composableBuilder( + column: $table.campus, builder: (column) => ColumnFilters(column)); + + ColumnFilters get dateOfBirth => $composableBuilder( + column: $table.dateOfBirth, builder: (column) => ColumnFilters(column)); + + $$UserTableFilterComposer get userId { + final $$UserTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.userId, + referencedTable: $db.user, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableFilterComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$UserProfileTableOrderingComposer + extends Composer<_$AppDatabase, $UserProfileTable> { + $$UserProfileTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get bio => $composableBuilder( + column: $table.bio, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get vibePoints => $composableBuilder( + column: $table.vibePoints, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get profilePictureUrl => $composableBuilder( + column: $table.profilePictureUrl, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get lastSeen => $composableBuilder( + column: $table.lastSeen, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get modifiedAt => $composableBuilder( + column: $table.modifiedAt, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get admissionNumber => $composableBuilder( + column: $table.admissionNumber, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get campus => $composableBuilder( + column: $table.campus, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get dateOfBirth => $composableBuilder( + column: $table.dateOfBirth, builder: (column) => ColumnOrderings(column)); + + $$UserTableOrderingComposer get userId { + final $$UserTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.userId, + referencedTable: $db.user, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableOrderingComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$UserProfileTableAnnotationComposer + extends Composer<_$AppDatabase, $UserProfileTable> { + $$UserProfileTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get bio => + $composableBuilder(column: $table.bio, builder: (column) => column); + + GeneratedColumn get vibePoints => $composableBuilder( + column: $table.vibePoints, builder: (column) => column); + + GeneratedColumn get profilePictureUrl => $composableBuilder( + column: $table.profilePictureUrl, builder: (column) => column); + + GeneratedColumn get lastSeen => + $composableBuilder(column: $table.lastSeen, builder: (column) => column); + + GeneratedColumn get createdAt => + $composableBuilder(column: $table.createdAt, builder: (column) => column); + + GeneratedColumn get modifiedAt => $composableBuilder( + column: $table.modifiedAt, builder: (column) => column); + + GeneratedColumn get admissionNumber => $composableBuilder( + column: $table.admissionNumber, builder: (column) => column); + + GeneratedColumn get campus => + $composableBuilder(column: $table.campus, builder: (column) => column); + + GeneratedColumn get dateOfBirth => $composableBuilder( + column: $table.dateOfBirth, builder: (column) => column); + + $$UserTableAnnotationComposer get userId { + final $$UserTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.userId, + referencedTable: $db.user, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableAnnotationComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$UserProfileTableTableManager extends RootTableManager< + _$AppDatabase, + $UserProfileTable, + UserProfileData, + $$UserProfileTableFilterComposer, + $$UserProfileTableOrderingComposer, + $$UserProfileTableAnnotationComposer, + $$UserProfileTableCreateCompanionBuilder, + $$UserProfileTableUpdateCompanionBuilder, + (UserProfileData, $$UserProfileTableReferences), + UserProfileData, + PrefetchHooks Function({bool userId})> { + $$UserProfileTableTableManager(_$AppDatabase db, $UserProfileTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$UserProfileTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$UserProfileTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$UserProfileTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value userId = const Value.absent(), + Value bio = const Value.absent(), + Value vibePoints = const Value.absent(), + Value profilePictureUrl = const Value.absent(), + Value lastSeen = const Value.absent(), + Value createdAt = const Value.absent(), + Value modifiedAt = const Value.absent(), + Value admissionNumber = const Value.absent(), + Value campus = const Value.absent(), + Value dateOfBirth = const Value.absent(), + Value rowid = const Value.absent(), + }) => + UserProfileCompanion( + userId: userId, + bio: bio, + vibePoints: vibePoints, + profilePictureUrl: profilePictureUrl, + lastSeen: lastSeen, + createdAt: createdAt, + modifiedAt: modifiedAt, + admissionNumber: admissionNumber, + campus: campus, + dateOfBirth: dateOfBirth, + rowid: rowid, + ), + createCompanionCallback: ({ + required String userId, + Value bio = const Value.absent(), + Value vibePoints = const Value.absent(), + Value profilePictureUrl = const Value.absent(), + Value lastSeen = const Value.absent(), + Value createdAt = const Value.absent(), + Value modifiedAt = const Value.absent(), + Value admissionNumber = const Value.absent(), + Value campus = const Value.absent(), + required DateTime dateOfBirth, + Value rowid = const Value.absent(), + }) => + UserProfileCompanion.insert( + userId: userId, + bio: bio, + vibePoints: vibePoints, + profilePictureUrl: profilePictureUrl, + lastSeen: lastSeen, + createdAt: createdAt, + modifiedAt: modifiedAt, + admissionNumber: admissionNumber, + campus: campus, + dateOfBirth: dateOfBirth, + rowid: rowid, + ), + withReferenceMapper: (p0) => p0 + .map((e) => ( + e.readTable(table), + $$UserProfileTableReferences(db, table, e) + )) + .toList(), + prefetchHooksCallback: ({userId = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [], + addJoins: < + T extends TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic>>(state) { + if (userId) { + state = state.withJoin( + currentTable: table, + currentColumn: table.userId, + referencedTable: + $$UserProfileTableReferences._userIdTable(db), + referencedColumn: + $$UserProfileTableReferences._userIdTable(db).id, + ) as T; + } + + return state; + }, + getPrefetchedDataCallback: (items) async { + return []; + }, + ); + }, + )); +} + +typedef $$UserProfileTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $UserProfileTable, + UserProfileData, + $$UserProfileTableFilterComposer, + $$UserProfileTableOrderingComposer, + $$UserProfileTableAnnotationComposer, + $$UserProfileTableCreateCompanionBuilder, + $$UserProfileTableUpdateCompanionBuilder, + (UserProfileData, $$UserProfileTableReferences), + UserProfileData, + PrefetchHooks Function({bool userId})>; +typedef $$UserCredentialTableCreateCompanionBuilder = UserCredentialCompanion + Function({ + Value userId, + required String admno, + Value accessToken, + required String username, + required String email, + required String password, + Value lastLogin, + Value rowid, +}); +typedef $$UserCredentialTableUpdateCompanionBuilder = UserCredentialCompanion + Function({ + Value userId, + Value admno, + Value accessToken, + Value username, + Value email, + Value password, + Value lastLogin, + Value rowid, +}); + +final class $$UserCredentialTableReferences extends BaseReferences< + _$AppDatabase, $UserCredentialTable, UserCredentialData> { + $$UserCredentialTableReferences( + super.$_db, super.$_table, super.$_typedResult); + + static $UserTable _userIdTable(_$AppDatabase db) => db.user + .createAlias($_aliasNameGenerator(db.userCredential.userId, db.user.id)); + + $$UserTableProcessedTableManager? get userId { + if ($_item.userId == null) return null; + final manager = $$UserTableTableManager($_db, $_db.user) + .filter((f) => f.id($_item.userId!)); + final item = $_typedResult.readTableOrNull(_userIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static $UserTable _usernameTable(_$AppDatabase db) => db.user.createAlias( + $_aliasNameGenerator(db.userCredential.username, db.user.username)); + + $$UserTableProcessedTableManager? get username { + if ($_item.username == null) return null; + final manager = $$UserTableTableManager($_db, $_db.user) + .filter((f) => f.username($_item.username!)); + final item = $_typedResult.readTableOrNull(_usernameTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static $UserTable _emailTable(_$AppDatabase db) => db.user.createAlias( + $_aliasNameGenerator(db.userCredential.email, db.user.email)); + + $$UserTableProcessedTableManager? get email { + if ($_item.email == null) return null; + final manager = $$UserTableTableManager($_db, $_db.user) + .filter((f) => f.email($_item.email!)); + final item = $_typedResult.readTableOrNull(_emailTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} - ColumnFilters get createdAt => $composableBuilder( - column: $table.createdAt, builder: (column) => ColumnFilters(column)); +class $$UserCredentialTableFilterComposer + extends Composer<_$AppDatabase, $UserCredentialTable> { + $$UserCredentialTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get admno => $composableBuilder( + column: $table.admno, builder: (column) => ColumnFilters(column)); - ColumnFilters get modifiedAt => $composableBuilder( - column: $table.modifiedAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get accessToken => $composableBuilder( + column: $table.accessToken, builder: (column) => ColumnFilters(column)); - ColumnFilters get nationalId => $composableBuilder( - column: $table.nationalId, builder: (column) => ColumnFilters(column)); + ColumnFilters get password => $composableBuilder( + column: $table.password, builder: (column) => ColumnFilters(column)); - Expression userProfileRefs( - Expression Function($$UserProfileTableFilterComposer f) f) { - final $$UserProfileTableFilterComposer composer = $composerBuilder( + ColumnFilters get lastLogin => $composableBuilder( + column: $table.lastLogin, builder: (column) => ColumnFilters(column)); + + $$UserTableFilterComposer get userId { + final $$UserTableFilterComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.id, - referencedTable: $db.userProfile, - getReferencedColumn: (t) => t.userId, + getCurrentColumn: (t) => t.userId, + referencedTable: $db.user, + getReferencedColumn: (t) => t.id, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$UserProfileTableFilterComposer( + $$UserTableFilterComposer( $db: $db, - $table: $db.userProfile, + $table: $db.user, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: $removeJoinBuilderFromRootComposer, )); - return f(composer); + return composer; + } + + $$UserTableFilterComposer get username { + final $$UserTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.username, + referencedTable: $db.user, + getReferencedColumn: (t) => t.username, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableFilterComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + $$UserTableFilterComposer get email { + final $$UserTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.email, + referencedTable: $db.user, + getReferencedColumn: (t) => t.email, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableFilterComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; } } -class $$UserTableOrderingComposer extends Composer<_$AppDatabase, $UserTable> { - $$UserTableOrderingComposer({ +class $$UserCredentialTableOrderingComposer + extends Composer<_$AppDatabase, $UserCredentialTable> { + $$UserCredentialTableOrderingComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - ColumnOrderings get id => $composableBuilder( - column: $table.id, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get username => $composableBuilder( - column: $table.username, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get firstname => $composableBuilder( - column: $table.firstname, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get othernames => $composableBuilder( - column: $table.othernames, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get phone => $composableBuilder( - column: $table.phone, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get admno => $composableBuilder( + column: $table.admno, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get email => $composableBuilder( - column: $table.email, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get accessToken => $composableBuilder( + column: $table.accessToken, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get gender => $composableBuilder( - column: $table.gender, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get password => $composableBuilder( + column: $table.password, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get active => $composableBuilder( - column: $table.active, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get lastLogin => $composableBuilder( + column: $table.lastLogin, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get createdAt => $composableBuilder( - column: $table.createdAt, builder: (column) => ColumnOrderings(column)); + $$UserTableOrderingComposer get userId { + final $$UserTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.userId, + referencedTable: $db.user, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableOrderingComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } - ColumnOrderings get modifiedAt => $composableBuilder( - column: $table.modifiedAt, builder: (column) => ColumnOrderings(column)); + $$UserTableOrderingComposer get username { + final $$UserTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.username, + referencedTable: $db.user, + getReferencedColumn: (t) => t.username, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableOrderingComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } - ColumnOrderings get nationalId => $composableBuilder( - column: $table.nationalId, builder: (column) => ColumnOrderings(column)); + $$UserTableOrderingComposer get email { + final $$UserTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.email, + referencedTable: $db.user, + getReferencedColumn: (t) => t.email, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableOrderingComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } } -class $$UserTableAnnotationComposer - extends Composer<_$AppDatabase, $UserTable> { - $$UserTableAnnotationComposer({ +class $$UserCredentialTableAnnotationComposer + extends Composer<_$AppDatabase, $UserCredentialTable> { + $$UserCredentialTableAnnotationComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - GeneratedColumn get id => - $composableBuilder(column: $table.id, builder: (column) => column); - - GeneratedColumn get username => - $composableBuilder(column: $table.username, builder: (column) => column); - - GeneratedColumn get firstname => - $composableBuilder(column: $table.firstname, builder: (column) => column); - - GeneratedColumn get othernames => $composableBuilder( - column: $table.othernames, builder: (column) => column); - - GeneratedColumn get phone => - $composableBuilder(column: $table.phone, builder: (column) => column); - - GeneratedColumn get email => - $composableBuilder(column: $table.email, builder: (column) => column); + GeneratedColumn get admno => + $composableBuilder(column: $table.admno, builder: (column) => column); - GeneratedColumn get gender => - $composableBuilder(column: $table.gender, builder: (column) => column); + GeneratedColumn get accessToken => $composableBuilder( + column: $table.accessToken, builder: (column) => column); - GeneratedColumn get active => - $composableBuilder(column: $table.active, builder: (column) => column); + GeneratedColumn get password => + $composableBuilder(column: $table.password, builder: (column) => column); - GeneratedColumn get createdAt => - $composableBuilder(column: $table.createdAt, builder: (column) => column); + GeneratedColumn get lastLogin => + $composableBuilder(column: $table.lastLogin, builder: (column) => column); - GeneratedColumn get modifiedAt => $composableBuilder( - column: $table.modifiedAt, builder: (column) => column); + $$UserTableAnnotationComposer get userId { + final $$UserTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.userId, + referencedTable: $db.user, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableAnnotationComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } - GeneratedColumn get nationalId => $composableBuilder( - column: $table.nationalId, builder: (column) => column); + $$UserTableAnnotationComposer get username { + final $$UserTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.username, + referencedTable: $db.user, + getReferencedColumn: (t) => t.username, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$UserTableAnnotationComposer( + $db: $db, + $table: $db.user, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } - Expression userProfileRefs( - Expression Function($$UserProfileTableAnnotationComposer a) f) { - final $$UserProfileTableAnnotationComposer composer = $composerBuilder( + $$UserTableAnnotationComposer get email { + final $$UserTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.id, - referencedTable: $db.userProfile, - getReferencedColumn: (t) => t.userId, + getCurrentColumn: (t) => t.email, + referencedTable: $db.user, + getReferencedColumn: (t) => t.email, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$UserProfileTableAnnotationComposer( + $$UserTableAnnotationComposer( $db: $db, - $table: $db.userProfile, + $table: $db.user, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: $removeJoinBuilderFromRootComposer, )); - return f(composer); + return composer; } } -class $$UserTableTableManager extends RootTableManager< +class $$UserCredentialTableTableManager extends RootTableManager< _$AppDatabase, - $UserTable, - UserData, - $$UserTableFilterComposer, - $$UserTableOrderingComposer, - $$UserTableAnnotationComposer, - $$UserTableCreateCompanionBuilder, - $$UserTableUpdateCompanionBuilder, - (UserData, $$UserTableReferences), - UserData, - PrefetchHooks Function({bool userProfileRefs})> { - $$UserTableTableManager(_$AppDatabase db, $UserTable table) + $UserCredentialTable, + UserCredentialData, + $$UserCredentialTableFilterComposer, + $$UserCredentialTableOrderingComposer, + $$UserCredentialTableAnnotationComposer, + $$UserCredentialTableCreateCompanionBuilder, + $$UserCredentialTableUpdateCompanionBuilder, + (UserCredentialData, $$UserCredentialTableReferences), + UserCredentialData, + PrefetchHooks Function({bool userId, bool username, bool email})> { + $$UserCredentialTableTableManager( + _$AppDatabase db, $UserCredentialTable table) : super(TableManagerState( db: db, table: table, createFilteringComposer: () => - $$UserTableFilterComposer($db: db, $table: table), + $$UserCredentialTableFilterComposer($db: db, $table: table), createOrderingComposer: () => - $$UserTableOrderingComposer($db: db, $table: table), + $$UserCredentialTableOrderingComposer($db: db, $table: table), createComputedFieldComposer: () => - $$UserTableAnnotationComposer($db: db, $table: table), + $$UserCredentialTableAnnotationComposer($db: db, $table: table), updateCompanionCallback: ({ - Value id = const Value.absent(), + Value userId = const Value.absent(), + Value admno = const Value.absent(), + Value accessToken = const Value.absent(), Value username = const Value.absent(), - Value firstname = const Value.absent(), - Value othernames = const Value.absent(), - Value phone = const Value.absent(), - Value email = const Value.absent(), - Value gender = const Value.absent(), - Value active = const Value.absent(), - Value createdAt = const Value.absent(), - Value modifiedAt = const Value.absent(), - Value nationalId = const Value.absent(), + Value email = const Value.absent(), + Value password = const Value.absent(), + Value lastLogin = const Value.absent(), Value rowid = const Value.absent(), }) => - UserCompanion( - id: id, + UserCredentialCompanion( + userId: userId, + admno: admno, + accessToken: accessToken, username: username, - firstname: firstname, - othernames: othernames, - phone: phone, email: email, - gender: gender, - active: active, - createdAt: createdAt, - modifiedAt: modifiedAt, - nationalId: nationalId, + password: password, + lastLogin: lastLogin, rowid: rowid, ), createCompanionCallback: ({ - required String id, + Value userId = const Value.absent(), + required String admno, + Value accessToken = const Value.absent(), required String username, - required String firstname, - Value othernames = const Value.absent(), - required String phone, - Value email = const Value.absent(), - required String gender, - Value active = const Value.absent(), - required DateTime createdAt, - required DateTime modifiedAt, - required String nationalId, + required String email, + required String password, + Value lastLogin = const Value.absent(), Value rowid = const Value.absent(), }) => - UserCompanion.insert( - id: id, + UserCredentialCompanion.insert( + userId: userId, + admno: admno, + accessToken: accessToken, username: username, - firstname: firstname, - othernames: othernames, - phone: phone, email: email, - gender: gender, - active: active, - createdAt: createdAt, - modifiedAt: modifiedAt, - nationalId: nationalId, + password: password, + lastLogin: lastLogin, rowid: rowid, ), withReferenceMapper: (p0) => p0 - .map((e) => - (e.readTable(table), $$UserTableReferences(db, table, e))) + .map((e) => ( + e.readTable(table), + $$UserCredentialTableReferences(db, table, e) + )) .toList(), - prefetchHooksCallback: ({userProfileRefs = false}) { + prefetchHooksCallback: ( + {userId = false, username = false, email = false}) { return PrefetchHooks( db: db, - explicitlyWatchedTables: [if (userProfileRefs) db.userProfile], - addJoins: null, + explicitlyWatchedTables: [], + addJoins: < + T extends TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic>>(state) { + if (userId) { + state = state.withJoin( + currentTable: table, + currentColumn: table.userId, + referencedTable: + $$UserCredentialTableReferences._userIdTable(db), + referencedColumn: + $$UserCredentialTableReferences._userIdTable(db).id, + ) as T; + } + if (username) { + state = state.withJoin( + currentTable: table, + currentColumn: table.username, + referencedTable: + $$UserCredentialTableReferences._usernameTable(db), + referencedColumn: $$UserCredentialTableReferences + ._usernameTable(db) + .username, + ) as T; + } + if (email) { + state = state.withJoin( + currentTable: table, + currentColumn: table.email, + referencedTable: + $$UserCredentialTableReferences._emailTable(db), + referencedColumn: + $$UserCredentialTableReferences._emailTable(db).email, + ) as T; + } + + return state; + }, getPrefetchedDataCallback: (items) async { - return [ - if (userProfileRefs) - await $_getPrefetchedData( - currentTable: table, - referencedTable: - $$UserTableReferences._userProfileRefsTable(db), - managerFromTypedResult: (p0) => - $$UserTableReferences(db, table, p0) - .userProfileRefs, - referencedItemsForCurrentItem: (item, - referencedItems) => - referencedItems.where((e) => e.userId == item.id), - typedResults: items) - ]; + return []; }, ); }, )); } -typedef $$UserTableProcessedTableManager = ProcessedTableManager< +typedef $$UserCredentialTableProcessedTableManager = ProcessedTableManager< _$AppDatabase, - $UserTable, - UserData, - $$UserTableFilterComposer, - $$UserTableOrderingComposer, - $$UserTableAnnotationComposer, - $$UserTableCreateCompanionBuilder, - $$UserTableUpdateCompanionBuilder, - (UserData, $$UserTableReferences), - UserData, - PrefetchHooks Function({bool userProfileRefs})>; -typedef $$UserProfileTableCreateCompanionBuilder = UserProfileCompanion - Function({ - Value id, - required String userId, - Value bio, - Value vibePoints, - Value profilePictureUrl, - Value lastSeen, - Value createdAt, - Value modifiedAt, - Value admissionNumber, - Value campus, - required DateTime dateOfBirth, + $UserCredentialTable, + UserCredentialData, + $$UserCredentialTableFilterComposer, + $$UserCredentialTableOrderingComposer, + $$UserCredentialTableAnnotationComposer, + $$UserCredentialTableCreateCompanionBuilder, + $$UserCredentialTableUpdateCompanionBuilder, + (UserCredentialData, $$UserCredentialTableReferences), + UserCredentialData, + PrefetchHooks Function({bool userId, bool username, bool email})>; +typedef $$CourseTableCreateCompanionBuilder = CourseCompanion Function({ + required String unit, + Value user, + required String section, + required String weekDay, + required String campus, + required String room, + required String lecturer, + required String period, + Value color, + Value createdAt, + Value rowid, }); -typedef $$UserProfileTableUpdateCompanionBuilder = UserProfileCompanion - Function({ - Value id, - Value userId, - Value bio, - Value vibePoints, - Value profilePictureUrl, - Value lastSeen, - Value createdAt, - Value modifiedAt, - Value admissionNumber, +typedef $$CourseTableUpdateCompanionBuilder = CourseCompanion Function({ + Value unit, + Value user, + Value section, + Value weekDay, Value campus, - Value dateOfBirth, + Value room, + Value lecturer, + Value period, + Value color, + Value createdAt, + Value rowid, }); -final class $$UserProfileTableReferences - extends BaseReferences<_$AppDatabase, $UserProfileTable, UserProfileData> { - $$UserProfileTableReferences(super.$_db, super.$_table, super.$_typedResult); +final class $$CourseTableReferences + extends BaseReferences<_$AppDatabase, $CourseTable, CourseData> { + $$CourseTableReferences(super.$_db, super.$_table, super.$_typedResult); - static $UserTable _userIdTable(_$AppDatabase db) => db.user - .createAlias($_aliasNameGenerator(db.userProfile.userId, db.user.id)); + static $UserTable _userTable(_$AppDatabase db) => + db.user.createAlias($_aliasNameGenerator(db.course.user, db.user.id)); - $$UserTableProcessedTableManager? get userId { - if ($_item.userId == null) return null; + $$UserTableProcessedTableManager? get user { + if ($_item.user == null) return null; final manager = $$UserTableTableManager($_db, $_db.user) - .filter((f) => f.id($_item.userId!)); - final item = $_typedResult.readTableOrNull(_userIdTable($_db)); + .filter((f) => f.id($_item.user!)); + final item = $_typedResult.readTableOrNull(_userTable($_db)); if (item == null) return manager; return ProcessedTableManager( manager.$state.copyWith(prefetchedData: [item])); } -} -class $$UserProfileTableFilterComposer - extends Composer<_$AppDatabase, $UserProfileTable> { - $$UserProfileTableFilterComposer({ + static MultiTypedResultKey<$TodoTable, List> _todoRefsTable( + _$AppDatabase db) => + MultiTypedResultKey.fromTable(db.todo, + aliasName: $_aliasNameGenerator(db.course.unit, db.todo.unit)); + + $$TodoTableProcessedTableManager get todoRefs { + final manager = $$TodoTableTableManager($_db, $_db.todo) + .filter((f) => f.unit.unit($_item.unit)); + + final cache = $_typedResult.readTableOrNull(_todoRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } +} + +class $$CourseTableFilterComposer + extends Composer<_$AppDatabase, $CourseTable> { + $$CourseTableFilterComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - ColumnFilters get id => $composableBuilder( - column: $table.id, builder: (column) => ColumnFilters(column)); - - ColumnFilters get bio => $composableBuilder( - column: $table.bio, builder: (column) => ColumnFilters(column)); + ColumnFilters get unit => $composableBuilder( + column: $table.unit, builder: (column) => ColumnFilters(column)); - ColumnFilters get vibePoints => $composableBuilder( - column: $table.vibePoints, builder: (column) => ColumnFilters(column)); + ColumnFilters get section => $composableBuilder( + column: $table.section, builder: (column) => ColumnFilters(column)); - ColumnFilters get profilePictureUrl => $composableBuilder( - column: $table.profilePictureUrl, - builder: (column) => ColumnFilters(column)); + ColumnFilters get weekDay => $composableBuilder( + column: $table.weekDay, builder: (column) => ColumnFilters(column)); - ColumnFilters get lastSeen => $composableBuilder( - column: $table.lastSeen, builder: (column) => ColumnFilters(column)); + ColumnFilters get campus => $composableBuilder( + column: $table.campus, builder: (column) => ColumnFilters(column)); - ColumnFilters get createdAt => $composableBuilder( - column: $table.createdAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get room => $composableBuilder( + column: $table.room, builder: (column) => ColumnFilters(column)); - ColumnFilters get modifiedAt => $composableBuilder( - column: $table.modifiedAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get lecturer => $composableBuilder( + column: $table.lecturer, builder: (column) => ColumnFilters(column)); - ColumnFilters get admissionNumber => $composableBuilder( - column: $table.admissionNumber, - builder: (column) => ColumnFilters(column)); + ColumnFilters get period => $composableBuilder( + column: $table.period, builder: (column) => ColumnFilters(column)); - ColumnFilters get campus => $composableBuilder( - column: $table.campus, builder: (column) => ColumnFilters(column)); + ColumnFilters get color => $composableBuilder( + column: $table.color, builder: (column) => ColumnFilters(column)); - ColumnFilters get dateOfBirth => $composableBuilder( - column: $table.dateOfBirth, builder: (column) => ColumnFilters(column)); + ColumnFilters get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnFilters(column)); - $$UserTableFilterComposer get userId { + $$UserTableFilterComposer get user { final $$UserTableFilterComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.userId, + getCurrentColumn: (t) => t.user, referencedTable: $db.user, getReferencedColumn: (t) => t.id, builder: (joinBuilder, @@ -1993,53 +4135,69 @@ class $$UserProfileTableFilterComposer )); return composer; } + + Expression todoRefs( + Expression Function($$TodoTableFilterComposer f) f) { + final $$TodoTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.unit, + referencedTable: $db.todo, + getReferencedColumn: (t) => t.unit, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$TodoTableFilterComposer( + $db: $db, + $table: $db.todo, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } } -class $$UserProfileTableOrderingComposer - extends Composer<_$AppDatabase, $UserProfileTable> { - $$UserProfileTableOrderingComposer({ +class $$CourseTableOrderingComposer + extends Composer<_$AppDatabase, $CourseTable> { + $$CourseTableOrderingComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - ColumnOrderings get id => $composableBuilder( - column: $table.id, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get unit => $composableBuilder( + column: $table.unit, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get bio => $composableBuilder( - column: $table.bio, builder: (column) => ColumnOrderings(column)); - - ColumnOrderings get vibePoints => $composableBuilder( - column: $table.vibePoints, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get section => $composableBuilder( + column: $table.section, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get profilePictureUrl => $composableBuilder( - column: $table.profilePictureUrl, - builder: (column) => ColumnOrderings(column)); + ColumnOrderings get weekDay => $composableBuilder( + column: $table.weekDay, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get lastSeen => $composableBuilder( - column: $table.lastSeen, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get campus => $composableBuilder( + column: $table.campus, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get createdAt => $composableBuilder( - column: $table.createdAt, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get room => $composableBuilder( + column: $table.room, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get modifiedAt => $composableBuilder( - column: $table.modifiedAt, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get lecturer => $composableBuilder( + column: $table.lecturer, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get admissionNumber => $composableBuilder( - column: $table.admissionNumber, - builder: (column) => ColumnOrderings(column)); + ColumnOrderings get period => $composableBuilder( + column: $table.period, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get campus => $composableBuilder( - column: $table.campus, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get color => $composableBuilder( + column: $table.color, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get dateOfBirth => $composableBuilder( - column: $table.dateOfBirth, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnOrderings(column)); - $$UserTableOrderingComposer get userId { + $$UserTableOrderingComposer get user { final $$UserTableOrderingComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.userId, + getCurrentColumn: (t) => t.user, referencedTable: $db.user, getReferencedColumn: (t) => t.id, builder: (joinBuilder, @@ -2057,49 +4215,46 @@ class $$UserProfileTableOrderingComposer } } -class $$UserProfileTableAnnotationComposer - extends Composer<_$AppDatabase, $UserProfileTable> { - $$UserProfileTableAnnotationComposer({ +class $$CourseTableAnnotationComposer + extends Composer<_$AppDatabase, $CourseTable> { + $$CourseTableAnnotationComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - GeneratedColumn get id => - $composableBuilder(column: $table.id, builder: (column) => column); + GeneratedColumn get unit => + $composableBuilder(column: $table.unit, builder: (column) => column); - GeneratedColumn get bio => - $composableBuilder(column: $table.bio, builder: (column) => column); - - GeneratedColumn get vibePoints => $composableBuilder( - column: $table.vibePoints, builder: (column) => column); + GeneratedColumn get section => + $composableBuilder(column: $table.section, builder: (column) => column); - GeneratedColumn get profilePictureUrl => $composableBuilder( - column: $table.profilePictureUrl, builder: (column) => column); + GeneratedColumn get weekDay => + $composableBuilder(column: $table.weekDay, builder: (column) => column); - GeneratedColumn get lastSeen => - $composableBuilder(column: $table.lastSeen, builder: (column) => column); + GeneratedColumn get campus => + $composableBuilder(column: $table.campus, builder: (column) => column); - GeneratedColumn get createdAt => - $composableBuilder(column: $table.createdAt, builder: (column) => column); + GeneratedColumn get room => + $composableBuilder(column: $table.room, builder: (column) => column); - GeneratedColumn get modifiedAt => $composableBuilder( - column: $table.modifiedAt, builder: (column) => column); + GeneratedColumn get lecturer => + $composableBuilder(column: $table.lecturer, builder: (column) => column); - GeneratedColumn get admissionNumber => $composableBuilder( - column: $table.admissionNumber, builder: (column) => column); + GeneratedColumn get period => + $composableBuilder(column: $table.period, builder: (column) => column); - GeneratedColumn get campus => - $composableBuilder(column: $table.campus, builder: (column) => column); + GeneratedColumn get color => + $composableBuilder(column: $table.color, builder: (column) => column); - GeneratedColumn get dateOfBirth => $composableBuilder( - column: $table.dateOfBirth, builder: (column) => column); + GeneratedColumn get createdAt => + $composableBuilder(column: $table.createdAt, builder: (column) => column); - $$UserTableAnnotationComposer get userId { + $$UserTableAnnotationComposer get user { final $$UserTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.userId, + getCurrentColumn: (t) => t.user, referencedTable: $db.user, getReferencedColumn: (t) => t.id, builder: (joinBuilder, @@ -2115,92 +4270,111 @@ class $$UserProfileTableAnnotationComposer )); return composer; } + + Expression todoRefs( + Expression Function($$TodoTableAnnotationComposer a) f) { + final $$TodoTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.unit, + referencedTable: $db.todo, + getReferencedColumn: (t) => t.unit, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$TodoTableAnnotationComposer( + $db: $db, + $table: $db.todo, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } } -class $$UserProfileTableTableManager extends RootTableManager< +class $$CourseTableTableManager extends RootTableManager< _$AppDatabase, - $UserProfileTable, - UserProfileData, - $$UserProfileTableFilterComposer, - $$UserProfileTableOrderingComposer, - $$UserProfileTableAnnotationComposer, - $$UserProfileTableCreateCompanionBuilder, - $$UserProfileTableUpdateCompanionBuilder, - (UserProfileData, $$UserProfileTableReferences), - UserProfileData, - PrefetchHooks Function({bool userId})> { - $$UserProfileTableTableManager(_$AppDatabase db, $UserProfileTable table) + $CourseTable, + CourseData, + $$CourseTableFilterComposer, + $$CourseTableOrderingComposer, + $$CourseTableAnnotationComposer, + $$CourseTableCreateCompanionBuilder, + $$CourseTableUpdateCompanionBuilder, + (CourseData, $$CourseTableReferences), + CourseData, + PrefetchHooks Function({bool user, bool todoRefs})> { + $$CourseTableTableManager(_$AppDatabase db, $CourseTable table) : super(TableManagerState( db: db, table: table, createFilteringComposer: () => - $$UserProfileTableFilterComposer($db: db, $table: table), + $$CourseTableFilterComposer($db: db, $table: table), createOrderingComposer: () => - $$UserProfileTableOrderingComposer($db: db, $table: table), + $$CourseTableOrderingComposer($db: db, $table: table), createComputedFieldComposer: () => - $$UserProfileTableAnnotationComposer($db: db, $table: table), + $$CourseTableAnnotationComposer($db: db, $table: table), updateCompanionCallback: ({ - Value id = const Value.absent(), - Value userId = const Value.absent(), - Value bio = const Value.absent(), - Value vibePoints = const Value.absent(), - Value profilePictureUrl = const Value.absent(), - Value lastSeen = const Value.absent(), - Value createdAt = const Value.absent(), - Value modifiedAt = const Value.absent(), - Value admissionNumber = const Value.absent(), + Value unit = const Value.absent(), + Value user = const Value.absent(), + Value section = const Value.absent(), + Value weekDay = const Value.absent(), Value campus = const Value.absent(), - Value dateOfBirth = const Value.absent(), + Value room = const Value.absent(), + Value lecturer = const Value.absent(), + Value period = const Value.absent(), + Value color = const Value.absent(), + Value createdAt = const Value.absent(), + Value rowid = const Value.absent(), }) => - UserProfileCompanion( - id: id, - userId: userId, - bio: bio, - vibePoints: vibePoints, - profilePictureUrl: profilePictureUrl, - lastSeen: lastSeen, - createdAt: createdAt, - modifiedAt: modifiedAt, - admissionNumber: admissionNumber, + CourseCompanion( + unit: unit, + user: user, + section: section, + weekDay: weekDay, campus: campus, - dateOfBirth: dateOfBirth, + room: room, + lecturer: lecturer, + period: period, + color: color, + createdAt: createdAt, + rowid: rowid, ), createCompanionCallback: ({ - Value id = const Value.absent(), - required String userId, - Value bio = const Value.absent(), - Value vibePoints = const Value.absent(), - Value profilePictureUrl = const Value.absent(), - Value lastSeen = const Value.absent(), - Value createdAt = const Value.absent(), - Value modifiedAt = const Value.absent(), - Value admissionNumber = const Value.absent(), - Value campus = const Value.absent(), - required DateTime dateOfBirth, + required String unit, + Value user = const Value.absent(), + required String section, + required String weekDay, + required String campus, + required String room, + required String lecturer, + required String period, + Value color = const Value.absent(), + Value createdAt = const Value.absent(), + Value rowid = const Value.absent(), }) => - UserProfileCompanion.insert( - id: id, - userId: userId, - bio: bio, - vibePoints: vibePoints, - profilePictureUrl: profilePictureUrl, - lastSeen: lastSeen, - createdAt: createdAt, - modifiedAt: modifiedAt, - admissionNumber: admissionNumber, + CourseCompanion.insert( + unit: unit, + user: user, + section: section, + weekDay: weekDay, campus: campus, - dateOfBirth: dateOfBirth, + room: room, + lecturer: lecturer, + period: period, + color: color, + createdAt: createdAt, + rowid: rowid, ), withReferenceMapper: (p0) => p0 - .map((e) => ( - e.readTable(table), - $$UserProfileTableReferences(db, table, e) - )) + .map((e) => + (e.readTable(table), $$CourseTableReferences(db, table, e))) .toList(), - prefetchHooksCallback: ({userId = false}) { + prefetchHooksCallback: ({user = false, todoRefs = false}) { return PrefetchHooks( db: db, - explicitlyWatchedTables: [], + explicitlyWatchedTables: [if (todoRefs) db.todo], addJoins: < T extends TableManagerState< dynamic, @@ -2214,127 +4388,161 @@ class $$UserProfileTableTableManager extends RootTableManager< dynamic, dynamic, dynamic>>(state) { - if (userId) { + if (user) { state = state.withJoin( currentTable: table, - currentColumn: table.userId, - referencedTable: - $$UserProfileTableReferences._userIdTable(db), - referencedColumn: - $$UserProfileTableReferences._userIdTable(db).id, + currentColumn: table.user, + referencedTable: $$CourseTableReferences._userTable(db), + referencedColumn: $$CourseTableReferences._userTable(db).id, ) as T; } return state; }, getPrefetchedDataCallback: (items) async { - return []; + return [ + if (todoRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: + $$CourseTableReferences._todoRefsTable(db), + managerFromTypedResult: (p0) => + $$CourseTableReferences(db, table, p0).todoRefs, + referencedItemsForCurrentItem: (item, + referencedItems) => + referencedItems.where((e) => e.unit == item.unit), + typedResults: items) + ]; }, ); }, )); } -typedef $$UserProfileTableProcessedTableManager = ProcessedTableManager< +typedef $$CourseTableProcessedTableManager = ProcessedTableManager< _$AppDatabase, - $UserProfileTable, - UserProfileData, - $$UserProfileTableFilterComposer, - $$UserProfileTableOrderingComposer, - $$UserProfileTableAnnotationComposer, - $$UserProfileTableCreateCompanionBuilder, - $$UserProfileTableUpdateCompanionBuilder, - (UserProfileData, $$UserProfileTableReferences), - UserProfileData, - PrefetchHooks Function({bool userId})>; -typedef $$UserCredentialTableCreateCompanionBuilder = UserCredentialCompanion - Function({ - Value userId, - required String admno, - Value accessToken, - required String username, - required String email, - required String password, - Value lastLogin, - Value rowid, + $CourseTable, + CourseData, + $$CourseTableFilterComposer, + $$CourseTableOrderingComposer, + $$CourseTableAnnotationComposer, + $$CourseTableCreateCompanionBuilder, + $$CourseTableUpdateCompanionBuilder, + (CourseData, $$CourseTableReferences), + CourseData, + PrefetchHooks Function({bool user, bool todoRefs})>; +typedef $$TodoTableCreateCompanionBuilder = TodoCompanion Function({ + Value id, + required String userId, + Value unit, + required String title, + required String body, + Value subtasks, + Value color, + Value notify, + Value complete, + Value autocomplete, + Value notifyAt, + Value duedate, + Value dateCreated, + Value dateModified, + Value completedAt, }); -typedef $$UserCredentialTableUpdateCompanionBuilder = UserCredentialCompanion - Function({ - Value userId, - Value admno, - Value accessToken, - Value username, - Value email, - Value password, - Value lastLogin, - Value rowid, +typedef $$TodoTableUpdateCompanionBuilder = TodoCompanion Function({ + Value id, + Value userId, + Value unit, + Value title, + Value body, + Value subtasks, + Value color, + Value notify, + Value complete, + Value autocomplete, + Value notifyAt, + Value duedate, + Value dateCreated, + Value dateModified, + Value completedAt, }); -final class $$UserCredentialTableReferences extends BaseReferences< - _$AppDatabase, $UserCredentialTable, UserCredentialData> { - $$UserCredentialTableReferences( - super.$_db, super.$_table, super.$_typedResult); - - static $UserTable _userIdTable(_$AppDatabase db) => db.user - .createAlias($_aliasNameGenerator(db.userCredential.userId, db.user.id)); - - $$UserTableProcessedTableManager? get userId { - if ($_item.userId == null) return null; - final manager = $$UserTableTableManager($_db, $_db.user) - .filter((f) => f.id($_item.userId!)); - final item = $_typedResult.readTableOrNull(_userIdTable($_db)); - if (item == null) return manager; - return ProcessedTableManager( - manager.$state.copyWith(prefetchedData: [item])); - } - - static $UserTable _usernameTable(_$AppDatabase db) => db.user.createAlias( - $_aliasNameGenerator(db.userCredential.username, db.user.username)); +final class $$TodoTableReferences + extends BaseReferences<_$AppDatabase, $TodoTable, TodoData> { + $$TodoTableReferences(super.$_db, super.$_table, super.$_typedResult); - $$UserTableProcessedTableManager? get username { - if ($_item.username == null) return null; + static $UserTable _userIdTable(_$AppDatabase db) => + db.user.createAlias($_aliasNameGenerator(db.todo.userId, db.user.id)); + + $$UserTableProcessedTableManager? get userId { + if ($_item.userId == null) return null; final manager = $$UserTableTableManager($_db, $_db.user) - .filter((f) => f.username($_item.username!)); - final item = $_typedResult.readTableOrNull(_usernameTable($_db)); + .filter((f) => f.id($_item.userId!)); + final item = $_typedResult.readTableOrNull(_userIdTable($_db)); if (item == null) return manager; return ProcessedTableManager( manager.$state.copyWith(prefetchedData: [item])); } - static $UserTable _emailTable(_$AppDatabase db) => db.user.createAlias( - $_aliasNameGenerator(db.userCredential.email, db.user.email)); + static $CourseTable _unitTable(_$AppDatabase db) => + db.course.createAlias($_aliasNameGenerator(db.todo.unit, db.course.unit)); - $$UserTableProcessedTableManager? get email { - if ($_item.email == null) return null; - final manager = $$UserTableTableManager($_db, $_db.user) - .filter((f) => f.email($_item.email!)); - final item = $_typedResult.readTableOrNull(_emailTable($_db)); + $$CourseTableProcessedTableManager? get unit { + if ($_item.unit == null) return null; + final manager = $$CourseTableTableManager($_db, $_db.course) + .filter((f) => f.unit($_item.unit!)); + final item = $_typedResult.readTableOrNull(_unitTable($_db)); if (item == null) return manager; return ProcessedTableManager( manager.$state.copyWith(prefetchedData: [item])); } } -class $$UserCredentialTableFilterComposer - extends Composer<_$AppDatabase, $UserCredentialTable> { - $$UserCredentialTableFilterComposer({ +class $$TodoTableFilterComposer extends Composer<_$AppDatabase, $TodoTable> { + $$TodoTableFilterComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - ColumnFilters get admno => $composableBuilder( - column: $table.admno, builder: (column) => ColumnFilters(column)); + ColumnFilters get id => $composableBuilder( + column: $table.id, builder: (column) => ColumnFilters(column)); - ColumnFilters get accessToken => $composableBuilder( - column: $table.accessToken, builder: (column) => ColumnFilters(column)); + ColumnFilters get title => $composableBuilder( + column: $table.title, builder: (column) => ColumnFilters(column)); - ColumnFilters get password => $composableBuilder( - column: $table.password, builder: (column) => ColumnFilters(column)); + ColumnFilters get body => $composableBuilder( + column: $table.body, builder: (column) => ColumnFilters(column)); - ColumnFilters get lastLogin => $composableBuilder( - column: $table.lastLogin, builder: (column) => ColumnFilters(column)); + ColumnFilters get subtasks => $composableBuilder( + column: $table.subtasks, builder: (column) => ColumnFilters(column)); + + ColumnFilters get color => $composableBuilder( + column: $table.color, builder: (column) => ColumnFilters(column)); + + ColumnFilters get notify => $composableBuilder( + column: $table.notify, builder: (column) => ColumnFilters(column)); + + ColumnFilters get complete => $composableBuilder( + column: $table.complete, builder: (column) => ColumnFilters(column)); + + ColumnFilters get autocomplete => $composableBuilder( + column: $table.autocomplete, builder: (column) => ColumnFilters(column)); + + ColumnFilters get notifyAt => $composableBuilder( + column: $table.notifyAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get duedate => $composableBuilder( + column: $table.duedate, builder: (column) => ColumnFilters(column)); + + ColumnFilters get dateCreated => $composableBuilder( + column: $table.dateCreated, builder: (column) => ColumnFilters(column)); + + ColumnFilters get dateModified => $composableBuilder( + column: $table.dateModified, builder: (column) => ColumnFilters(column)); + + ColumnFilters get completedAt => $composableBuilder( + column: $table.completedAt, builder: (column) => ColumnFilters(column)); $$UserTableFilterComposer get userId { final $$UserTableFilterComposer composer = $composerBuilder( @@ -2356,38 +4564,18 @@ class $$UserCredentialTableFilterComposer return composer; } - $$UserTableFilterComposer get username { - final $$UserTableFilterComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.username, - referencedTable: $db.user, - getReferencedColumn: (t) => t.username, - builder: (joinBuilder, - {$addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer}) => - $$UserTableFilterComposer( - $db: $db, - $table: $db.user, - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - )); - return composer; - } - - $$UserTableFilterComposer get email { - final $$UserTableFilterComposer composer = $composerBuilder( + $$CourseTableFilterComposer get unit { + final $$CourseTableFilterComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.email, - referencedTable: $db.user, - getReferencedColumn: (t) => t.email, + getCurrentColumn: (t) => t.unit, + referencedTable: $db.course, + getReferencedColumn: (t) => t.unit, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$UserTableFilterComposer( + $$CourseTableFilterComposer( $db: $db, - $table: $db.user, + $table: $db.course, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -2397,26 +4585,54 @@ class $$UserCredentialTableFilterComposer } } -class $$UserCredentialTableOrderingComposer - extends Composer<_$AppDatabase, $UserCredentialTable> { - $$UserCredentialTableOrderingComposer({ +class $$TodoTableOrderingComposer extends Composer<_$AppDatabase, $TodoTable> { + $$TodoTableOrderingComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - ColumnOrderings get admno => $composableBuilder( - column: $table.admno, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get id => $composableBuilder( + column: $table.id, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get accessToken => $composableBuilder( - column: $table.accessToken, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get title => $composableBuilder( + column: $table.title, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get password => $composableBuilder( - column: $table.password, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get body => $composableBuilder( + column: $table.body, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get lastLogin => $composableBuilder( - column: $table.lastLogin, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get subtasks => $composableBuilder( + column: $table.subtasks, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get color => $composableBuilder( + column: $table.color, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get notify => $composableBuilder( + column: $table.notify, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get complete => $composableBuilder( + column: $table.complete, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get autocomplete => $composableBuilder( + column: $table.autocomplete, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get notifyAt => $composableBuilder( + column: $table.notifyAt, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get duedate => $composableBuilder( + column: $table.duedate, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get dateCreated => $composableBuilder( + column: $table.dateCreated, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get dateModified => $composableBuilder( + column: $table.dateModified, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get completedAt => $composableBuilder( + column: $table.completedAt, builder: (column) => ColumnOrderings(column)); $$UserTableOrderingComposer get userId { final $$UserTableOrderingComposer composer = $composerBuilder( @@ -2438,38 +4654,18 @@ class $$UserCredentialTableOrderingComposer return composer; } - $$UserTableOrderingComposer get username { - final $$UserTableOrderingComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.username, - referencedTable: $db.user, - getReferencedColumn: (t) => t.username, - builder: (joinBuilder, - {$addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer}) => - $$UserTableOrderingComposer( - $db: $db, - $table: $db.user, - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - )); - return composer; - } - - $$UserTableOrderingComposer get email { - final $$UserTableOrderingComposer composer = $composerBuilder( + $$CourseTableOrderingComposer get unit { + final $$CourseTableOrderingComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.email, - referencedTable: $db.user, - getReferencedColumn: (t) => t.email, + getCurrentColumn: (t) => t.unit, + referencedTable: $db.course, + getReferencedColumn: (t) => t.unit, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$UserTableOrderingComposer( + $$CourseTableOrderingComposer( $db: $db, - $table: $db.user, + $table: $db.course, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -2479,26 +4675,53 @@ class $$UserCredentialTableOrderingComposer } } -class $$UserCredentialTableAnnotationComposer - extends Composer<_$AppDatabase, $UserCredentialTable> { - $$UserCredentialTableAnnotationComposer({ +class $$TodoTableAnnotationComposer + extends Composer<_$AppDatabase, $TodoTable> { + $$TodoTableAnnotationComposer({ required super.$db, required super.$table, super.joinBuilder, super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - GeneratedColumn get admno => - $composableBuilder(column: $table.admno, builder: (column) => column); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); - GeneratedColumn get accessToken => $composableBuilder( - column: $table.accessToken, builder: (column) => column); + GeneratedColumn get title => + $composableBuilder(column: $table.title, builder: (column) => column); - GeneratedColumn get password => - $composableBuilder(column: $table.password, builder: (column) => column); + GeneratedColumn get body => + $composableBuilder(column: $table.body, builder: (column) => column); - GeneratedColumn get lastLogin => - $composableBuilder(column: $table.lastLogin, builder: (column) => column); + GeneratedColumn get subtasks => + $composableBuilder(column: $table.subtasks, builder: (column) => column); + + GeneratedColumn get color => + $composableBuilder(column: $table.color, builder: (column) => column); + + GeneratedColumn get notify => + $composableBuilder(column: $table.notify, builder: (column) => column); + + GeneratedColumn get complete => + $composableBuilder(column: $table.complete, builder: (column) => column); + + GeneratedColumn get autocomplete => $composableBuilder( + column: $table.autocomplete, builder: (column) => column); + + GeneratedColumn get notifyAt => + $composableBuilder(column: $table.notifyAt, builder: (column) => column); + + GeneratedColumn get duedate => + $composableBuilder(column: $table.duedate, builder: (column) => column); + + GeneratedColumn get dateCreated => $composableBuilder( + column: $table.dateCreated, builder: (column) => column); + + GeneratedColumn get dateModified => $composableBuilder( + column: $table.dateModified, builder: (column) => column); + + GeneratedColumn get completedAt => $composableBuilder( + column: $table.completedAt, builder: (column) => column); $$UserTableAnnotationComposer get userId { final $$UserTableAnnotationComposer composer = $composerBuilder( @@ -2520,38 +4743,18 @@ class $$UserCredentialTableAnnotationComposer return composer; } - $$UserTableAnnotationComposer get username { - final $$UserTableAnnotationComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.username, - referencedTable: $db.user, - getReferencedColumn: (t) => t.username, - builder: (joinBuilder, - {$addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer}) => - $$UserTableAnnotationComposer( - $db: $db, - $table: $db.user, - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - )); - return composer; - } - - $$UserTableAnnotationComposer get email { - final $$UserTableAnnotationComposer composer = $composerBuilder( + $$CourseTableAnnotationComposer get unit { + final $$CourseTableAnnotationComposer composer = $composerBuilder( composer: this, - getCurrentColumn: (t) => t.email, - referencedTable: $db.user, - getReferencedColumn: (t) => t.email, + getCurrentColumn: (t) => t.unit, + referencedTable: $db.course, + getReferencedColumn: (t) => t.unit, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - $$UserTableAnnotationComposer( + $$CourseTableAnnotationComposer( $db: $db, - $table: $db.user, + $table: $db.course, $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -2561,77 +4764,101 @@ class $$UserCredentialTableAnnotationComposer } } -class $$UserCredentialTableTableManager extends RootTableManager< +class $$TodoTableTableManager extends RootTableManager< _$AppDatabase, - $UserCredentialTable, - UserCredentialData, - $$UserCredentialTableFilterComposer, - $$UserCredentialTableOrderingComposer, - $$UserCredentialTableAnnotationComposer, - $$UserCredentialTableCreateCompanionBuilder, - $$UserCredentialTableUpdateCompanionBuilder, - (UserCredentialData, $$UserCredentialTableReferences), - UserCredentialData, - PrefetchHooks Function({bool userId, bool username, bool email})> { - $$UserCredentialTableTableManager( - _$AppDatabase db, $UserCredentialTable table) + $TodoTable, + TodoData, + $$TodoTableFilterComposer, + $$TodoTableOrderingComposer, + $$TodoTableAnnotationComposer, + $$TodoTableCreateCompanionBuilder, + $$TodoTableUpdateCompanionBuilder, + (TodoData, $$TodoTableReferences), + TodoData, + PrefetchHooks Function({bool userId, bool unit})> { + $$TodoTableTableManager(_$AppDatabase db, $TodoTable table) : super(TableManagerState( db: db, table: table, createFilteringComposer: () => - $$UserCredentialTableFilterComposer($db: db, $table: table), + $$TodoTableFilterComposer($db: db, $table: table), createOrderingComposer: () => - $$UserCredentialTableOrderingComposer($db: db, $table: table), + $$TodoTableOrderingComposer($db: db, $table: table), createComputedFieldComposer: () => - $$UserCredentialTableAnnotationComposer($db: db, $table: table), + $$TodoTableAnnotationComposer($db: db, $table: table), updateCompanionCallback: ({ - Value userId = const Value.absent(), - Value admno = const Value.absent(), - Value accessToken = const Value.absent(), - Value username = const Value.absent(), - Value email = const Value.absent(), - Value password = const Value.absent(), - Value lastLogin = const Value.absent(), - Value rowid = const Value.absent(), + Value id = const Value.absent(), + Value userId = const Value.absent(), + Value unit = const Value.absent(), + Value title = const Value.absent(), + Value body = const Value.absent(), + Value subtasks = const Value.absent(), + Value color = const Value.absent(), + Value notify = const Value.absent(), + Value complete = const Value.absent(), + Value autocomplete = const Value.absent(), + Value notifyAt = const Value.absent(), + Value duedate = const Value.absent(), + Value dateCreated = const Value.absent(), + Value dateModified = const Value.absent(), + Value completedAt = const Value.absent(), }) => - UserCredentialCompanion( + TodoCompanion( + id: id, userId: userId, - admno: admno, - accessToken: accessToken, - username: username, - email: email, - password: password, - lastLogin: lastLogin, - rowid: rowid, + unit: unit, + title: title, + body: body, + subtasks: subtasks, + color: color, + notify: notify, + complete: complete, + autocomplete: autocomplete, + notifyAt: notifyAt, + duedate: duedate, + dateCreated: dateCreated, + dateModified: dateModified, + completedAt: completedAt, ), createCompanionCallback: ({ - Value userId = const Value.absent(), - required String admno, - Value accessToken = const Value.absent(), - required String username, - required String email, - required String password, - Value lastLogin = const Value.absent(), - Value rowid = const Value.absent(), + Value id = const Value.absent(), + required String userId, + Value unit = const Value.absent(), + required String title, + required String body, + Value subtasks = const Value.absent(), + Value color = const Value.absent(), + Value notify = const Value.absent(), + Value complete = const Value.absent(), + Value autocomplete = const Value.absent(), + Value notifyAt = const Value.absent(), + Value duedate = const Value.absent(), + Value dateCreated = const Value.absent(), + Value dateModified = const Value.absent(), + Value completedAt = const Value.absent(), }) => - UserCredentialCompanion.insert( + TodoCompanion.insert( + id: id, userId: userId, - admno: admno, - accessToken: accessToken, - username: username, - email: email, - password: password, - lastLogin: lastLogin, - rowid: rowid, + unit: unit, + title: title, + body: body, + subtasks: subtasks, + color: color, + notify: notify, + complete: complete, + autocomplete: autocomplete, + notifyAt: notifyAt, + duedate: duedate, + dateCreated: dateCreated, + dateModified: dateModified, + completedAt: completedAt, ), withReferenceMapper: (p0) => p0 - .map((e) => ( - e.readTable(table), - $$UserCredentialTableReferences(db, table, e) - )) + .map((e) => + (e.readTable(table), $$TodoTableReferences(db, table, e))) .toList(), - prefetchHooksCallback: ( - {userId = false, username = false, email = false}) { + prefetchHooksCallback: ({userId = false, unit = false}) { return PrefetchHooks( db: db, explicitlyWatchedTables: [], @@ -2652,31 +4879,16 @@ class $$UserCredentialTableTableManager extends RootTableManager< state = state.withJoin( currentTable: table, currentColumn: table.userId, - referencedTable: - $$UserCredentialTableReferences._userIdTable(db), - referencedColumn: - $$UserCredentialTableReferences._userIdTable(db).id, - ) as T; - } - if (username) { - state = state.withJoin( - currentTable: table, - currentColumn: table.username, - referencedTable: - $$UserCredentialTableReferences._usernameTable(db), - referencedColumn: $$UserCredentialTableReferences - ._usernameTable(db) - .username, + referencedTable: $$TodoTableReferences._userIdTable(db), + referencedColumn: $$TodoTableReferences._userIdTable(db).id, ) as T; } - if (email) { + if (unit) { state = state.withJoin( currentTable: table, - currentColumn: table.email, - referencedTable: - $$UserCredentialTableReferences._emailTable(db), - referencedColumn: - $$UserCredentialTableReferences._emailTable(db).email, + currentColumn: table.unit, + referencedTable: $$TodoTableReferences._unitTable(db), + referencedColumn: $$TodoTableReferences._unitTable(db).unit, ) as T; } @@ -2690,18 +4902,18 @@ class $$UserCredentialTableTableManager extends RootTableManager< )); } -typedef $$UserCredentialTableProcessedTableManager = ProcessedTableManager< +typedef $$TodoTableProcessedTableManager = ProcessedTableManager< _$AppDatabase, - $UserCredentialTable, - UserCredentialData, - $$UserCredentialTableFilterComposer, - $$UserCredentialTableOrderingComposer, - $$UserCredentialTableAnnotationComposer, - $$UserCredentialTableCreateCompanionBuilder, - $$UserCredentialTableUpdateCompanionBuilder, - (UserCredentialData, $$UserCredentialTableReferences), - UserCredentialData, - PrefetchHooks Function({bool userId, bool username, bool email})>; + $TodoTable, + TodoData, + $$TodoTableFilterComposer, + $$TodoTableOrderingComposer, + $$TodoTableAnnotationComposer, + $$TodoTableCreateCompanionBuilder, + $$TodoTableUpdateCompanionBuilder, + (TodoData, $$TodoTableReferences), + TodoData, + PrefetchHooks Function({bool userId, bool unit})>; class $AppDatabaseManager { final _$AppDatabase _db; @@ -2711,4 +4923,7 @@ class $AppDatabaseManager { $$UserProfileTableTableManager(_db, _db.userProfile); $$UserCredentialTableTableManager get userCredential => $$UserCredentialTableTableManager(_db, _db.userCredential); + $$CourseTableTableManager get course => + $$CourseTableTableManager(_db, _db.course); + $$TodoTableTableManager get todo => $$TodoTableTableManager(_db, _db.todo); } diff --git a/lib/features/auth/auth.dart b/lib/features/auth/auth.dart index fd4af2f..9617e38 100644 --- a/lib/features/auth/auth.dart +++ b/lib/features/auth/auth.dart @@ -1,2 +1,4 @@ +export 'cubit/auth_cubit.dart'; +export 'cubit/auth_states.dart'; export './views/login_page.dart'; export './views/user_selection_page.dart'; diff --git a/lib/features/auth/cubit/auth_cubit.dart b/lib/features/auth/cubit/auth_cubit.dart index feaf058..40d1674 100644 --- a/lib/features/auth/cubit/auth_cubit.dart +++ b/lib/features/auth/cubit/auth_cubit.dart @@ -8,6 +8,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:academia/features/auth/cubit/auth_states.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; +/// TODO: erick figure out a way to automatically log in user when connection is established class AuthCubit extends Cubit { final UserRepository _userRepository = UserRepository(); @@ -20,12 +21,22 @@ class AuthCubit extends Cubit { }, (users) { if (users.isEmpty) { emit(AuthFirstAppLaunch()); + return null; } else if (users.length == 1) { return fetchUserCredsFromCache(users.first).then((result) { result.fold((error) { emit(AuthErrorState(error)); return; - }, (creds) { + }, (creds) async { + final List connectivityResult = + await (Connectivity().checkConnectivity()); + + // Authenticate locally if no internet connection was found + if (connectivityResult.contains(ConnectivityResult.none)) { + emit(AuthenticatedState(user: users.first, localAuth: true)); + return; + } + authenticate(creds).then((auth) { auth.fold((error) { emit(AuthErrorState(error)); @@ -44,12 +55,6 @@ class AuthCubit extends Cubit { ); } - StreamSubscription> subscription = Connectivity() - .onConnectivityChanged - .listen((List result) { - // Received changes in available connectivity types! - }); - /// Authenticate performs authentication mechanisms with both verisafe /// and magnet to authenticate a user Future> authenticate( @@ -68,8 +73,8 @@ class AuthCubit extends Cubit { } Future fetchUserProfile(UserData user) async { - final result = await _userRepository.fetchUserProfile(user); - result.fold((l) { + final result = await _userRepository.fetchUserProfileFromCache(user); + return result.fold((l) { debugPrint(l); return null; }, (r) { diff --git a/lib/features/auth/models/user_profile.dart b/lib/features/auth/models/user_profile.dart index 147ef0b..4e749d2 100644 --- a/lib/features/auth/models/user_profile.dart +++ b/lib/features/auth/models/user_profile.dart @@ -2,8 +2,6 @@ import 'package:drift/drift.dart'; import './user.dart'; class UserProfile extends Table { - IntColumn get id => integer().autoIncrement()(); - @JsonKey("user_id") TextColumn get userId => text().references(User, #id)(); @@ -27,4 +25,7 @@ class UserProfile extends Table { TextColumn get campus => text().withDefault(const Constant("athi"))(); @JsonKey("date_of_birth") DateTimeColumn get dateOfBirth => dateTime()(); + + @override + Set>? get primaryKey => {userId}; } diff --git a/lib/features/auth/repository/user_local_repository.dart b/lib/features/auth/repository/user_local_repository.dart index 2a13621..e1dd6bb 100644 --- a/lib/features/auth/repository/user_local_repository.dart +++ b/lib/features/auth/repository/user_local_repository.dart @@ -1,12 +1,13 @@ import 'package:academia/database/database.dart'; import 'package:dartz/dartz.dart'; import 'package:drift/drift.dart'; +import 'package:get_it/get_it.dart'; /// Repository for manipulation of user related information /// in the application's local cache final class UserLocalRepository { // the db's instance - final AppDatabase _localDb = LocalDatabase().getInstance(); + final AppDatabase _localDb = GetIt.instance.get(instanceName: "cacheDB"); /// Fetches all users from the local cache /// incase of an error it will return a [String] to the left @@ -101,6 +102,26 @@ final class UserLocalRepository { } } + /// Sets a user's profile to the cache + Future> addUserProfile(UserProfileData profile) async { + try { + final ok = + await _localDb.into(_localDb.userProfile).insertOnConflictUpdate( + profile.toCompanion(true), + ); + if (ok != 0) { + return right(true); + } + return left( + "The specified user profile data was not inserted since it exists and confliced", + ); + } catch (e) { + return left( + "Failed to append user profile to cache with error description ${e.toString()}", + ); + } + } + /// Retrieves a user's profile from the cache Future> fetchUserProfile( UserData user) async { diff --git a/lib/features/auth/repository/user_remote_repository.dart b/lib/features/auth/repository/user_remote_repository.dart index 6b34c6d..e5e08ce 100644 --- a/lib/features/auth/repository/user_remote_repository.dart +++ b/lib/features/auth/repository/user_remote_repository.dart @@ -14,7 +14,7 @@ final class UserRemoteRepository with DioErrorHandler { ) async { try { final response = await _client.dio.post( - "/auth/authenticate", + "/verisafe/v2/auth/authenticate", data: credentials.toJson(), ); @@ -26,7 +26,26 @@ final class UserRemoteRepository with DioErrorHandler { } on DioException catch (de) { return handleDioError(de); } catch (e) { - return left("Please check your internet connection and try that again!"); + return left("Something went terribly wrong please try that later"); + } + } + + /// The function attempts to fetch a user's profile from verisafe + /// In the event of success it retuns the [UserProfileData] + /// and in case of failure it retuns a string indicating what exactly + /// went wrong + Future> fetchUserProfile() async { + try { + final response = await _client.dio.get("verisafe/v2/users/profile"); + if (response.statusCode == 200) { + return right(UserProfileData.fromJson(response.data)); + } + + return left(response.data["error"] ?? response.statusMessage); + } on DioException catch (de) { + return handleDioError(de); + } catch (e) { + return left("Something went terribly wrong please try that later"); } } } diff --git a/lib/features/auth/repository/user_repository.dart b/lib/features/auth/repository/user_repository.dart index 0dca726..4598a17 100644 --- a/lib/features/auth/repository/user_repository.dart +++ b/lib/features/auth/repository/user_repository.dart @@ -46,15 +46,17 @@ final class UserRepository { Future> authenticateRemotely( UserCredentialData credentials) async { // Register a magnet singleton instance - GetIt.instance.registerSingletonIfAbsent( - () => Magnet(credentials.admno, credentials.password), - instanceName: "magnet", - ); - // authenticate with magnet - final magnetResult = - await (GetIt.instance.get(instanceName: "magnet").login()); + // TODO: (erick) enable auth with magnet + // GetIt.instance.registerSingletonIfAbsent( + // () => Magnet(credentials.admno, credentials.password), + // instanceName: "magnet", + // ); + // authenticate with magnet + const magnetResult = + // await (GetIt.instance.get(instanceName: "magnet").login()); + Right(Object()); return magnetResult.fold((error) { return left(error.toString()); }, (session) async { @@ -80,9 +82,34 @@ final class UserRepository { } /// Retrieves a user's profile from the cache - Future> fetchUserProfile( + Future> fetchUserProfileFromCache( + UserData user, + ) async { + final localResult = await _userLocalRepository.fetchUserProfile(user); + if (localResult.isRight()) { + final profile = (localResult as Right).value; + if (profile == null) { + return left( + "Failed to fetch your profile from cache please connect to the internet and refresh", + ); + } + return right((localResult as Right).value); + } + + return Left((localResult as Left).value); + } + + Future> refreshUserProfile( UserData user, ) async { - return await _userLocalRepository.fetchUserProfile(user); + // Fetch from the remote db + final remoteResult = await _userRemoteRepository.fetchUserProfile(); + if (remoteResult.isRight()) { + final profile = (remoteResult as Right).value; + await _userLocalRepository.addUserProfile(profile); + return right(profile); + } + + return (left((remoteResult as Left).value)); } } diff --git a/lib/features/auth/views/login_page.dart b/lib/features/auth/views/login_page.dart index 517fc50..1046520 100644 --- a/lib/features/auth/views/login_page.dart +++ b/lib/features/auth/views/login_page.dart @@ -1,6 +1,5 @@ import 'package:academia/database/database.dart'; -import 'package:academia/features/auth/cubit/auth_cubit.dart'; -import 'package:academia/features/auth/cubit/auth_states.dart'; +import 'package:academia/features/features.dart'; import 'package:academia/utils/router/router.dart'; import 'package:academia/utils/validator/validator.dart'; import 'package:flutter/material.dart'; @@ -35,25 +34,6 @@ class _LoginPageState extends State { bool validateForm() { return _formState.currentState!.validate(); } - // - // /// Shows a dialog with [title] and [content] - // void _showMessageDialog(String title, String content) { - // showDialog( - // context: context, - // builder: (context) => AlertDialog( - // title: Text(title), - // content: Text(content), - // actions: [ - // TextButton( - // onPressed: () { - // context.pop(); - // }, - // child: const Text("Ok"), - // ), - // ], - // ), - // ); - // } @override Widget build(BuildContext context) { @@ -198,7 +178,8 @@ class _LoginPageState extends State { ); }, (r) { HapticFeedback.heavyImpact(); - GoRouter.of(context).pushNamed( + context.pop(); + GoRouter.of(context).pushReplacementNamed( AcademiaRouter.home, ); }); diff --git a/lib/features/auth/views/user_selection_page.dart b/lib/features/auth/views/user_selection_page.dart index d8a0713..6c6866e 100644 --- a/lib/features/auth/views/user_selection_page.dart +++ b/lib/features/auth/views/user_selection_page.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:icons_plus/icons_plus.dart'; -import 'package:skeletonizer/skeletonizer.dart'; import 'package:sliver_tools/sliver_tools.dart'; class UserSelectionPage extends StatefulWidget { @@ -20,25 +19,6 @@ class UserSelectionPage extends StatefulWidget { class _UserSelectionPageState extends State { late AuthCubit authCubit = BlocProvider.of(context); - /// Shows a dialog with [title] and [content] - void _showMessageDialog(String title, String content) { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(title), - content: Text(content), - actions: [ - TextButton( - onPressed: () { - context.pop(); - }, - child: const Text("Ok"), - ), - ], - ), - ); - } - @override Widget build(BuildContext context) { return Scaffold( diff --git a/lib/features/auth/views/widgets/user_selection_tile.dart b/lib/features/auth/views/widgets/user_selection_tile.dart index a46abda..a5f793d 100644 --- a/lib/features/auth/views/widgets/user_selection_tile.dart +++ b/lib/features/auth/views/widgets/user_selection_tile.dart @@ -1,6 +1,7 @@ import 'package:academia/database/database.dart'; import 'package:academia/features/auth/cubit/auth_cubit.dart'; import 'package:academia/features/auth/cubit/auth_states.dart'; +import 'package:academia/features/home/views/layout.dart'; import 'package:academia/utils/router/router.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; @@ -22,7 +23,7 @@ class UserSelectionTile extends StatefulWidget { } class _UserSelectionTileState extends State { - late AuthCubit _authCubit = BlocProvider.of(context); + late AuthCubit authCubit = BlocProvider.of(context); UserProfileData? profile; UserCredentialData? creds; @@ -46,11 +47,11 @@ class _UserSelectionTileState extends State { } Future _fetchUserProfile(UserData user) async { - return await _authCubit.fetchUserProfile(user); + return await authCubit.fetchUserProfile(user); } Future _fetchUserCredentials(UserData user) async { - final result = await _authCubit.fetchUserCredsFromCache(user); + final result = await authCubit.fetchUserCredsFromCache(user); return result.fold((l) { _showMessageDialog("Error", l); return null; @@ -73,15 +74,17 @@ class _UserSelectionTileState extends State { enabled: snapshot.connectionState != ConnectionState.done, child: ListTile( onTap: () async { - final result = await _authCubit.authenticate(creds!); + final result = await authCubit.authenticate(creds!); result.fold((l) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text(l), )); }, (r) { if (!context.mounted) return; - GoRouter.of(context) - .pushReplacementNamed(AcademiaRouter.home); + context.pop(); + GoRouter.of(context).pushReplacementNamed( + AcademiaRouter.home, + ); }); }, title: Text("@${widget.user.username}"), diff --git a/lib/features/courses/courses.dart b/lib/features/courses/courses.dart new file mode 100644 index 0000000..f2a958a --- /dev/null +++ b/lib/features/courses/courses.dart @@ -0,0 +1,4 @@ +export 'views/courses_page.dart'; +export 'views/course_mobile_view_page.dart'; +export 'cubit/course_cubit.dart'; +export 'cubit/course_state.dart'; diff --git a/lib/features/courses/cubit/course_cubit.dart b/lib/features/courses/cubit/course_cubit.dart new file mode 100644 index 0000000..05654b5 --- /dev/null +++ b/lib/features/courses/cubit/course_cubit.dart @@ -0,0 +1,50 @@ +import 'dart:developer'; + +import 'package:academia/database/database.dart'; +import 'package:academia/features/courses/cubit/course_state.dart'; +import 'package:academia/features/courses/repository/course_repository.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class CourseCubit extends Cubit { + final CourseRepository _courseRepository = CourseRepository(); + CourseCubit() : super(CourseStateInitial()); + + Future syncCourses(UserData user) async { + emit(CourseStateLoading()); + final res = await _courseRepository.syncCoursesWithMagnet(user); + if (res.isLeft()) { + emit(CourseStateError(error: (res as Left).value)); + } + emit(CourseStateLoaded(courses: (res as Right).value)); + } + + Future fetchCachedCourses(UserData user) async { + emit(CourseStateLoading()); + final result = await _courseRepository.fetchAllCachedCourses(user); + result.fold((error) { + print(error); + emit(CourseStateError(error: error)); + }, (courses) { + emit(CourseStateLoaded(courses: courses)); + }); + } + + Future saveCouse(CourseData course) async { + if (state is! CourseStateLoaded) { + return; + } + var courses = []; + courses = (state as CourseStateLoaded).courses; + courses.removeWhere((c) => c.unit == course.unit); + emit(CourseStateLoading()); + final result = await _courseRepository.saveCourseToCache(course); + result.fold((error) { + emit(CourseStateError(error: error)); + }, (ok) { + courses.add(course); + emit(CourseStateLoaded(courses: courses)); + log("Data saved to localdb sucessfully"); + }); + } +} diff --git a/lib/features/courses/cubit/course_state.dart b/lib/features/courses/cubit/course_state.dart new file mode 100644 index 0000000..9251005 --- /dev/null +++ b/lib/features/courses/cubit/course_state.dart @@ -0,0 +1,37 @@ +import 'package:academia/database/database.dart'; + +/// The base course state +/// note that the [busy] flag will be inherited by all +/// states to indicate that the state is busy and might +/// change +abstract class CourseState { + CourseState({this.busy = false}); + bool busy; +} + +/// The [CourseStateInitial] represents the first state +/// of courses +final class CourseStateInitial extends CourseState {} + +/// The [CourseStateLoading] indicates that the courses +/// are loading either from remote or cache and they're +/// bound to change +final class CourseStateLoading extends CourseState {} + +/// [CourseStateLoaded] indicates that the courses are loaded +/// The [courses] member contains a list of all courses +final class CourseStateLoaded extends CourseState { + final List courses; + CourseStateLoaded({required this.courses}); +} + +/// The [CourseStateError] represents the courses error state +/// It should be emitted if for example fetching was an error +/// or parsing the course data was an error +/// +/// The [error] member contains a [String] message of +/// what went wrong +final class CourseStateError extends CourseState { + final String error; + CourseStateError({required this.error}); +} diff --git a/lib/features/courses/models/course.dart b/lib/features/courses/models/course.dart new file mode 100644 index 0000000..91d9ac3 --- /dev/null +++ b/lib/features/courses/models/course.dart @@ -0,0 +1,21 @@ +import 'package:academia/features/auth/models/user.dart'; +import 'package:drift/drift.dart'; + +class Course extends Table { + TextColumn get unit => text()(); + TextColumn get user => text().references(User, #id).nullable()(); + TextColumn get section => text()(); + @JsonKey("day_of_the_week") + TextColumn get weekDay => text()(); + TextColumn get campus => text()(); + TextColumn get room => text()(); + TextColumn get lecturer => text()(); + TextColumn get period => text()(); + IntColumn get color => integer().nullable()(); + @JsonKey("created_at") + DateTimeColumn get createdAt => + dateTime().nullable().withDefault(Constant(DateTime.now()))(); + + @override + Set>? get primaryKey => {unit}; +} diff --git a/lib/features/courses/models/semester.dart b/lib/features/courses/models/semester.dart new file mode 100644 index 0000000..2e96da6 --- /dev/null +++ b/lib/features/courses/models/semester.dart @@ -0,0 +1,18 @@ +import 'package:drift/drift.dart'; + +class Semester extends Table { + TextColumn get id => text()(); + TextColumn get name => text()(); + TextColumn get description => text()(); + @JsonKey("begins_at") + DateTimeColumn get beginsAt => dateTime()(); + @JsonKey("ends_at") + DateTimeColumn get endsAt => dateTime()(); + @JsonKey("created_at") + DateTimeColumn get createdAt => dateTime()(); + @JsonKey("modified_at") + DateTimeColumn get modifiedAt => dateTime()(); + + @override + Set>? get primaryKey => {id}; +} diff --git a/lib/features/courses/repository/course_local_repository.dart b/lib/features/courses/repository/course_local_repository.dart new file mode 100644 index 0000000..f7e6927 --- /dev/null +++ b/lib/features/courses/repository/course_local_repository.dart @@ -0,0 +1,68 @@ +import 'package:academia/database/database.dart'; +import 'package:dartz/dartz.dart'; +import 'package:drift/drift.dart'; +import 'package:get_it/get_it.dart'; + +/// [CourseLocalRepository] +/// A Helper class to manipulate course related information +/// on the device local storage +final class CourseLocalRepository { + // the db's instance + final AppDatabase _localDb = GetIt.instance.get(instanceName: "cacheDB"); + + /// Fetches all cached courses + /// Incase of an error a message of type [String] is returned + /// On success, a [List] of [CourseData] is returned + Future>> fetchAllCachedCourses( + UserData user) async { + try { + final courses = await _localDb.managers.course + .filter((c) => c.user.id.equals(user.id)) + .get(distinct: true); + return right(courses); + } catch (e) { + return left("Failed to retrieve users with message ${e.toString()}"); + } + } + + /// Adds a [CourseData] specified by [course] to [_localDb] cache + /// This method can also be used to update courses since it also updates the + /// information on conflict + Future> addCourseToCache(CourseData course) async { + try { + final ok = await _localDb.into(_localDb.course).insert( + course.toCompanion(true), + mode: InsertMode.insertOrReplace, + ); + if (ok != 0) { + return right(true); + } + return left( + "The specified course data was not inserted since it exists and conflicted", + ); + } catch (e) { + return left( + "Failed to append course to cache with error description ${e.toString()}", + ); + } + } + + /// Delete the [CourseData] specified by [course] from local cache + /// It wil return an instance of [String] describing the error that it might have + /// encountered or a boolean [true] incase it was a success + Future> deleteCourseFromCache(CourseData course) async { + try { + final ok = await _localDb.delete(_localDb.course).delete(course); + if (ok != 0) { + return right(true); + } + return left( + "The specified course was not deleted because it does not exist", + ); + } catch (e) { + return left( + "Failed to delete course from cache with error description ${e.toString()}", + ); + } + } +} diff --git a/lib/features/courses/repository/course_remote_repository.dart b/lib/features/courses/repository/course_remote_repository.dart new file mode 100644 index 0000000..8439e47 --- /dev/null +++ b/lib/features/courses/repository/course_remote_repository.dart @@ -0,0 +1,39 @@ +import 'package:academia/database/database.dart'; +import 'package:academia/utils/network/network.dart'; +import 'package:dartz/dartz.dart'; +import 'package:dio/dio.dart'; +import 'package:get_it/get_it.dart'; +import 'package:magnet/magnet.dart'; + +final class CourseRemoteRepository with DioErrorHandler { + final DioClient _dioClient = DioClient(); + + /// Fetches courses from magnet. + Future>> fetchCoursesFromMagnet() async { + final magnetInstance = GetIt.instance.get(instanceName: "magnet"); + final magnetResult = await magnetInstance.fetchUserTimeTable(); + return magnetResult.fold((error) { + return left(error.toString()); + }, (courses) { + return right(courses.map((c) => CourseData.fromJson(c)).toList()); + }); + } + + /// Sync courses with wookie + Future> syncCourseWithWookie(CourseData course) async { + try { + final response = await _dioClient.dio.post( + "/wookie/courses/create", + data: course.toJson(), + ); + if (response.statusCode == 201) { + return right(true); + } + return right(false); + } on DioException catch (de) { + return handleDioError(de); + } catch (e) { + return left("Something went terribly wrong please try that later"); + } + } +} diff --git a/lib/features/courses/repository/course_repository.dart b/lib/features/courses/repository/course_repository.dart new file mode 100644 index 0000000..94b4b6e --- /dev/null +++ b/lib/features/courses/repository/course_repository.dart @@ -0,0 +1,51 @@ +import 'package:academia/database/database.dart'; +import 'package:dartz/dartz.dart'; +import 'package:drift/drift.dart'; + +import 'course_local_repository.dart'; +import 'course_remote_repository.dart'; + +final class CourseRepository { + final CourseLocalRepository _localRepository = CourseLocalRepository(); + final CourseRemoteRepository _courseRemoteRepository = + CourseRemoteRepository(); + + /// Fetches all cached courses + /// Incase of an error a message of type [String] is returned + /// On success, a [List] of [CourseData] is returned + Future>> fetchAllCachedCourses( + UserData user) async { + return await _localRepository.fetchAllCachedCourses(user); + } + + Future>> syncCoursesWithMagnet( + UserData user) async { + final result = await _courseRemoteRepository.fetchCoursesFromMagnet(); + + return result.fold((error) { + return left(error); + }, (courses) async { + // Cache them to local db + for (final course in courses) { + syncCourseWithWookie(course); + final res = await _localRepository.addCourseToCache( + course.copyWith(user: Value(user.id)), + ); + if (res.isLeft()) { + return left((res as Left).value); + } + } + return right(courses); + }); + } + + /// Saves [course] to the local cache + /// Useful for updating information on a course + Future> saveCourseToCache(CourseData course) async { + return await _localRepository.addCourseToCache(course); + } + + Future> syncCourseWithWookie(CourseData course) async { + return await _courseRemoteRepository.syncCourseWithWookie(course); + } +} diff --git a/lib/features/courses/views/course_mobile_view_page.dart b/lib/features/courses/views/course_mobile_view_page.dart new file mode 100644 index 0000000..6605531 --- /dev/null +++ b/lib/features/courses/views/course_mobile_view_page.dart @@ -0,0 +1,232 @@ +import 'package:academia/database/database.dart'; +import 'package:academia/features/courses/courses.dart'; +import 'package:drift/drift.dart'; +import 'package:flex_color_picker/flex_color_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:icons_plus/icons_plus.dart'; +import 'package:sliver_tools/sliver_tools.dart'; + +class CourseMobileViewPage extends StatefulWidget { + const CourseMobileViewPage({ + super.key, + required this.course, + }); + + final CourseData course; + @override + State createState() => _CourseMobileViewPageState(); +} + +class _CourseMobileViewPageState extends State { + late CourseCubit courseCubit = BlocProvider.of(context); + late Color? color; + + @override + void initState() { + super.initState(); + color = widget.course.color == null ? null : Color(widget.course.color!); + } + + @override + Widget build(BuildContext context) { + return Theme( + data: color == null + ? Theme.of(context) + : ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: color!), + ), + child: Builder( + builder: (context) => Scaffold( + body: CustomScrollView( + slivers: [ + SliverAppBar( + pinned: true, + floating: true, + snap: true, + expandedHeight: 128, + flexibleSpace: FlexibleSpaceBar( + title: Text(widget.course.unit), + ), + + // actions + actions: [ + IconButton( + onPressed: () {}, + icon: const Icon(Bootstrap.trash), + ), + ], + ), + SliverPadding( + padding: const EdgeInsets.all(12), + sliver: MultiSliver( + children: [ + SliverPinnedHeader( + child: Container( + color: Theme.of(context).colorScheme.surface, + padding: const EdgeInsets.symmetric(vertical: 16), + child: Text( + "Course Information", + style: Theme.of(context).textTheme.headlineSmall, + ), + ), + ), + // Information cards + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.hash), + title: const Text("Course Unit Code"), + subtitle: Text(widget.course.unit), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.zero, + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.nut), + title: const Text("Course Section"), + subtitle: Text(widget.course.section), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.zero, + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.person_badge), + title: const Text("Lecturer"), + subtitle: Text(widget.course.lecturer), + ), + ), + + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.zero, + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.calendar2_date), + title: const Text("Every"), + subtitle: Text(widget.course.weekDay), + ), + ), + + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.zero, + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.clock), + title: const Text("Period"), + subtitle: Text(widget.course.period), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(12), + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.house_check), + title: const Text("Venue"), + subtitle: Text(widget.course.room), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(12), + ), + ), + child: ListTile( + onTap: () { + final result = showColorPickerDialog( + context, + Theme.of(context).colorScheme.primary, + ); + result.then((color) { + setState(() { + this.color = color; + }); + courseCubit.saveCouse(widget.course.copyWith( + color: Value(color.value), + )); + }); + }, + leading: CircleAvatar(backgroundColor: color), + title: const Text("Course Color"), + subtitle: + const Text("Pick a color to identify this course"), + ), + ), + ], + ), + ), + SliverPadding( + padding: const EdgeInsets.all(12), + sliver: MultiSliver( + children: [ + SliverPinnedHeader( + child: Container( + color: Theme.of(context).colorScheme.surface, + padding: const EdgeInsets.symmetric(vertical: 16), + child: Text( + "Course Notes & Reminders", + style: Theme.of(context).textTheme.headlineSmall, + ), + ), + ), + // Graph + SliverList.builder( + itemCount: 10, + itemBuilder: (context, index) => ListTile( + leading: CircleAvatar( + child: Text(index.toString()), + ), + title: const Text("Hi"), + subtitle: const Text("Some really nice content"), + ), + ), + ], + ), + ), + ], + ), + floatingActionButton: FloatingActionButton.extended( + onPressed: () {}, + label: const Text("New Reminder"), + icon: const Icon(Bootstrap.alarm), + ), + ), + ), + ); + } +} diff --git a/lib/features/courses/views/courses_page.dart b/lib/features/courses/views/courses_page.dart new file mode 100644 index 0000000..29b9616 --- /dev/null +++ b/lib/features/courses/views/courses_page.dart @@ -0,0 +1,18 @@ +import 'package:academia/features/courses/views/courses_page_desktop.dart'; +import 'package:academia/features/courses/views/courses_page_mobile.dart'; +import 'package:academia/utils/utils.dart'; +import 'package:flutter/material.dart'; + +class CoursesPage extends StatelessWidget { + const CoursesPage({super.key}); + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, constraints) => + constraints.maxWidth < ScreenDimension.mobileWidth + ? const CoursesPageMobile() + : const CoursesPageDesktop(), + ); + } +} diff --git a/lib/features/courses/views/courses_page_desktop.dart b/lib/features/courses/views/courses_page_desktop.dart new file mode 100644 index 0000000..bb6c95f --- /dev/null +++ b/lib/features/courses/views/courses_page_desktop.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class CoursesPageDesktop extends StatelessWidget { + const CoursesPageDesktop({super.key}); + + @override + Widget build(BuildContext context) { + return Center( + child: Text("Course page desktop"), + ); + } +} diff --git a/lib/features/courses/views/courses_page_mobile.dart b/lib/features/courses/views/courses_page_mobile.dart new file mode 100644 index 0000000..1257f8c --- /dev/null +++ b/lib/features/courses/views/courses_page_mobile.dart @@ -0,0 +1,116 @@ +import 'package:academia/features/features.dart'; +import 'package:academia/utils/router/router.dart'; +import 'package:academia/utils/utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:go_router/go_router.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:skeletonizer/skeletonizer.dart'; + +class CoursesPageMobile extends StatefulWidget { + const CoursesPageMobile({super.key}); + + @override + State createState() => _CoursesPageMobileState(); +} + +class _CoursesPageMobileState extends State { + late CourseCubit courseCubit = BlocProvider.of(context); + late AuthCubit authCubit = BlocProvider.of(context); + + @override + void initState() { + courseCubit.fetchCachedCourses( + (authCubit.state as AuthenticatedState).user, + ); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: RefreshIndicator( + onRefresh: () async { + await courseCubit.syncCourses( + (authCubit.state as AuthenticatedState).user, + ); + }, + child: CustomScrollView( + slivers: [ + SliverAppBar( + expandedHeight: 250, + pinned: true, + floating: true, + snap: true, + flexibleSpace: FlexibleSpaceBar( + title: Text( + "Courses", + style: Theme.of(context).textTheme.headlineMedium?.copyWith( + fontFamily: GoogleFonts.libreBaskerville().fontFamily, + ), + ), + ), + ), + BlocBuilder(builder: (context, state) { + if (state is CourseStateLoaded) { + if (state.courses.isNotEmpty) { + return SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 12), + sliver: SliverList.separated( + itemBuilder: (context, index) { + final course = state.courses[index]; + return ListTile( + onTap: () => context.pushNamed( + AcademiaRouter.courseView, + extra: course, + ), + leading: CircleAvatar( + backgroundColor: course.color == null + ? null + : Color(course.color!), + ), + title: Text("${course.unit} ${course.section}"), + subtitle: Text( + "${course.room} * ${course.period} * ${course.lecturer.capitalize()}", + ), + ); + }, + separatorBuilder: (context, index) => const SizedBox(), + itemCount: state.courses.length, + ), + ); + } + + return const SliverFillRemaining( + // TODO: erick add an illustration or animation + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text("You have no courses yet, please pull to refresh"), + ], + ), + ); + } + return SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 12), + sliver: SliverList.separated( + itemCount: 8, + itemBuilder: (context, index) => const Skeletonizer( + enabled: true, + child: ListTile( + leading: CircleAvatar(), + title: Text("Some Couse"), + subtitle: Text("PLAB * 10:00 - 13:00 * Awesome Lecturer"), + ), + ), + separatorBuilder: (context, index) => const SizedBox(), + ), + ); + }), + ], + ), + ), + ); + } +} diff --git a/lib/features/essentials/essentials.dart b/lib/features/essentials/essentials.dart new file mode 100644 index 0000000..8c408fb --- /dev/null +++ b/lib/features/essentials/essentials.dart @@ -0,0 +1 @@ +export 'views/essentials_page.dart'; diff --git a/lib/features/essentials/views/essentials_mobile_page.dart b/lib/features/essentials/views/essentials_mobile_page.dart new file mode 100644 index 0000000..6c2291d --- /dev/null +++ b/lib/features/essentials/views/essentials_mobile_page.dart @@ -0,0 +1,178 @@ +import 'package:academia/utils/router/router.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:icons_plus/icons_plus.dart'; +import 'package:sliver_tools/sliver_tools.dart'; + +class EssentialsMobilePage extends StatefulWidget { + const EssentialsMobilePage({super.key}); + + @override + State createState() => _EssentialsMobilePageState(); +} + +class _EssentialsMobilePageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + body: CustomScrollView( + slivers: [ + SliverAppBar( + pinned: true, + snap: true, + floating: true, + expandedHeight: 250, + backgroundColor: Theme.of(context).colorScheme.errorContainer, + flexibleSpace: FlexibleSpaceBar( + title: Text( + "Essentials", + style: Theme.of(context).textTheme.headlineMedium?.copyWith( + fontFamily: GoogleFonts.libreBaskerville().fontFamily, + ), + ), + ), + actions: [ + IconButton( + onPressed: () {}, + icon: const Icon(Bootstrap.qr_code_scan), + ), + ], + ), + SliverPadding( + padding: const EdgeInsets.all(12), + sliver: MultiSliver( + children: [ + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), + ), + ), + child: ListTile( + onTap: () { + context.pushNamed(AcademiaRouter.todo); + }, + leading: const Icon(Bootstrap.bell), + title: const Text("Todos & Assigments"), + subtitle: + const Text("Keep track of your assignments and todos"), + ), + ), + const Card( + elevation: 0, + margin: EdgeInsets.only(bottom: 2), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.zero, + ), + ), + child: ListTile( + leading: Icon(Bootstrap.clock), + title: Text("Exam timetable"), + subtitle: Text("Psst.. Never miss an exam"), + ), + ), + const Card( + elevation: 0, + margin: EdgeInsets.only(bottom: 2), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.zero, + ), + ), + child: ListTile( + leading: Icon(Bootstrap.filetype_pdf), + title: Text("Past Revision Papers"), + subtitle: Text("You want them? You get them.."), + ), + ), + + const Card( + elevation: 0, + margin: EdgeInsets.only(bottom: 2), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.zero, + ), + ), + child: ListTile( + leading: Icon(Bootstrap.file_ppt), + title: Text("Ask Me"), + subtitle: Text("Boring notes? We'll help you revise"), + ), + ), + const Card( + elevation: 0, + margin: EdgeInsets.only(bottom: 2), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(12), + ), + ), + child: ListTile( + leading: Icon(Bootstrap.play), + title: Text("Flash Cards"), + subtitle: Text( + "Curious if you really understood? Try our flashcards", + ), + ), + ), + + //Page Break for student performance + const SizedBox(height: 18), + const Card( + margin: EdgeInsets.only(bottom: 2), + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), + ), + ), + child: ListTile( + leading: Icon(Bootstrap.bell), + title: Text("Student Audit"), + subtitle: Text("Keep track of your assignments and todos"), + ), + ), + const Card( + elevation: 0, + margin: EdgeInsets.only(bottom: 2), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.zero, + ), + ), + child: ListTile( + leading: Icon(Bootstrap.activity), + title: Text("GPA Calculator"), + subtitle: Text("Watch out for those grades!"), + ), + ), + + const Card( + elevation: 0, + margin: EdgeInsets.only(bottom: 2), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(12), + ), + ), + child: ListTile( + leading: Icon(Bootstrap.play), + title: Text("Flash Cards"), + subtitle: Text( + "Curious if you really understood? Try our flashcards", + ), + ), + ), + ], + ), + ) + ], + ), + ); + } +} diff --git a/lib/features/essentials/views/essentials_page.dart b/lib/features/essentials/views/essentials_page.dart new file mode 100644 index 0000000..51774cf --- /dev/null +++ b/lib/features/essentials/views/essentials_page.dart @@ -0,0 +1,19 @@ +import 'package:academia/features/essentials/views/essentials_mobile_page.dart'; +import 'package:academia/utils/responsive/responsive.dart'; +import 'package:flutter/material.dart'; + +class EssentialsPage extends StatelessWidget { + const EssentialsPage({super.key}); + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, constraints) => + constraints.maxWidth < ScreenDimension.mobileWidth + ? const EssentialsMobilePage() + : const Center( + child: Text("Essentials coming soon"), + ), + ); + } +} diff --git a/lib/features/features.dart b/lib/features/features.dart index 6a4ff23..def19d8 100644 --- a/lib/features/features.dart +++ b/lib/features/features.dart @@ -2,3 +2,5 @@ export 'onboarding/onboarding.dart'; export 'auth/auth.dart'; export 'home/home.dart'; export 'profile/profile.dart'; +export 'courses/courses.dart'; +export 'todo/todo.dart'; diff --git a/lib/features/home/views/layout.dart b/lib/features/home/views/layout.dart index be4e2e5..859655e 100644 --- a/lib/features/home/views/layout.dart +++ b/lib/features/home/views/layout.dart @@ -1,6 +1,9 @@ +import 'dart:async'; + +import 'package:academia/features/essentials/essentials.dart'; import 'package:academia/features/features.dart'; -import 'package:academia/features/profile/profile_page_desktop.dart'; import 'package:academia/utils/responsive/responsive.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/material.dart'; import 'package:icons_plus/icons_plus.dart'; @@ -13,21 +16,58 @@ class Layout extends StatefulWidget { class _LayoutState extends State { int _selectedIndex = 0; - final pages = const [ - Center( - child: Text("Statistics"), - ), - Center( - child: Text("Statistics"), - ), - Center( - child: Text("Statistics"), - ), - Center( - child: Text("Statistics"), - ), - ProfilePage() - ]; + // final pages = const [ + // Center( + // child: Text("Statistics"), + // ), + // Center( + // child: Text("Courses"), + // ), + // Center( + // child: Text("Social"), + // ), + // Center( + // child: Text("Statistics"), + // ), + // ProfilePage() + // ]; + + // Stream subscription for network notification + @override + void initState() { + super.initState(); + StreamSubscription> subscription = Connectivity() + .onConnectivityChanged + .listen((List result) { + // Received changes in available connectivity types! + if (result.contains(ConnectivityResult.none)) { + if (!mounted) return; + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + duration: Duration(days: 30), + showCloseIcon: true, + content: Text( + "Your internet connection has been lost some features may not work"), + ), + ); + return; + } + if (!result.contains(ConnectivityResult.none)) { + if (!mounted) return; + + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + showCloseIcon: true, + content: Text("Your internet connection has been restored"), + ), + ); + return; + } + }); + } + @override Widget build(BuildContext context) { return LayoutBuilder( @@ -35,7 +75,17 @@ class _LayoutState extends State { body: constraints.maxWidth < ScreenDimension.mobileWidth ? IndexedStack( index: _selectedIndex, - children: pages, + children: const [ + Center( + child: Text("Statistics"), + ), + CoursesPage(), + Center( + child: Text("Social"), + ), + EssentialsPage(), + ProfilePage() + ], ) : Row( children: [ @@ -80,7 +130,17 @@ class _LayoutState extends State { Expanded( child: IndexedStack( index: _selectedIndex, - children: pages, + children: const [ + Center( + child: Text("Statistics"), + ), + CoursesPage(), + Center( + child: Text("Social"), + ), + EssentialsPage(), + ProfilePage() + ], ), ) ], diff --git a/lib/features/profile/cubit/profile_cubit.dart b/lib/features/profile/cubit/profile_cubit.dart new file mode 100644 index 0000000..c11def0 --- /dev/null +++ b/lib/features/profile/cubit/profile_cubit.dart @@ -0,0 +1,42 @@ +import 'package:academia/database/database.dart'; +import 'package:academia/features/auth/repository/user_repository.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import './profile_state.dart'; + +final class ProfileCubit extends Cubit { + final UserRepository _userRepository = UserRepository(); + ProfileCubit() : super(ProfileInitalState()); + + /// Fetches the profile for a [User] specified by [user] from + /// the local cache + Future> fetchUserProfileFromCache( + UserData user, + ) async { + emit(ProfileLoadingState()); + final result = await _userRepository.fetchUserProfileFromCache(user); + return result.fold((l) { + emit(ProfileErrorState(error: l)); + return left(l); + }, (r) { + emit(ProfileLoadedState(userProfiles: r)); + return right(r); + }); + } + + /// Fetches the profile for a [User] specified by [user] from + /// the remote repo + Future> fetchUserProfileFromRemote( + UserData user, + ) async { + emit(ProfileLoadingState()); + final result = await _userRepository.refreshUserProfile(user); + return result.fold((l) { + emit(ProfileErrorState(error: l)); + return left(l); + }, (r) { + emit(ProfileLoadedState(userProfiles: r)); + return right(r); + }); + } +} diff --git a/lib/features/profile/cubit/profile_state.dart b/lib/features/profile/cubit/profile_state.dart new file mode 100644 index 0000000..4470bf3 --- /dev/null +++ b/lib/features/profile/cubit/profile_state.dart @@ -0,0 +1,22 @@ +// The base profile state +import 'package:academia/database/database.dart'; + +class ProfileState {} + +// Profile initial +class ProfileInitalState extends ProfileState {} + +/// Profile loading state +class ProfileLoadingState extends ProfileState {} + +/// Profile error state +class ProfileErrorState extends ProfileState { + final String error; + ProfileErrorState({required this.error}); +} + +/// Profile loaded state +class ProfileLoadedState extends ProfileState { + final UserProfileData userProfiles; + ProfileLoadedState({required this.userProfiles}); +} diff --git a/lib/features/profile/profile.dart b/lib/features/profile/profile.dart index 988ef68..a9c445a 100644 --- a/lib/features/profile/profile.dart +++ b/lib/features/profile/profile.dart @@ -1 +1,3 @@ -export 'profile_page.dart'; +export 'views/profile_page.dart'; +export 'cubit/profile_cubit.dart'; +export 'cubit/profile_state.dart'; diff --git a/lib/features/profile/profile_page_mobile.dart b/lib/features/profile/profile_page_mobile.dart deleted file mode 100644 index 26db170..0000000 --- a/lib/features/profile/profile_page_mobile.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:icons_plus/icons_plus.dart'; -import 'package:sliver_tools/sliver_tools.dart'; - -class ProfilePageMobile extends StatefulWidget { - const ProfilePageMobile({super.key}); - - @override - State createState() => _ProfilePageMobileState(); -} - -class _ProfilePageMobileState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - body: CustomScrollView( - slivers: [ - SliverAppBar( - pinned: true, - floating: true, - snap: true, - title: const Text("My Profile"), - actions: [ - IconButton( - onPressed: () {}, - icon: const Icon(Bootstrap.pen), - ), - ], - ), - SliverPinnedHeader( - child: Container( - width: MediaQuery.of(context).size.width, - padding: const EdgeInsets.all(12), - child: Column( - spacing: 12, - children: [ - const CircleAvatar( - radius: 80, - ), - Text( - "John Doe Sang Kipkemboi", - style: Theme.of(context).textTheme.headlineSmall, - overflow: TextOverflow.ellipsis, - ), - const Text( - "Some long bio here to be here", - overflow: TextOverflow.visible, - ), - FilledButton( - onPressed: () {}, - child: const Text("Preview my school ID"), - ), - ], - ), - ), - ), - SliverPadding( - padding: const EdgeInsets.all(12), - sliver: SliverClip( - child: MultiSliver( - children: const [ - ListTile( - leading: Icon(Bootstrap.hash), - title: Text("Admission Number"), - subtitle: Text("21-1000"), - ), - ListTile( - leading: Icon(Bootstrap.compass), - title: Text("Campus"), - subtitle: Text("Athi River"), - ), - ListTile( - leading: Icon(Bootstrap.phone), - title: Text("Phone Number"), - subtitle: Text("078277272"), - ), - ListTile( - leading: Icon(Bootstrap.envelope_heart), - title: Text("Email"), - subtitle: Text("someone@example.com"), - ) - ], - ), - ), - ), - ], - ), - ); - } -} diff --git a/lib/features/profile/profile_page.dart b/lib/features/profile/views/profile_page.dart similarity index 80% rename from lib/features/profile/profile_page.dart rename to lib/features/profile/views/profile_page.dart index b72d985..aedc1c4 100644 --- a/lib/features/profile/profile_page.dart +++ b/lib/features/profile/views/profile_page.dart @@ -1,7 +1,7 @@ -import 'package:academia/features/profile/profile_page_desktop.dart'; -import 'package:academia/features/profile/profile_page_mobile.dart'; import 'package:academia/utils/responsive/responsive.dart'; import 'package:flutter/material.dart'; +import 'profile_page_mobile.dart'; +import 'profile_page_desktop.dart'; class ProfilePage extends StatefulWidget { const ProfilePage({super.key}); diff --git a/lib/features/profile/profile_page_desktop.dart b/lib/features/profile/views/profile_page_desktop.dart similarity index 100% rename from lib/features/profile/profile_page_desktop.dart rename to lib/features/profile/views/profile_page_desktop.dart diff --git a/lib/features/profile/views/profile_page_mobile.dart b/lib/features/profile/views/profile_page_mobile.dart new file mode 100644 index 0000000..cf77b76 --- /dev/null +++ b/lib/features/profile/views/profile_page_mobile.dart @@ -0,0 +1,303 @@ +import 'package:academia/database/database.dart'; +import 'package:academia/features/features.dart'; +import 'package:academia/utils/router/router.dart'; +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:go_router/go_router.dart'; +import 'package:icons_plus/icons_plus.dart'; +import 'package:skeletonizer/skeletonizer.dart'; +import 'package:sliver_tools/sliver_tools.dart'; + +class ProfilePageMobile extends StatefulWidget { + const ProfilePageMobile({super.key}); + + @override + State createState() => _ProfilePageMobileState(); +} + +class _ProfilePageMobileState extends State { + late UserData user; + late AuthCubit authCubit = BlocProvider.of(context); + late ProfileCubit profileCubit = BlocProvider.of(context); + + @override + void initState() { + super.initState(); + if (authCubit.state is AuthenticatedState) { + user = (authCubit.state as AuthenticatedState).user; + profileCubit.fetchUserProfileFromCache(user); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: RefreshIndicator( + onRefresh: () async { + final localAuth = (authCubit.state as AuthenticatedState).localAuth; + if (localAuth) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + "Please check your internet connection and try again!", + ), + ), + ); + return; + } + final response = await profileCubit.fetchUserProfileFromRemote(user); + response.fold((error) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(error)), + ); + }, (profile) { + setState(() {}); + }); + }, + child: CustomScrollView( + slivers: [ + SliverAppBar( + automaticallyImplyLeading: false, + pinned: true, + floating: true, + actions: [ + IconButton( + onPressed: () {}, + icon: const Icon(Bootstrap.pencil), + ), + IconButton( + onPressed: () { + HapticFeedback.heavyImpact().then((val) { + if (!context.mounted) return; + GoRouter.of(context).pushNamed(AcademiaRouter.auth); + }); + }, + icon: const Icon(Bootstrap.person_add), + ) + ], + ), + SliverPinnedHeader( + child: Container( + width: MediaQuery.of(context).size.width, + padding: const EdgeInsets.all(12), + child: Row( + spacing: 12, + children: [ + CircleAvatar( + radius: 60, + child: ClipRRect( + borderRadius: BorderRadius.circular(50), + child: BlocBuilder( + buildWhen: (previous, current) { + if (current is ProfileLoadingState) { + return true; + } else if (current is ProfileLoadedState) { + return true; + } + return false; + }, + builder: (context, state) { + if (state is ProfileLoadingState) { + return const CircularProgressIndicator.adaptive(); + } + final profile = + (state as ProfileLoadedState).userProfiles; + + return CachedNetworkImage( + imageUrl: profile.profilePictureUrl ?? "", + fit: BoxFit.fill, + errorWidget: (context, error, message) { + return Image.asset( + "assets/icons/academia_prod.png", + ); + }, + ); + }, + ), + ), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 2, + children: [ + Text( + "${user.firstname} ${user.othernames}", + style: Theme.of(context).textTheme.headlineSmall, + overflow: TextOverflow.ellipsis, + ), + TextButton( + onPressed: () {}, + child: const Text("Preview my school ID"), + ), + ], + ), + ), + ], + ), + ), + ), + SliverPadding( + padding: const EdgeInsets.all(12), + sliver: SliverClip( + child: BlocBuilder( + builder: (context, state) { + if (profileCubit.state is! ProfileLoadedState) { + return SliverFillRemaining( + child: Skeletonizer( + enabled: true, + child: ListView.builder( + itemCount: 8, + itemBuilder: (context, index) => Card( + elevation: 0, + shape: index == 0 + ? const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), + ), + ) + : index == 7 + ? const RoundedRectangleBorder( + borderRadius: + BorderRadius.vertical( + bottom: Radius.circular(12), + ), + ) + : const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.zero)), + child: const ListTile(), + )), + ), + ); + } + final profile = (state as ProfileLoadedState).userProfiles; + return MultiSliver( + pushPinnedChildren: true, + children: [ + SliverPinnedHeader( + child: Container( + color: Theme.of(context).colorScheme.surface, + child: Text( + "Student information", + style: Theme.of(context).textTheme.titleLarge, + ), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.hash), + title: const Text("Admission Number"), + subtitle: Text("${profile.admissionNumber}"), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.zero, + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.at), + title: const Text("Academia Username"), + subtitle: Text("@${user.username}"), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.zero, + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.chat_dots), + title: const Text("Bio"), + subtitle: Text( + "${profile.bio}", + overflow: TextOverflow.visible, + ), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.zero)), + child: ListTile( + leading: const Icon(Bootstrap.gender_ambiguous), + title: const Text("Gender"), + subtitle: Text(user.gender), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.zero)), + child: ListTile( + leading: const Icon(Icons.card_giftcard), + title: const Text("National ID"), + subtitle: Text(user.nationalId), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.zero)), + child: ListTile( + leading: const Icon(Bootstrap.phone), + title: const Text("Phone"), + subtitle: Text(user.phone), + ), + ), + Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.zero)), + child: ListTile( + leading: const Icon(Bootstrap.envelope), + title: const Text("Email"), + subtitle: Text(user.email ?? "unknown"), + ), + ), + Card( + margin: EdgeInsets.zero, + elevation: 0, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(12), + ), + ), + child: ListTile( + leading: const Icon(Bootstrap.house_heart), + title: const Text("Campus"), + subtitle: Text(profile.campus), + ), + ), + ], + ); + }, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/todo/models/todo.dart b/lib/features/todo/models/todo.dart new file mode 100644 index 0000000..290882f --- /dev/null +++ b/lib/features/todo/models/todo.dart @@ -0,0 +1,27 @@ +import 'package:academia/features/auth/models/user.dart'; +import 'package:academia/features/courses/models/course.dart'; +import 'package:drift/drift.dart'; + +class Todo extends Table { + IntColumn get id => integer().autoIncrement().nullable()(); + TextColumn get userId => text().references(User, #id)(); + TextColumn get unit => text().references(Course, #unit).nullable()(); + TextColumn get title => text()(); + TextColumn get body => text()(); + TextColumn get subtasks => text().nullable()(); + IntColumn get color => integer().nullable()(); + BoolColumn get notify => boolean().withDefault(const Constant(false))(); + BoolColumn get complete => boolean().withDefault(const Constant(false))(); + BoolColumn get autocomplete => boolean().withDefault(const Constant(false))(); + DateTimeColumn get notifyAt => dateTime().nullable()(); + DateTimeColumn get duedate => dateTime().nullable()(); + DateTimeColumn get dateCreated => + dateTime().withDefault(Constant(DateTime.now()))(); + DateTimeColumn get dateModified => + dateTime().withDefault(Constant(DateTime.now()))(); + DateTimeColumn get completedAt => + dateTime().withDefault(Constant(DateTime.now()))(); + + @override + Set>? get primaryKey => {id}; +} diff --git a/lib/features/todo/todo.dart b/lib/features/todo/todo.dart new file mode 100644 index 0000000..3f3c55b --- /dev/null +++ b/lib/features/todo/todo.dart @@ -0,0 +1,2 @@ +export 'views/todo_page.dart'; +export 'views/todo_view_page.dart'; diff --git a/lib/features/todo/views/todo_page.dart b/lib/features/todo/views/todo_page.dart new file mode 100644 index 0000000..a8700bc --- /dev/null +++ b/lib/features/todo/views/todo_page.dart @@ -0,0 +1,37 @@ +import 'package:academia/utils/router/router.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:icons_plus/icons_plus.dart'; + +class TodoPage extends StatelessWidget { + const TodoPage({super.key}); + @override + Widget build(BuildContext context) { + return Scaffold( + body: const CustomScrollView( + slivers: [ + SliverAppBar( + pinned: true, + snap: true, + floating: true, + expandedHeight: 128, + flexibleSpace: FlexibleSpaceBar( + title: Text("Todos & Assignments"), + ), + ), + SliverFillRemaining( + child: Center( + child: Text("You have no todos added yet"), + ), + ) + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + context.pushNamed(AcademiaRouter.todoView); + }, + child: const Icon(Bootstrap.plus_circle_dotted), + ), + ); + } +} diff --git a/lib/features/todo/views/todo_view_page.dart b/lib/features/todo/views/todo_view_page.dart new file mode 100644 index 0000000..8487ced --- /dev/null +++ b/lib/features/todo/views/todo_view_page.dart @@ -0,0 +1,424 @@ +import 'dart:convert'; + +import 'package:academia/database/database.dart'; +import 'package:academia/features/features.dart'; +import 'package:drift/drift.dart' as drift; +import 'package:flex_color_picker/flex_color_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:go_router/go_router.dart'; +import 'package:icons_plus/icons_plus.dart'; +import 'package:sliver_tools/sliver_tools.dart'; + +enum TodoEditState { + create, + modify, +} + +class TodoViewPage extends StatefulWidget { + const TodoViewPage({super.key, this.todoData}); + final TodoData? todoData; + + @override + State createState() => _TodoViewPageState(); +} + +class _TodoViewPageState extends State { + late CourseCubit courseCubit = BlocProvider.of(context); + late TodoEditState editState = + widget.todoData == null ? TodoEditState.create : TodoEditState.modify; + + late TodoData todo; + final TextEditingController _titleController = TextEditingController(); + final TextEditingController _descriptionController = TextEditingController(); + Map? subtasks; + + @override + void initState() { + todo = widget.todoData == null + ? TodoData( + userId: "", + title: "", + body: "", + notify: false, + complete: false, + autocomplete: false, + dateCreated: DateTime.now(), + dateModified: DateTime.now(), + completedAt: DateTime.now()) + : widget.todoData!; + + _titleController.text = todo.title; + _descriptionController.text = todo.body; + subtasks = todo.subtasks == null ? {} : json.decode(todo.subtasks!); + + super.initState(); + } + + void _showAddSubtaskDialog() { + final TextEditingController subTaskController = TextEditingController(); + showModalBottomSheet( + context: context, + builder: (context) => Container( + padding: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + spacing: 16, + children: [ + Text( + "Please add a subtask to your todo", + style: Theme.of(context).textTheme.headlineSmall, + ), + TextFormField( + controller: subTaskController, + decoration: InputDecoration( + hintText: "Remember to...", + hintStyle: Theme.of(context).textTheme.titleMedium, + border: const OutlineInputBorder( + borderSide: BorderSide(width: 2), + ), + ), + ), + FilledButton( + onPressed: () { + setState(() { + subtasks![subTaskController.text.capitalize] = false; + }); + context.pop(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Subtask sucessfully added to task"), + ), + ); + }, + child: const Text( + "Add sub task", + ), + ) + ], + ), + ), + ); + } + + Future _configureDueDate() async { + final picked = await showDatePicker( + context: context, + firstDate: DateTime.now(), + lastDate: DateTime.now().add( + const Duration(days: 365), + ), + ); + if (picked != null) { + setState(() { + todo = todo.copyWith(duedate: drift.Value(picked)); + }); + } + } + + Future _configureNotificationTime() async { + final picked = await showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + ); + + if (picked != null) { + setState(() { + todo = todo.copyWith( + notifyAt: drift.Value( + DateTime.now().copyWith( + hour: picked.hour, + minute: picked.minute, + ), + ), + ); + }); + } + } + + Future _showCoursePickerDialog() async { + showModalBottomSheet( + context: context, + builder: (context) => Container( + padding: const EdgeInsets.all(16), + child: BlocBuilder(builder: (context, state) { + if (state is! CourseStateLoaded) { + return const Center( + child: Text("Please refresh courses to continue"), + ); + } + + final courses = (state).courses; + return ListView.builder( + itemCount: courses.length, + itemBuilder: (context, index) { + return CheckboxListTile( + title: Text(courses[index].unit), + value: false, + onChanged: (val) { + setState(() { + todo = todo.copyWith( + unit: drift.Value(courses[index].unit)); + }); + context.pop(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + "Successfully linked task to ${courses[index].unit}"), + ), + ); + }); + }); + }), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: CustomScrollView( + slivers: [ + SliverAppBar( + floating: true, + snap: true, + pinned: true, + expandedHeight: 128, + flexibleSpace: FlexibleSpaceBar( + title: Text( + editState == TodoEditState.create + ? "Create a todo item" + : "Modify todo", + ), + ), + ), + SliverPadding( + padding: const EdgeInsets.all(12), + sliver: MultiSliver( + children: [ + SliverPinnedHeader( + child: Container( + color: Theme.of(context).colorScheme.surface, + child: TextFormField( + controller: _titleController, + maxLength: 30, + decoration: InputDecoration( + hintText: "Tap to add a title", + hintStyle: + Theme.of(context).textTheme.headlineSmall?.copyWith( + color: Theme.of(context).colorScheme.primary, + ), + border: const OutlineInputBorder( + borderSide: BorderSide.none, + ), + ), + ), + ), + ), + SliverPinnedHeader( + child: Text( + "Add some sub-tasks 🫠", + style: Theme.of(context).textTheme.headlineSmall, + ), + ), + SliverList.builder( + itemBuilder: (context, index) { + if (index == subtasks!.keys.length) { + return TextButton.icon( + onPressed: _showAddSubtaskDialog, + icon: const Icon(Bootstrap.journal_plus), + label: const Text("Add a subtask"), + ); + } + var item = subtasks!.entries.elementAt(index); + return CheckboxListTile( + onChanged: (value) { + setState(() { + subtasks![item.key] = value!; + }); + }, + value: item.value, + title: Text(item.key), + ); + }, + itemCount: subtasks!.keys.length + 1, + ), + const SizedBox(height: 16), + SliverPinnedHeader( + child: Container( + margin: const EdgeInsets.symmetric(vertical: 16), + color: Theme.of(context).colorScheme.surface, + child: Text( + "More task configurations", + style: Theme.of(context).textTheme.headlineSmall, + ), + ), + ), + SliverToBoxAdapter( + child: Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), + ), + ), + child: ListTile( + onTap: () async { + final color = await showColorPickerDialog( + context, + Theme.of(context).colorScheme.primary, + ); + + setState(() { + todo = todo.copyWith(color: drift.Value(color.value)); + }); + }, + title: const Text("Pick a color for this task"), + leading: CircleAvatar( + backgroundColor: + todo.color == null ? null : Color(todo.color!), + ), + ), + ), + ), + SliverToBoxAdapter( + child: Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, + ), + child: ListTile( + leading: const Icon(Bootstrap.calendar_day), + enableFeedback: true, + onTap: () async { + await _configureDueDate(); + await HapticFeedback.heavyImpact(); + }, + title: const Text("Pick due date for task"), + subtitle: Text( + todo.duedate == null + ? "Not configured yet" + : todo.duedate.toString(), + ), + ), + ), + ), + SliverToBoxAdapter( + child: Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, + ), + child: ListTile( + leading: const Icon(Bootstrap.vinyl), + enableFeedback: false, + onTap: () { + _showCoursePickerDialog(); + HapticFeedback.heavyImpact().then((value) {}); + }, + title: const Text("Pick a course for this task"), + subtitle: todo.unit == null ? null : Text(todo.unit!), + ), + ), + ), + SliverToBoxAdapter( + child: Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, + ), + child: SwitchListTile( + enableFeedback: true, + onChanged: (val) { + HapticFeedback.heavyImpact().then((value) { + setState(() { + todo = todo.copyWith(complete: val); + }); + }); + }, + value: todo.complete, + title: const Text("Mark task as complete"), + ), + ), + ), + SliverToBoxAdapter( + child: Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, + ), + child: SwitchListTile( + enableFeedback: true, + onChanged: (val) { + HapticFeedback.heavyImpact().then((value) { + setState(() { + todo = todo.copyWith(autocomplete: val); + }); + }); + }, + value: todo.autocomplete, + title: const Text("Automatically close this task"), + ), + ), + ), + SliverToBoxAdapter( + child: Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, + ), + child: SwitchListTile( + enableFeedback: false, + onChanged: (val) { + HapticFeedback.heavyImpact().then((value) { + setState(() { + todo = todo.copyWith(notify: val); + }); + }); + }, + value: todo.notify, + title: const Text("Notify me on this task"), + ), + ), + ), + SliverToBoxAdapter( + child: Card( + elevation: 0, + margin: const EdgeInsets.only(bottom: 2), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(12), + ), + ), + child: ListTile( + enabled: todo.notify, + onTap: () async { + await _configureNotificationTime(); + }, + title: const Text("Configure task's notification"), + leading: const Icon(Bootstrap.bell), + subtitle: const Text( + "Notifications will automatically repeat on the specified time until completed or deleted", + ), + ), + ), + ), + ], + ), + ), + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: () {}, + child: const Icon(Bootstrap.check), + ), + ); + } +} diff --git a/lib/utils/network/auth_interceptor.dart b/lib/utils/network/auth_interceptor.dart index c143e47..b06dc49 100644 --- a/lib/utils/network/auth_interceptor.dart +++ b/lib/utils/network/auth_interceptor.dart @@ -35,11 +35,13 @@ class AuthInterceptor extends Interceptor { @override void onError(DioException err, ErrorInterceptorHandler handler) async { - // TODO: erick Add automatic token refreshing - if (err.response?.statusCode == 401) { - return handler - .resolve(await dio.fetch(err.requestOptions)); // Repeat the request. - } + // TODO: erick Add automatic token refreshing and code retrial + // if (err.response?.statusCode == 401) { + // print("Some really bad error"); + // + // return handler + // .resolve(await dio.fetch(err.requestOptions)); // Repeat the request. + // } return handler.reject(DioException( requestOptions: err.requestOptions, diff --git a/lib/utils/network/dio_client.dart b/lib/utils/network/dio_client.dart index d1fbff2..a1d58c7 100644 --- a/lib/utils/network/dio_client.dart +++ b/lib/utils/network/dio_client.dart @@ -4,8 +4,8 @@ import './auth_interceptor.dart'; import 'package:pretty_dio_logger/pretty_dio_logger.dart'; class DioClient { - static const String _baseUrl = "http://192.168.2.115:8000/v2"; - // static const String _baseUrl = "http://192.168.26.183:8000/v2"; + // static const String _baseUrl = "http://192.168.43.218:8000/v2"; + static const String _baseUrl = "http://192.168.43.218:8000"; DioClient() { dio.interceptors.add( diff --git a/lib/utils/router/default_route.dart b/lib/utils/router/default_route.dart index 96b42cf..fef345d 100644 --- a/lib/utils/router/default_route.dart +++ b/lib/utils/router/default_route.dart @@ -1,5 +1,3 @@ -import 'package:academia/features/auth/cubit/auth_cubit.dart'; -import 'package:academia/features/auth/cubit/auth_states.dart'; import 'package:academia/features/features.dart'; import 'package:academia/utils/router/router.dart'; import 'package:flutter/material.dart'; diff --git a/lib/utils/router/router.dart b/lib/utils/router/router.dart index 8126d78..7f7efa0 100644 --- a/lib/utils/router/router.dart +++ b/lib/utils/router/router.dart @@ -1,8 +1,6 @@ -import 'package:academia/features/auth/cubit/auth_cubit.dart'; -import 'package:academia/features/auth/cubit/auth_states.dart'; +import 'package:academia/database/database.dart'; import 'package:academia/utils/router/default_route.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:academia/features/features.dart'; @@ -17,6 +15,9 @@ class AcademiaRouter { static const String home = "home"; static const String userSelection = "user-selection"; static const String onboarding = "onboarding"; + static const String courseView = "course-view"; + static const String todo = "todo"; + static const String todoView = "todo-view"; static final GoRouter _router = GoRouter( initialLocation: "/", @@ -52,6 +53,27 @@ class AcademiaRouter { path: "/$userSelection", builder: (context, state) => const UserSelectionPage(), ), + GoRoute( + name: todo, + path: "/$todo", + builder: (context, state) => const TodoPage(), + ), + GoRoute( + name: todoView, + path: "/$todoView", + builder: (context, state) { + TodoData? todo = state.extra as TodoData?; + return TodoViewPage(todoData: todo); + }, + ), + GoRoute( + name: courseView, + path: "/$courseView", + builder: (context, state) { + final CourseData course = state.extra as CourseData; + return CourseMobileViewPage(course: course); + }, + ), ], ); } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index ac1e339..fee0649 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -1 +1,7 @@ export 'responsive/responsive.dart'; + +extension StringExtension on String { + String capitalize() { + return "${this[0].toUpperCase()}${substring(1).toLowerCase()}"; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 606a5ba..7d55ba8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -64,6 +64,7 @@ dependencies: get_it: ^8.0.2 pretty_dio_logger: ^1.4.0 connectivity_plus: ^6.1.1 + flex_color_picker: ^3.6.0 dev_dependencies: flutter_test: