down with daos, mild refactoring, moving to pulling from real data

This commit is contained in:
Joshua Burman 2024-12-15 22:21:23 -05:00
parent 54d47245ae
commit 67d7a374d4
22 changed files with 731 additions and 528 deletions

View File

@ -0,0 +1,35 @@
import 'package:drift/drift.dart';
import 'package:sendtrain/database/database.dart';
part 'activities_dao.g.dart';
@DriftAccessor(tables: [Activities])
class ActivitiesDao extends DatabaseAccessor<AppDatabase> with _$ActivitiesDaoMixin {
ActivitiesDao(super.db);
Future<List<Activity>> all() async {
return await select(activities).get();
}
Future<List<Activity>> find(int id) async {
return await (select(activities)..where((activity) => activity.id.equals(id) )).get();
}
Future<List<Activity>> sessionActivities(int id) async {
final result = select(db.sessionActivities).join(
[
innerJoin(
db.activities,
db.activities.id
.equalsExp(db.sessionActivities.activityId),
),
],
)..where(db.sessionActivities.sessionId.equals(id));
final activities = (await result.get())
.map((e) => e.readTable(db.activities))
.toList();
return activities;
}
}

View File

@ -0,0 +1,8 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'activities_dao.dart';
// ignore_for_file: type=lint
mixin _$ActivitiesDaoMixin on DatabaseAccessor<AppDatabase> {
$ActivitiesTable get activities => attachedDatabase.activities;
}

View File

@ -0,0 +1,37 @@
import 'package:drift/drift.dart';
import 'package:sendtrain/database/database.dart';
part 'media_items_dao.g.dart';
@DriftAccessor(tables: [MediaItems])
class MediaItemsDao extends DatabaseAccessor<AppDatabase> with _$MediaItemsDaoMixin {
MediaItemsDao(super.db);
Future<List<MediaItem>> all() async {
return await select(mediaItems).get();
}
Future<List<MediaItem>> find(int id) async {
return await (select(mediaItems)..where((mediaItem) => mediaItem.id.equals(id) )).get();
}
Future<List<MediaItem>> mediaItemsFromSession(Session session) async {
final result = select(db.objectMediaItems).join(
[
innerJoin(
db.mediaItems,
db.mediaItems.id.equalsExp(db.objectMediaItems.mediaId),
),
],
)
..where(
db.objectMediaItems.objectType.equals(ObjectType.sessions.name))
..where(db.objectMediaItems.objectId.equals(session.id));
final mediaItems = (await result.get())
.map((e) => e.readTable(db.mediaItems))
.toList();
return mediaItems;
}
}

View File

@ -0,0 +1,8 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'media_items_dao.dart';
// ignore_for_file: type=lint
mixin _$MediaItemsDaoMixin on DatabaseAccessor<AppDatabase> {
$MediaItemsTable get mediaItems => attachedDatabase.mediaItems;
}

View File

@ -0,0 +1,24 @@
import 'package:drift/drift.dart';
import 'package:sendtrain/database/database.dart';
part 'session_activities_dao.g.dart';
@DriftAccessor(tables: [SessionActivities])
class SessionActivitiesDao extends DatabaseAccessor<AppDatabase> with _$SessionActivitiesDaoMixin {
SessionActivitiesDao(super.db);
Future<List<SessionActivity>> all() async {
return await select(sessionActivities).get();
}
Future<List<SessionActivity>> find(int id) async {
return await (select(sessionActivities)..where((sessionActivity) => sessionActivity.id.equals(id) )).get();
}
Future<List<SessionActivity>> sessionActivitiesBySessionId(int id) async {
final result = db.managers.sessionActivities
.filter((sessionActivity) => sessionActivity.sessionId.id(id));
return result.get();
}
}

View File

@ -0,0 +1,11 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'session_activities_dao.dart';
// ignore_for_file: type=lint
mixin _$SessionActivitiesDaoMixin on DatabaseAccessor<AppDatabase> {
$SessionsTable get sessions => attachedDatabase.sessions;
$ActivitiesTable get activities => attachedDatabase.activities;
$SessionActivitiesTable get sessionActivities =>
attachedDatabase.sessionActivities;
}

View File

@ -0,0 +1,17 @@
import 'package:drift/drift.dart';
import 'package:sendtrain/database/database.dart';
part 'sessions_dao.g.dart';
@DriftAccessor(tables: [Sessions])
class SessionsDao extends DatabaseAccessor<AppDatabase> with _$SessionsDaoMixin {
SessionsDao(super.db);
Future<List<Session>> all() async {
return await select(sessions).get();
}
Future<List<Session>> find(int id) async {
return await (select(sessions)..where((session) => session.id.equals(id) )).get();
}
}

View File

@ -0,0 +1,8 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'sessions_dao.dart';
// ignore_for_file: type=lint
mixin _$SessionsDaoMixin on DatabaseAccessor<AppDatabase> {
$SessionsTable get sessions => attachedDatabase.sessions;
}

View File

@ -1,5 +1,7 @@
import 'package:drift/drift.dart';
import 'package:drift_flutter/drift_flutter.dart';
import 'package:sendtrain/database/daos/activities_dao.dart';
import 'package:sendtrain/database/daos/sessions_dao.dart';
part 'database.g.dart';
@ -74,9 +76,15 @@ class Actions extends Table {
DateTimeColumn get createdAt => dateTime().withDefault(Variable(DateTime.now()))();
}
enum ObjectType {
actions,
activities,
sessions,
}
class ObjectMediaItems extends Table {
IntColumn get id => integer().autoIncrement()();
IntColumn get objectId => integer().references(Actions, #id)();
IntColumn get objectId => integer()();
TextColumn get objectType => textEnum<ObjectType>()();
IntColumn get mediaId => integer().references(MediaItems, #id)();
DateTimeColumn get createdAt => dateTime().withDefault(Variable(DateTime.now()))();
}
@ -89,7 +97,7 @@ class MediaItems extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get title => text().withLength(min: 3, max: 32)();
TextColumn get description => text().named('body')();
TextColumn get reference => text().withLength(min: 3, max: 32)();
TextColumn get reference => text().withLength(min: 3, max: 256)();
TextColumn get type => textEnum<MediaType>()();
DateTimeColumn get createdAt => dateTime().withDefault(Variable(DateTime.now()))();
}
@ -102,6 +110,10 @@ class MediaItems extends Table {
Actions,
ObjectMediaItems,
MediaItems
], daos: [
SessionsDao,
ActivitiesDao,
MediaItems
])
class AppDatabase extends _$AppDatabase {

View File

@ -1644,7 +1644,7 @@ class $MediaItemsTable extends MediaItems
late final GeneratedColumn<String> reference = GeneratedColumn<String>(
'reference', aliasedName, false,
additionalChecks:
GeneratedColumn.checkTextLength(minTextLength: 3, maxTextLength: 32),
GeneratedColumn.checkTextLength(minTextLength: 3, maxTextLength: 256),
type: DriftSqlType.string,
requiredDuringInsert: true);
static const VerificationMeta _typeMeta = const VerificationMeta('type');
@ -1975,10 +1975,15 @@ class $ObjectMediaItemsTable extends ObjectMediaItems
@override
late final GeneratedColumn<int> objectId = GeneratedColumn<int>(
'object_id', aliasedName, false,
type: DriftSqlType.int,
requiredDuringInsert: true,
defaultConstraints:
GeneratedColumn.constraintIsAlways('REFERENCES actions (id)'));
type: DriftSqlType.int, requiredDuringInsert: true);
static const VerificationMeta _objectTypeMeta =
const VerificationMeta('objectType');
@override
late final GeneratedColumnWithTypeConverter<ObjectType, String> objectType =
GeneratedColumn<String>('object_type', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true)
.withConverter<ObjectType>(
$ObjectMediaItemsTable.$converterobjectType);
static const VerificationMeta _mediaIdMeta =
const VerificationMeta('mediaId');
@override
@ -1997,7 +2002,8 @@ class $ObjectMediaItemsTable extends ObjectMediaItems
requiredDuringInsert: false,
defaultValue: Variable(DateTime.now()));
@override
List<GeneratedColumn> get $columns => [id, objectId, mediaId, createdAt];
List<GeneratedColumn> get $columns =>
[id, objectId, objectType, mediaId, createdAt];
@override
String get aliasedName => _alias ?? actualTableName;
@override
@ -2017,6 +2023,7 @@ class $ObjectMediaItemsTable extends ObjectMediaItems
} else if (isInserting) {
context.missing(_objectIdMeta);
}
context.handle(_objectTypeMeta, const VerificationResult.success());
if (data.containsKey('media_id')) {
context.handle(_mediaIdMeta,
mediaId.isAcceptableOrUnknown(data['media_id']!, _mediaIdMeta));
@ -2040,6 +2047,9 @@ class $ObjectMediaItemsTable extends ObjectMediaItems
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
objectId: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}object_id'])!,
objectType: $ObjectMediaItemsTable.$converterobjectType.fromSql(
attachedDatabase.typeMapping.read(
DriftSqlType.string, data['${effectivePrefix}object_type'])!),
mediaId: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}media_id'])!,
createdAt: attachedDatabase.typeMapping
@ -2051,16 +2061,21 @@ class $ObjectMediaItemsTable extends ObjectMediaItems
$ObjectMediaItemsTable createAlias(String alias) {
return $ObjectMediaItemsTable(attachedDatabase, alias);
}
static JsonTypeConverter2<ObjectType, String, String> $converterobjectType =
const EnumNameConverter<ObjectType>(ObjectType.values);
}
class ObjectMediaItem extends DataClass implements Insertable<ObjectMediaItem> {
final int id;
final int objectId;
final ObjectType objectType;
final int mediaId;
final DateTime createdAt;
const ObjectMediaItem(
{required this.id,
required this.objectId,
required this.objectType,
required this.mediaId,
required this.createdAt});
@override
@ -2068,6 +2083,10 @@ class ObjectMediaItem extends DataClass implements Insertable<ObjectMediaItem> {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['object_id'] = Variable<int>(objectId);
{
map['object_type'] = Variable<String>(
$ObjectMediaItemsTable.$converterobjectType.toSql(objectType));
}
map['media_id'] = Variable<int>(mediaId);
map['created_at'] = Variable<DateTime>(createdAt);
return map;
@ -2077,6 +2096,7 @@ class ObjectMediaItem extends DataClass implements Insertable<ObjectMediaItem> {
return ObjectMediaItemsCompanion(
id: Value(id),
objectId: Value(objectId),
objectType: Value(objectType),
mediaId: Value(mediaId),
createdAt: Value(createdAt),
);
@ -2088,6 +2108,8 @@ class ObjectMediaItem extends DataClass implements Insertable<ObjectMediaItem> {
return ObjectMediaItem(
id: serializer.fromJson<int>(json['id']),
objectId: serializer.fromJson<int>(json['objectId']),
objectType: $ObjectMediaItemsTable.$converterobjectType
.fromJson(serializer.fromJson<String>(json['objectType'])),
mediaId: serializer.fromJson<int>(json['mediaId']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
);
@ -2098,16 +2120,23 @@ class ObjectMediaItem extends DataClass implements Insertable<ObjectMediaItem> {
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'objectId': serializer.toJson<int>(objectId),
'objectType': serializer.toJson<String>(
$ObjectMediaItemsTable.$converterobjectType.toJson(objectType)),
'mediaId': serializer.toJson<int>(mediaId),
'createdAt': serializer.toJson<DateTime>(createdAt),
};
}
ObjectMediaItem copyWith(
{int? id, int? objectId, int? mediaId, DateTime? createdAt}) =>
{int? id,
int? objectId,
ObjectType? objectType,
int? mediaId,
DateTime? createdAt}) =>
ObjectMediaItem(
id: id ?? this.id,
objectId: objectId ?? this.objectId,
objectType: objectType ?? this.objectType,
mediaId: mediaId ?? this.mediaId,
createdAt: createdAt ?? this.createdAt,
);
@ -2115,6 +2144,8 @@ class ObjectMediaItem extends DataClass implements Insertable<ObjectMediaItem> {
return ObjectMediaItem(
id: data.id.present ? data.id.value : this.id,
objectId: data.objectId.present ? data.objectId.value : this.objectId,
objectType:
data.objectType.present ? data.objectType.value : this.objectType,
mediaId: data.mediaId.present ? data.mediaId.value : this.mediaId,
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
);
@ -2125,6 +2156,7 @@ class ObjectMediaItem extends DataClass implements Insertable<ObjectMediaItem> {
return (StringBuffer('ObjectMediaItem(')
..write('id: $id, ')
..write('objectId: $objectId, ')
..write('objectType: $objectType, ')
..write('mediaId: $mediaId, ')
..write('createdAt: $createdAt')
..write(')'))
@ -2132,13 +2164,14 @@ class ObjectMediaItem extends DataClass implements Insertable<ObjectMediaItem> {
}
@override
int get hashCode => Object.hash(id, objectId, mediaId, createdAt);
int get hashCode => Object.hash(id, objectId, objectType, mediaId, createdAt);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is ObjectMediaItem &&
other.id == this.id &&
other.objectId == this.objectId &&
other.objectType == this.objectType &&
other.mediaId == this.mediaId &&
other.createdAt == this.createdAt);
}
@ -2146,30 +2179,36 @@ class ObjectMediaItem extends DataClass implements Insertable<ObjectMediaItem> {
class ObjectMediaItemsCompanion extends UpdateCompanion<ObjectMediaItem> {
final Value<int> id;
final Value<int> objectId;
final Value<ObjectType> objectType;
final Value<int> mediaId;
final Value<DateTime> createdAt;
const ObjectMediaItemsCompanion({
this.id = const Value.absent(),
this.objectId = const Value.absent(),
this.objectType = const Value.absent(),
this.mediaId = const Value.absent(),
this.createdAt = const Value.absent(),
});
ObjectMediaItemsCompanion.insert({
this.id = const Value.absent(),
required int objectId,
required ObjectType objectType,
required int mediaId,
this.createdAt = const Value.absent(),
}) : objectId = Value(objectId),
objectType = Value(objectType),
mediaId = Value(mediaId);
static Insertable<ObjectMediaItem> custom({
Expression<int>? id,
Expression<int>? objectId,
Expression<String>? objectType,
Expression<int>? mediaId,
Expression<DateTime>? createdAt,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (objectId != null) 'object_id': objectId,
if (objectType != null) 'object_type': objectType,
if (mediaId != null) 'media_id': mediaId,
if (createdAt != null) 'created_at': createdAt,
});
@ -2178,11 +2217,13 @@ class ObjectMediaItemsCompanion extends UpdateCompanion<ObjectMediaItem> {
ObjectMediaItemsCompanion copyWith(
{Value<int>? id,
Value<int>? objectId,
Value<ObjectType>? objectType,
Value<int>? mediaId,
Value<DateTime>? createdAt}) {
return ObjectMediaItemsCompanion(
id: id ?? this.id,
objectId: objectId ?? this.objectId,
objectType: objectType ?? this.objectType,
mediaId: mediaId ?? this.mediaId,
createdAt: createdAt ?? this.createdAt,
);
@ -2197,6 +2238,10 @@ class ObjectMediaItemsCompanion extends UpdateCompanion<ObjectMediaItem> {
if (objectId.present) {
map['object_id'] = Variable<int>(objectId.value);
}
if (objectType.present) {
map['object_type'] = Variable<String>(
$ObjectMediaItemsTable.$converterobjectType.toSql(objectType.value));
}
if (mediaId.present) {
map['media_id'] = Variable<int>(mediaId.value);
}
@ -2211,6 +2256,7 @@ class ObjectMediaItemsCompanion extends UpdateCompanion<ObjectMediaItem> {
return (StringBuffer('ObjectMediaItemsCompanion(')
..write('id: $id, ')
..write('objectId: $objectId, ')
..write('objectType: $objectType, ')
..write('mediaId: $mediaId, ')
..write('createdAt: $createdAt')
..write(')'))
@ -2231,6 +2277,8 @@ abstract class _$AppDatabase extends GeneratedDatabase {
late final $MediaItemsTable mediaItems = $MediaItemsTable(this);
late final $ObjectMediaItemsTable objectMediaItems =
$ObjectMediaItemsTable(this);
late final SessionsDao sessionsDao = SessionsDao(this as AppDatabase);
late final ActivitiesDao activitiesDao = ActivitiesDao(this as AppDatabase);
@override
Iterable<TableInfo<Table, Object?>> get allTables =>
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
@ -3254,23 +3302,6 @@ final class $$ActionsTableReferences
return ProcessedTableManager(
manager.$state.copyWith(prefetchedData: cache));
}
static MultiTypedResultKey<$ObjectMediaItemsTable, List<ObjectMediaItem>>
_objectMediaItemsRefsTable(_$AppDatabase db) =>
MultiTypedResultKey.fromTable(db.objectMediaItems,
aliasName: $_aliasNameGenerator(
db.actions.id, db.objectMediaItems.objectId));
$$ObjectMediaItemsTableProcessedTableManager get objectMediaItemsRefs {
final manager =
$$ObjectMediaItemsTableTableManager($_db, $_db.objectMediaItems)
.filter((f) => f.objectId.id($_item.id));
final cache =
$_typedResult.readTableOrNull(_objectMediaItemsRefsTable($_db));
return ProcessedTableManager(
manager.$state.copyWith(prefetchedData: cache));
}
}
class $$ActionsTableFilterComposer
@ -3317,27 +3348,6 @@ class $$ActionsTableFilterComposer
));
return f(composer);
}
Expression<bool> objectMediaItemsRefs(
Expression<bool> Function($$ObjectMediaItemsTableFilterComposer f) f) {
final $$ObjectMediaItemsTableFilterComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.id,
referencedTable: $db.objectMediaItems,
getReferencedColumn: (t) => t.objectId,
builder: (joinBuilder,
{$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer}) =>
$$ObjectMediaItemsTableFilterComposer(
$db: $db,
$table: $db.objectMediaItems,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
));
return f(composer);
}
}
class $$ActionsTableOrderingComposer
@ -3409,27 +3419,6 @@ class $$ActionsTableAnnotationComposer
));
return f(composer);
}
Expression<T> objectMediaItemsRefs<T extends Object>(
Expression<T> Function($$ObjectMediaItemsTableAnnotationComposer a) f) {
final $$ObjectMediaItemsTableAnnotationComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.id,
referencedTable: $db.objectMediaItems,
getReferencedColumn: (t) => t.objectId,
builder: (joinBuilder,
{$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer}) =>
$$ObjectMediaItemsTableAnnotationComposer(
$db: $db,
$table: $db.objectMediaItems,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
));
return f(composer);
}
}
class $$ActionsTableTableManager extends RootTableManager<
@ -3443,8 +3432,7 @@ class $$ActionsTableTableManager extends RootTableManager<
$$ActionsTableUpdateCompanionBuilder,
(Action, $$ActionsTableReferences),
Action,
PrefetchHooks Function(
{bool activityActionsRefs, bool objectMediaItemsRefs})> {
PrefetchHooks Function({bool activityActionsRefs})> {
$$ActionsTableTableManager(_$AppDatabase db, $ActionsTable table)
: super(TableManagerState(
db: db,
@ -3487,13 +3475,11 @@ class $$ActionsTableTableManager extends RootTableManager<
.map((e) =>
(e.readTable(table), $$ActionsTableReferences(db, table, e)))
.toList(),
prefetchHooksCallback: (
{activityActionsRefs = false, objectMediaItemsRefs = false}) {
prefetchHooksCallback: ({activityActionsRefs = false}) {
return PrefetchHooks(
db: db,
explicitlyWatchedTables: [
if (activityActionsRefs) db.activityActions,
if (objectMediaItemsRefs) db.objectMediaItems
if (activityActionsRefs) db.activityActions
],
addJoins: null,
getPrefetchedDataCallback: (items) async {
@ -3509,18 +3495,6 @@ class $$ActionsTableTableManager extends RootTableManager<
referencedItemsForCurrentItem: (item,
referencedItems) =>
referencedItems.where((e) => e.actionId == item.id),
typedResults: items),
if (objectMediaItemsRefs)
await $_getPrefetchedData(
currentTable: table,
referencedTable: $$ActionsTableReferences
._objectMediaItemsRefsTable(db),
managerFromTypedResult: (p0) =>
$$ActionsTableReferences(db, table, p0)
.objectMediaItemsRefs,
referencedItemsForCurrentItem: (item,
referencedItems) =>
referencedItems.where((e) => e.objectId == item.id),
typedResults: items)
];
},
@ -3540,8 +3514,7 @@ typedef $$ActionsTableProcessedTableManager = ProcessedTableManager<
$$ActionsTableUpdateCompanionBuilder,
(Action, $$ActionsTableReferences),
Action,
PrefetchHooks Function(
{bool activityActionsRefs, bool objectMediaItemsRefs})>;
PrefetchHooks Function({bool activityActionsRefs})>;
typedef $$ActivityActionsTableCreateCompanionBuilder = ActivityActionsCompanion
Function({
Value<int> id,
@ -4142,6 +4115,7 @@ typedef $$ObjectMediaItemsTableCreateCompanionBuilder
= ObjectMediaItemsCompanion Function({
Value<int> id,
required int objectId,
required ObjectType objectType,
required int mediaId,
Value<DateTime> createdAt,
});
@ -4149,6 +4123,7 @@ typedef $$ObjectMediaItemsTableUpdateCompanionBuilder
= ObjectMediaItemsCompanion Function({
Value<int> id,
Value<int> objectId,
Value<ObjectType> objectType,
Value<int> mediaId,
Value<DateTime> createdAt,
});
@ -4158,19 +4133,6 @@ final class $$ObjectMediaItemsTableReferences extends BaseReferences<
$$ObjectMediaItemsTableReferences(
super.$_db, super.$_table, super.$_typedResult);
static $ActionsTable _objectIdTable(_$AppDatabase db) =>
db.actions.createAlias(
$_aliasNameGenerator(db.objectMediaItems.objectId, db.actions.id));
$$ActionsTableProcessedTableManager get objectId {
final manager = $$ActionsTableTableManager($_db, $_db.actions)
.filter((f) => f.id($_item.objectId!));
final item = $_typedResult.readTableOrNull(_objectIdTable($_db));
if (item == null) return manager;
return ProcessedTableManager(
manager.$state.copyWith(prefetchedData: [item]));
}
static $MediaItemsTable _mediaIdTable(_$AppDatabase db) =>
db.mediaItems.createAlias(
$_aliasNameGenerator(db.objectMediaItems.mediaId, db.mediaItems.id));
@ -4197,29 +4159,17 @@ class $$ObjectMediaItemsTableFilterComposer
ColumnFilters<int> get id => $composableBuilder(
column: $table.id, builder: (column) => ColumnFilters(column));
ColumnFilters<int> get objectId => $composableBuilder(
column: $table.objectId, builder: (column) => ColumnFilters(column));
ColumnWithTypeConverterFilters<ObjectType, ObjectType, String>
get objectType => $composableBuilder(
column: $table.objectType,
builder: (column) => ColumnWithTypeConverterFilters(column));
ColumnFilters<DateTime> get createdAt => $composableBuilder(
column: $table.createdAt, builder: (column) => ColumnFilters(column));
$$ActionsTableFilterComposer get objectId {
final $$ActionsTableFilterComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.objectId,
referencedTable: $db.actions,
getReferencedColumn: (t) => t.id,
builder: (joinBuilder,
{$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer}) =>
$$ActionsTableFilterComposer(
$db: $db,
$table: $db.actions,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
));
return composer;
}
$$MediaItemsTableFilterComposer get mediaId {
final $$MediaItemsTableFilterComposer composer = $composerBuilder(
composer: this,
@ -4253,29 +4203,15 @@ class $$ObjectMediaItemsTableOrderingComposer
ColumnOrderings<int> get id => $composableBuilder(
column: $table.id, builder: (column) => ColumnOrderings(column));
ColumnOrderings<int> get objectId => $composableBuilder(
column: $table.objectId, builder: (column) => ColumnOrderings(column));
ColumnOrderings<String> get objectType => $composableBuilder(
column: $table.objectType, builder: (column) => ColumnOrderings(column));
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
column: $table.createdAt, builder: (column) => ColumnOrderings(column));
$$ActionsTableOrderingComposer get objectId {
final $$ActionsTableOrderingComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.objectId,
referencedTable: $db.actions,
getReferencedColumn: (t) => t.id,
builder: (joinBuilder,
{$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer}) =>
$$ActionsTableOrderingComposer(
$db: $db,
$table: $db.actions,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
));
return composer;
}
$$MediaItemsTableOrderingComposer get mediaId {
final $$MediaItemsTableOrderingComposer composer = $composerBuilder(
composer: this,
@ -4309,29 +4245,16 @@ class $$ObjectMediaItemsTableAnnotationComposer
GeneratedColumn<int> get id =>
$composableBuilder(column: $table.id, builder: (column) => column);
GeneratedColumn<int> get objectId =>
$composableBuilder(column: $table.objectId, builder: (column) => column);
GeneratedColumnWithTypeConverter<ObjectType, String> get objectType =>
$composableBuilder(
column: $table.objectType, builder: (column) => column);
GeneratedColumn<DateTime> get createdAt =>
$composableBuilder(column: $table.createdAt, builder: (column) => column);
$$ActionsTableAnnotationComposer get objectId {
final $$ActionsTableAnnotationComposer composer = $composerBuilder(
composer: this,
getCurrentColumn: (t) => t.objectId,
referencedTable: $db.actions,
getReferencedColumn: (t) => t.id,
builder: (joinBuilder,
{$addJoinBuilderToRootComposer,
$removeJoinBuilderFromRootComposer}) =>
$$ActionsTableAnnotationComposer(
$db: $db,
$table: $db.actions,
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
joinBuilder: joinBuilder,
$removeJoinBuilderFromRootComposer:
$removeJoinBuilderFromRootComposer,
));
return composer;
}
$$MediaItemsTableAnnotationComposer get mediaId {
final $$MediaItemsTableAnnotationComposer composer = $composerBuilder(
composer: this,
@ -4364,7 +4287,7 @@ class $$ObjectMediaItemsTableTableManager extends RootTableManager<
$$ObjectMediaItemsTableUpdateCompanionBuilder,
(ObjectMediaItem, $$ObjectMediaItemsTableReferences),
ObjectMediaItem,
PrefetchHooks Function({bool objectId, bool mediaId})> {
PrefetchHooks Function({bool mediaId})> {
$$ObjectMediaItemsTableTableManager(
_$AppDatabase db, $ObjectMediaItemsTable table)
: super(TableManagerState(
@ -4379,24 +4302,28 @@ class $$ObjectMediaItemsTableTableManager extends RootTableManager<
updateCompanionCallback: ({
Value<int> id = const Value.absent(),
Value<int> objectId = const Value.absent(),
Value<ObjectType> objectType = const Value.absent(),
Value<int> mediaId = const Value.absent(),
Value<DateTime> createdAt = const Value.absent(),
}) =>
ObjectMediaItemsCompanion(
id: id,
objectId: objectId,
objectType: objectType,
mediaId: mediaId,
createdAt: createdAt,
),
createCompanionCallback: ({
Value<int> id = const Value.absent(),
required int objectId,
required ObjectType objectType,
required int mediaId,
Value<DateTime> createdAt = const Value.absent(),
}) =>
ObjectMediaItemsCompanion.insert(
id: id,
objectId: objectId,
objectType: objectType,
mediaId: mediaId,
createdAt: createdAt,
),
@ -4406,7 +4333,7 @@ class $$ObjectMediaItemsTableTableManager extends RootTableManager<
$$ObjectMediaItemsTableReferences(db, table, e)
))
.toList(),
prefetchHooksCallback: ({objectId = false, mediaId = false}) {
prefetchHooksCallback: ({mediaId = false}) {
return PrefetchHooks(
db: db,
explicitlyWatchedTables: [],
@ -4423,16 +4350,6 @@ class $$ObjectMediaItemsTableTableManager extends RootTableManager<
dynamic,
dynamic,
dynamic>>(state) {
if (objectId) {
state = state.withJoin(
currentTable: table,
currentColumn: table.objectId,
referencedTable:
$$ObjectMediaItemsTableReferences._objectIdTable(db),
referencedColumn:
$$ObjectMediaItemsTableReferences._objectIdTable(db).id,
) as T;
}
if (mediaId) {
state = state.withJoin(
currentTable: table,
@ -4465,7 +4382,7 @@ typedef $$ObjectMediaItemsTableProcessedTableManager = ProcessedTableManager<
$$ObjectMediaItemsTableUpdateCompanionBuilder,
(ObjectMediaItem, $$ObjectMediaItemsTableReferences),
ObjectMediaItem,
PrefetchHooks Function({bool objectId, bool mediaId})>;
PrefetchHooks Function({bool mediaId})>;
class $AppDatabaseManager {
final _$AppDatabase _db;

160
lib/database/seed.dart Normal file
View File

@ -0,0 +1,160 @@
import 'dart:math';
import 'package:drift/drift.dart';
import 'package:sendtrain/database/database.dart';
void seedDb() {
final database = AppDatabase();
// seed data setup
final List<List> sessionValues = [
[
'Projecting @ Climbers Rock',
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
],
[
'Moonboard @ Boardroom',
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
],
[
'Off-Wall Training',
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
],
[
'Climbing Outdoors',
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
],
[
'Volume Session @ Gravity',
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
],
];
final List<List> mediaItems = [
[
'https://www.climbing.com/wp-content/uploads/2022/06/campus-board-e1655470701154.jpeg',
MediaType.image
],
['BgheYcxhrsw', MediaType.youtube]
];
final int totalSessions = 15;
final int totalActivities = 6;
final int totalActions = 5;
final int totalMedia = 5;
final random = Random();
// seed loop
for (int i = 0; i < totalSessions; i++) {
// session things
var status = SessionStatus.completed;
if (i == 0) status = SessionStatus.started;
if (i == 1) status = SessionStatus.pending;
final sessionValue =
sessionValues[random.nextInt(sessionValues.length)];
database
.into(database.sessions)
.insert(SessionsCompanion.insert(
title: sessionValue[0],
content: sessionValue[1],
status: status,
date: Value(DateTime.now())))
.then((sessionId) {
// activities things
for (int j = 0; j < random.nextInt(totalActivities); j++) {
database
.into(database.activities)
.insert(ActivitiesCompanion.insert(
title: "test activity $j",
type: ActivityType
.values[random.nextInt(ActivityType.values.length)],
description: "test training activity $j",
category: ActivityCategories.values[
random.nextInt(ActivityCategories.values.length)]))
.then((activityId) {
// session activity relationships
database
.into(database.sessionActivities)
.insert(SessionActivitiesCompanion.insert(
sessionId: sessionId,
activityId: activityId,
results: Value("results json, will need to test"),
achievements: Value("comma, seperated, items"),
));
// actions
for (int k = 0; k < random.nextInt(totalActions); k++) {
database
.into(database.actions)
.insert(ActionsCompanion.insert(
title: 'test action $k',
description: 'test action description $k',
set: ''))
.then((actionId) {
// add activity action association
database.into(database.activityActions).insert(
ActivityActionsCompanion.insert(
activityId: activityId, actionId: actionId));
for (int l = 0; l < random.nextInt(totalMedia); l++) {
final mediaItem =
mediaItems[random.nextInt(mediaItems.length)];
database
.into(database.mediaItems)
.insert(MediaItemsCompanion.insert(
title: 'media title $l',
description: 'media description $l',
reference: mediaItem[0],
type: mediaItem[1]))
.then((mediaId) {
database.into(database.objectMediaItems).insert(
ObjectMediaItemsCompanion.insert(
objectId: actionId,
mediaId: mediaId,
objectType: ObjectType.actions));
});
}
});
}
for (int l = 0; l < random.nextInt(totalMedia); l++) {
final mediaItem = mediaItems[random.nextInt(mediaItems.length)];
database
.into(database.mediaItems)
.insert(MediaItemsCompanion.insert(
title: 'media title $l',
description: 'media description $l',
reference: mediaItem[0],
type: mediaItem[1]))
.then((mediaId) {
database.into(database.objectMediaItems).insert(
ObjectMediaItemsCompanion.insert(
objectId: activityId,
mediaId: mediaId,
objectType: ObjectType.activities));
});
}
});
}
for (int l = 0; l < random.nextInt(totalMedia); l++) {
final mediaItem = mediaItems[random.nextInt(mediaItems.length)];
database
.into(database.mediaItems)
.insert(MediaItemsCompanion.insert(
title: 'media title $l',
description: 'media description $l',
reference: mediaItem[0],
type: mediaItem[1]))
.then((mediaId) {
database.into(database.objectMediaItems).insert(
ObjectMediaItemsCompanion.insert(
objectId: sessionId,
mediaId: mediaId,
objectType: ObjectType.sessions));
});
}
});
}
}

View File

@ -1,16 +1,17 @@
import 'package:drift/drift.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:sendtrain/database.dart';
import 'package:sendtrain/models/activity_timer_model.dart';
import 'package:sendtrain/screens/activities_screen.dart';
import 'package:sendtrain/screens/sessions_screen.dart';
// ignore: unused_import
import 'package:sendtrain/database/seed.dart';
class SendTrain extends StatelessWidget {
const SendTrain({super.key});
@override
Widget build(BuildContext context) {
// seedDb();
return MaterialApp(
title: "Sendtrain",
theme: ThemeData.dark(useMaterial3: true),
@ -92,82 +93,6 @@ class _AppState extends State<App> {
}
void main() {
// final database = AppDatabase();
// database.into(database.sessions).insert(SessionsCompanion.insert(
// title: 'Projecting @ Climbers Rock',
// content: 'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
// status: SessionStatus.started,
// date: Value(DateTime.now())));
// database.into(database.sessions).insert(SessionsCompanion.insert(
// title: 'Moonboard @ Boardroom',
// content: 'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
// status: SessionStatus.pending,
// date: Value(DateTime.now())));
// database.into(database.sessions).insert(SessionsCompanion.insert(
// title: 'Moonboard @ Boardroom',
// content: 'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
// status: SessionStatus.completed,
// date: Value(DateTime.now())));
// database.into(database.sessions).insert(SessionsCompanion.insert(
// title: 'Projecting @ Climbers Rock',
// content: 'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
// status: SessionStatus.completed,
// date: Value(DateTime.now())));
// database.into(database.sessions).insert(SessionsCompanion.insert(
// title: 'Off-Wall Training',
// content: 'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
// status: SessionStatus.missed,
// date: Value(DateTime.now())));
// database.into(database.sessions).insert(SessionsCompanion.insert(
// title: 'Off-Wall Training',
// content: 'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
// status: SessionStatus.completed,
// date: Value(DateTime.now())));
// database.into(database.activities).insert(ActivitiesCompanion.insert(
// title: "test activity",
// type: ActivityType.technical,
// description: "test training activity",
// category: ActivityCategories.fundamentals));
// database
// .into(database.sessionActivities)
// .insert(SessionActivitiesCompanion.insert(
// sessionId: 1,
// activityId: 1,
// results: Value("results json, will need to test"),
// achievements: Value("comma, seperated, items"),
// ));
// database.into(database.actions).insert(ActionsCompanion.insert(
// title: "test action title",
// description: "teste action description",
// set: "not sure how the json will work yet",
// ));
// database
// .into(database.activityActions)
// .insert(ActivityActionsCompanion.insert(
// activityId: 1,
// actionId: 1,
// ));
// database.into(database.mediaItems).insert(MediaItemsCompanion.insert(
// title: "test youtube media item",
// description: "this is a test youtube item",
// reference: "sZVAEy9UmoY",
// type: MediaType.youtube));
// database
// .into(database.objectMediaItems)
// .insert(ObjectMediaItemsCompanion.insert(objectId: 1, mediaId: 1));
runApp(
ChangeNotifierProvider(
create: (context) => ActivityTimerModel(),

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:sendtrain/classes/activity_action.dart';
import 'package:sendtrain/database/database.dart' hide ActivityAction;
import 'package:sendtrain/models/activity_model.dart';
import '../widgets/activities_header.dart';
@ -13,6 +14,7 @@ class ActivitiesScreen extends StatefulWidget {
}
class _ActivitiesScreenState extends State<ActivitiesScreen> {
final Activity? activity = null;
final data = ActivityModel(
id: 1,
@ -40,23 +42,24 @@ class _ActivitiesScreenState extends State<ActivitiesScreen> {
@override
Widget build(BuildContext context) {
List<Widget> activities = List.generate(10, (i) => ActivityCard(activity: data));
return Text("N/A");
// List<Widget> activities = List.generate(10, (i) => ActivityCard(activity: data, data: activity));
return Padding(
padding: const EdgeInsets.fromLTRB(10, 15, 10, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const ActivitiesHeader(),
Expanded(
child: GridView.count(
primary: false,
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 2,
children: activities,
))
]));
// return Padding(
// padding: const EdgeInsets.fromLTRB(10, 15, 10, 0),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// const ActivitiesHeader(),
// Expanded(
// child: GridView.count(
// primary: false,
// padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
// crossAxisSpacing: 10,
// mainAxisSpacing: 10,
// crossAxisCount: 2,
// children: activities,
// ))
// ]));
}
}

View File

@ -1,31 +1,31 @@
import 'package:drift/drift.dart' hide Column;
import 'package:flutter/material.dart';
import 'package:sendtrain/database.dart';
import 'package:sendtrain/database/daos/sessions_dao.dart';
import 'package:sendtrain/database/database.dart';
import '../widgets/session_card.dart';
class SessionsScreen extends StatelessWidget {
final AppDatabase database = AppDatabase();
SessionsScreen({super.key});
Future<List<Session>> getSessions() async {
// database.managers.sessions.filter((session) => session.status(SessionStatus.pending));
return await database.managers.sessions.get();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<Session>>(
future: getSessions(),
future: SessionsDao(database).all(),
builder: (context, snapshot) {
if (snapshot.hasData) {
database.close();
final sessions = snapshot.data!;
final pending = sessions.where((session) => session.status == SessionStatus.completed || session.status == SessionStatus.missed);
final upcoming = sessions.firstWhere((session) => session.status == SessionStatus.pending);
final current = sessions.firstWhere((session) => session.status == SessionStatus.started);
final pending = sessions.where((session) =>
session.status == SessionStatus.completed ||
session.status == SessionStatus.missed);
final upcoming = sessions.firstWhere(
(session) => session.status == SessionStatus.pending);
final current = sessions.firstWhere(
(session) => session.status == SessionStatus.started);
List<Widget> previousSessions = List.generate(pending.length, (i) => SessionCard(type: 1, session: pending.elementAt(i)));
Widget upcomingSession =
SessionCard(session: upcoming);
List<Widget> previousSessions = List.generate(pending.length,
(i) => SessionCard(type: 1, session: pending.elementAt(i)));
Widget upcomingSession = SessionCard(session: upcoming);
Widget currentSession = SessionCard(session: current);
database.close();
@ -36,19 +36,22 @@ class SessionsScreen extends StatelessWidget {
const Padding(
padding: EdgeInsets.fromLTRB(15, 5, 0, 0),
child: Text(
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
style: TextStyle(
fontSize: 25, fontWeight: FontWeight.bold),
'Current:')),
currentSession,
const Padding(
padding: EdgeInsets.fromLTRB(15, 30, 0, 0),
child: Text(
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
style: TextStyle(
fontSize: 25, fontWeight: FontWeight.bold),
'Upcoming:')),
upcomingSession,
const Padding(
padding: EdgeInsets.fromLTRB(15, 30, 0, 0),
child: Text(
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
style: TextStyle(
fontSize: 25, fontWeight: FontWeight.bold),
'Previous:')),
SizedBox(
width: double.infinity,
@ -66,48 +69,5 @@ class SessionsScreen extends StatelessWidget {
return const CircularProgressIndicator();
}
});
// List<Widget> previousSessions = List.generate(
// 10, (i) => SessionCard(state: 1, type: 1, session: _sessions.first));
// Widget upcomingSession = SessionCard(state: 2, session: _sessions.first);
// Widget currentSession = SessionCard(session: _sessions.first);
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: <Widget>[
// const Padding(
// padding: EdgeInsets.fromLTRB(15, 5, 0, 0),
// child: Text(
// style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
// 'Current:')),
// currentSession,
// const Padding(
// padding: EdgeInsets.fromLTRB(15, 30, 0, 0),
// child: Text(
// style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
// 'Upcoming:')),
// upcomingSession,
// const Padding(
// padding: EdgeInsets.fromLTRB(15, 30, 0, 0),
// child: Text(
// style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
// 'Previous:')),
// SizedBox(
// width: double.infinity,
// height: 160,
// child: GridView.count(
// padding: const EdgeInsets.fromLTRB(15, 10, 0, 0),
// scrollDirection: Axis.horizontal,
// crossAxisSpacing: 5,
// mainAxisSpacing: 5,
// crossAxisCount: 1,
// children: previousSessions))
// // Flexible(
// // child: ListView(
// // scrollDirection: Axis.vertical,
// // children: previousSessions,
// // )),
// ],
// );
}
}

View File

@ -1,14 +1,16 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:sendtrain/classes/media.dart';
import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/models/activity_model.dart';
import 'package:sendtrain/models/activity_timer_model.dart';
import 'package:sendtrain/widgets/activity_view.dart';
class ActivityCard extends StatefulWidget {
final ActivityModel activity;
final Activity data;
const ActivityCard({super.key, required this.activity});
const ActivityCard({super.key, required this.activity, required this.data});
@override
State<ActivityCard> createState() => ActivityCardState();
@ -34,28 +36,28 @@ class ActivityCardState extends State<ActivityCard> {
: Theme.of(context).colorScheme.surfaceContainerLow,
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: () => showGeneralDialog(
barrierColor: Colors.black.withOpacity(0.5),
transitionDuration: const Duration(milliseconds: 220),
transitionBuilder: (BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
Animation<Offset> custom = Tween<Offset>(
begin: const Offset(0.0, 1.0),
end: const Offset(0.0, 0.0))
.animate(animation);
return SlideTransition(
position: custom,
child: Dialog.fullscreen(
child: ActivityView(activity: widget.activity)));
},
barrierDismissible: true,
barrierLabel: '',
context: context,
pageBuilder: (context, animation1, animation2) {
return Container();
}),
// onTap: () => showGeneralDialog(
// barrierColor: Colors.black.withOpacity(0.5),
// transitionDuration: const Duration(milliseconds: 220),
// transitionBuilder: (BuildContext context,
// Animation<double> animation,
// Animation<double> secondaryAnimation,
// Widget child) {
// Animation<Offset> custom = Tween<Offset>(
// begin: const Offset(0.0, 1.0),
// end: const Offset(0.0, 0.0))
// .animate(animation);
// return SlideTransition(
// position: custom,
// child: Dialog.fullscreen(
// child: ActivityView(activity: widget.activity)));
// },
// barrierDismissible: true,
// barrierLabel: '',
// context: context,
// pageBuilder: (context, animation1, animation2) {
// return Container();
// }),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
@ -79,13 +81,13 @@ class ActivityCardState extends State<ActivityCard> {
if (atm.activity?.id == widget.activity.id) {
return Text(
maxLines: 1,
"${widget.activity.title} (${formattedTime(atm.totalTime)})");
"${widget.data.title} (${formattedTime(atm.totalTime)})");
} else {
return Text(maxLines: 1, widget.activity.title);
return Text(maxLines: 1, widget.data.title);
}
},
),
subtitle: Text(maxLines: 2, widget.activity.description),
subtitle: Text(maxLines: 2, widget.data.description),
trailing: IconButton(
visualDensity: VisualDensity.compact,
icon: Icon(Icons.close_rounded),

View File

@ -193,22 +193,23 @@ class ActivityViewMedia extends StatelessWidget {
}
}
List<Widget> mediaCards =
List.generate(media.length, (i) => MediaCard(media: media[i]));
return Text("media!");
// List<Widget> mediaCards =
// List.generate(media.length, (i) => MediaCard(media: media[i]));
return Column(
children: [
SizedBox(
width: double.infinity,
height: 100,
child: GridView.count(
padding: const EdgeInsets.fromLTRB(15, 0, 0, 0),
scrollDirection: Axis.horizontal,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
crossAxisCount: 1,
children: mediaCards))
],
);
// return Column(
// children: [
// SizedBox(
// width: double.infinity,
// height: 100,
// child: GridView.count(
// padding: const EdgeInsets.fromLTRB(15, 0, 0, 0),
// scrollDirection: Axis.horizontal,
// crossAxisSpacing: 5,
// mainAxisSpacing: 5,
// crossAxisCount: 1,
// children: mediaCards))
// ],
// );
}
}

View File

@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:sendtrain/classes/media.dart';
import 'package:sendtrain/database/database.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
class MediaCard extends StatelessWidget {
const MediaCard({super.key, required this.media});
final Media media;
final MediaItem media;
@override
Widget build(BuildContext context) {
@ -14,22 +14,22 @@ class MediaCard extends StatelessWidget {
flags: const YoutubePlayerFlags(
autoPlay: false, mute: true, showLiveFullscreenButton: false));
DecorationImage mediaImage(Media media) {
DecorationImage mediaImage(MediaItem media) {
String image = '';
if (media.type == "image") {
if (media.type == MediaType.image) {
image = media.reference;
} else if (media.type == "youtube") {
} else if (media.type == MediaType.youtube) {
image = 'https://img.youtube.com/vi/${media.reference}/0.jpg';
}
return DecorationImage(image: NetworkImage(image), fit: BoxFit.cover);
}
Widget mediaItem(Media media) {
if (media.type == "image") {
Widget mediaItem(MediaItem media) {
if (media.type == MediaType.image) {
return Image(image: NetworkImage(media.reference));
} else if (media.type == "youtube") {
} else if (media.type == MediaType.youtube) {
return YoutubePlayer(
controller: controller,
aspectRatio: 16 / 9,
@ -62,7 +62,7 @@ class MediaCard extends StatelessWidget {
mediaItem(media),
const SizedBox(height: 15),
Text(
'${media.description}',
media.description,
style: const TextStyle(fontSize: 20),
),
const Divider(

View File

@ -3,7 +3,7 @@ import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:sendtrain/classes/activity_action.dart';
import 'package:sendtrain/classes/media.dart';
import 'package:sendtrain/database.dart' hide ActivityAction;
import 'package:sendtrain/database/database.dart' hide ActivityAction;
import 'package:sendtrain/models/activity_model.dart';
import 'package:sendtrain/models/session_model.dart';
import 'package:sendtrain/widgets/session_view.dart';

View File

@ -1,165 +1,103 @@
import 'package:drift/drift.dart' hide Column;
import 'package:flutter/material.dart';
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:sendtrain/database/daos/activities_dao.dart';
import 'package:sendtrain/classes/media.dart';
import 'package:sendtrain/database.dart';
import 'package:sendtrain/models/activity_model.dart';
import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/models/session_model.dart';
import 'package:sendtrain/widgets/activity_card.dart';
import 'package:sendtrain/widgets/media_card.dart';
import 'package:sendtrain/widgets/session_view_achievements.dart';
import 'package:sendtrain/widgets/session_view_activities.dart';
import 'package:sendtrain/widgets/session_view_media.dart';
class SessionView extends StatelessWidget {
const SessionView({super.key, required this.data, required this.session});
SessionView({super.key, required this.data, required this.session});
final SessionModel data;
final Session session;
final AppDatabase database = AppDatabase();
@override
Widget build(BuildContext context) {
initializeDateFormatting('en');
final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
return Scaffold(
floatingActionButtonLocation: ExpandableFab.location,
floatingActionButton: ExpandableFab(
distance: 70,
type: ExpandableFabType.up,
overlayStyle: ExpandableFabOverlayStyle(
color: Colors.black.withOpacity(0.5),
blur: 10,
),
children: [
FloatingActionButton.extended(
icon: const Icon(Icons.history_outlined),
label: Text('Restart'),
onPressed: () {},
),
FloatingActionButton.extended(
icon: const Icon(Icons.done_all_outlined),
label: Text('Done'),
onPressed: () {},
),
FloatingActionButton.extended(
icon: const Icon(Icons.edit_outlined),
label: Text('Edit'),
onPressed: () {},
),
]),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
AppBar(
centerTitle: true,
title: Text('Session @ ${dateFormat.format(session.date as DateTime)}',
style: const TextStyle(fontSize: 15)),
),
Padding(
padding: const EdgeInsets.only(
left: 15, right: 20, top: 15, bottom: 10),
child: Text(
maxLines: 1,
style: const TextStyle(
fontSize: 25, fontWeight: FontWeight.bold),
session.title)),
SessionViewAchievements(achievements: data.achievements),
Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child:
Text(style: const TextStyle(fontSize: 15), session.content)),
const Padding(
padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
child: Text(
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
'Media:')),
SessionViewMedia(media: data.media),
const Padding(
padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
child: Text(
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
'Activites:')),
SessionViewActivities(activities: data.activities),
],
));
}
}
class SessionViewActivities extends StatelessWidget {
const SessionViewActivities({super.key, this.activities});
final List<ActivityModel>? activities;
@override
Widget build(BuildContext context) {
return Expanded(
child: ListView.builder(
// shrinkWrap: true,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
itemCount: activities?.length,
itemBuilder: (BuildContext context, int index) {
return ActivityCard(activity: activities![index]);
},
));
}
}
class SessionViewAchievements extends StatelessWidget {
const SessionViewAchievements({super.key, this.achievements});
final List<String>? achievements;
@override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: SizedBox(
height: 40,
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
itemCount: achievements?.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(right: 5),
child: ActionChip(
visualDensity: VisualDensity.compact,
avatar: const Icon(Icons.check_circle_outline),
label: Text(maxLines: 1, '${achievements?[index]}'),
onPressed: () {},
));
},
))),
],
);
}
}
class SessionViewMedia extends StatelessWidget {
const SessionViewMedia({super.key, this.media});
final List<Media>? media;
@override
Widget build(BuildContext context) {
List<Widget> mediaCards = List.generate((media != null) ? media!.length : 0,
(i) => MediaCard(media: media![i]));
return Column(
children: [
SizedBox(
width: double.infinity,
height: 100,
child: GridView.count(
padding: const EdgeInsets.fromLTRB(15, 0, 0, 0),
scrollDirection: Axis.horizontal,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
crossAxisCount: 1,
children: mediaCards))
],
);
return FutureBuilder<List<Activity>>(
future: ActivitiesDao(database).sessionActivities(session.id),
builder: (context, snapshot) {
if (snapshot.hasData) {
final activities = snapshot.data!;
database.close();
return Scaffold(
floatingActionButtonLocation: ExpandableFab.location,
floatingActionButton: ExpandableFab(
distance: 70,
type: ExpandableFabType.up,
overlayStyle: ExpandableFabOverlayStyle(
color: Colors.black.withOpacity(0.5),
blur: 10,
),
children: [
FloatingActionButton.extended(
icon: const Icon(Icons.history_outlined),
label: Text('Restart'),
onPressed: () {},
),
FloatingActionButton.extended(
icon: const Icon(Icons.done_all_outlined),
label: Text('Done'),
onPressed: () {},
),
FloatingActionButton.extended(
icon: const Icon(Icons.edit_outlined),
label: Text('Edit'),
onPressed: () {},
),
]),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
AppBar(
centerTitle: true,
title: Text(
'Session @ ${dateFormat.format(session.date as DateTime)}',
style: const TextStyle(fontSize: 15)),
),
Padding(
padding: const EdgeInsets.only(
left: 15, right: 20, top: 15, bottom: 10),
child: Text(
maxLines: 1,
style: const TextStyle(
fontSize: 25, fontWeight: FontWeight.bold),
session.title)),
SessionViewAchievements(session: session),
Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Text(
style: const TextStyle(fontSize: 15),
session.content)),
const Padding(
padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
child: Text(
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
'Media:')),
SessionViewMedia(session: session, media: data.media),
const Padding(
padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
child: Text(
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
'Activites:')),
SessionViewActivities(
activities: data.activities, data: activities),
],
));
} else {
return const CircularProgressIndicator();
}
});
}
}

View File

@ -0,0 +1,65 @@
import 'package:flutter/material.dart';
import 'package:sendtrain/database/daos/session_activities_dao.dart';
import 'package:sendtrain/database/database.dart';
class SessionViewAchievements extends StatelessWidget {
SessionViewAchievements({super.key, required this.session});
final Session session;
final AppDatabase database = AppDatabase();
List<String> getAchievements(List<SessionActivity> sessionActivities) {
List<String> achievements = [];
for (int i = 0; i < sessionActivities.length; i++) {
final SessionActivity sessionActivity = sessionActivities[i];
final List? saAchievments = sessionActivity.achievements?.split(',');
if (saAchievments != null) {
saAchievments.forEach((achievement) => achievements.add(achievement));
}
}
return achievements;
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<SessionActivity>>(
future: SessionActivitiesDao(database).sessionActivitiesBySessionId(session.id),
builder: (context, snapshot) {
if (snapshot.hasData) {
final sessionActivities = snapshot.data!;
final achievements = getAchievements(sessionActivities);
database.close();
return Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: SizedBox(
height: 40,
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
itemCount: achievements.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(right: 5),
child: ActionChip(
visualDensity: VisualDensity.compact,
avatar:
const Icon(Icons.check_circle_outline),
label: Text(maxLines: 1, achievements[index]),
onPressed: () {},
));
},
))),
],
);
} else {
return const CircularProgressIndicator();
}
});
}
}

View File

@ -0,0 +1,28 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/models/activity_model.dart';
import 'package:sendtrain/widgets/activity_card.dart';
class SessionViewActivities extends StatelessWidget {
const SessionViewActivities({super.key, this.activities, required this.data});
final List<ActivityModel>? activities;
final List<Activity> data;
@override
Widget build(BuildContext context) {
return Expanded(
child: ListView.builder(
// shrinkWrap: true,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
return ActivityCard(
activity: activities![Random().nextInt(activities!.length)],
data: data[index]);
},
));
}
}

View File

@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'package:sendtrain/classes/media.dart';
import 'package:sendtrain/database/daos/media_items_dao.dart';
import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/widgets/media_card.dart';
class SessionViewMedia extends StatelessWidget {
SessionViewMedia({super.key, this.media, required this.session});
final List<Media>? media;
final Session session;
final AppDatabase database = AppDatabase();
@override
Widget build(BuildContext context) {
return FutureBuilder<List<MediaItem>>(
future: MediaItemsDao(database).mediaItemsFromSession(session),
builder: (context, snapshot) {
if (snapshot.hasData) {
final mediaItems = snapshot.data!;
database.close();
List<Widget> mediaCards = List.generate(
mediaItems.length, (i) => MediaCard(media: mediaItems[i]));
return Column(
children: [
SizedBox(
width: double.infinity,
height: 100,
child: GridView.count(
padding: const EdgeInsets.fromLTRB(15, 0, 0, 0),
scrollDirection: Axis.horizontal,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
crossAxisCount: 1,
children: mediaCards))
],
);
} else {
return CircularProgressIndicator();
}
});
}
}