mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
refactor: use drift for skip segments and source matches
This commit is contained in:
parent
3fb003ea60
commit
52d4f60ccc
@ -22,8 +22,6 @@ import 'package:spotube/provider/server/bonsoir.dart';
|
||||
import 'package:spotube/provider/server/server.dart';
|
||||
import 'package:spotube/provider/tray_manager/tray_manager.dart';
|
||||
import 'package:spotube/l10n/l10n.dart';
|
||||
import 'package:spotube/models/skip_segment.dart';
|
||||
import 'package:spotube/models/source_match.dart';
|
||||
import 'package:spotube/provider/connect/clients.dart';
|
||||
import 'package:spotube/provider/palette_provider.dart';
|
||||
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
||||
@ -84,23 +82,6 @@ Future<void> main(List<String> rawArgs) async {
|
||||
|
||||
Hive.init(hiveCacheDir);
|
||||
|
||||
Hive.registerAdapter(SkipSegmentAdapter());
|
||||
|
||||
Hive.registerAdapter(SourceMatchAdapter());
|
||||
Hive.registerAdapter(SourceTypeAdapter());
|
||||
|
||||
// Cache versioning entities with Adapter
|
||||
SourceMatch.version = 'v1';
|
||||
SkipSegment.version = 'v1';
|
||||
|
||||
await Hive.openLazyBox<SourceMatch>(
|
||||
SourceMatch.boxName,
|
||||
path: hiveCacheDir,
|
||||
);
|
||||
await Hive.openLazyBox(
|
||||
SkipSegment.boxName,
|
||||
path: hiveCacheDir,
|
||||
);
|
||||
await PersistedStateNotifier.initializeBoxes(
|
||||
path: hiveCacheDir,
|
||||
);
|
||||
|
@ -17,11 +17,14 @@ import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart';
|
||||
part 'database.g.dart';
|
||||
|
||||
part 'tables/preferences.dart';
|
||||
part 'tables/source_match.dart';
|
||||
part 'tables/skip_segment.dart';
|
||||
|
||||
part 'typeconverters/color.dart';
|
||||
part 'typeconverters/locale.dart';
|
||||
part 'typeconverters/string_list.dart';
|
||||
|
||||
@DriftDatabase(tables: [PreferencesTable])
|
||||
@DriftDatabase(tables: [PreferencesTable, SourceMatchTable, SkipSegmentTable])
|
||||
class AppDatabase extends _$AppDatabase {
|
||||
AppDatabase() : super(_openConnection());
|
||||
|
||||
|
@ -1204,16 +1204,608 @@ class PreferencesTableCompanion extends UpdateCompanion<PreferencesTableData> {
|
||||
}
|
||||
}
|
||||
|
||||
class $SourceMatchTableTable extends SourceMatchTable
|
||||
with TableInfo<$SourceMatchTableTable, SourceMatchTableData> {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
$SourceMatchTableTable(this.attachedDatabase, [this._alias]);
|
||||
static const VerificationMeta _idMeta = const VerificationMeta('id');
|
||||
@override
|
||||
late final GeneratedColumn<int> id = GeneratedColumn<int>(
|
||||
'id', aliasedName, false,
|
||||
hasAutoIncrement: true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
|
||||
static const VerificationMeta _trackIdMeta =
|
||||
const VerificationMeta('trackId');
|
||||
@override
|
||||
late final GeneratedColumn<String> trackId = GeneratedColumn<String>(
|
||||
'track_id', aliasedName, false,
|
||||
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||
static const VerificationMeta _sourceIdMeta =
|
||||
const VerificationMeta('sourceId');
|
||||
@override
|
||||
late final GeneratedColumn<String> sourceId = GeneratedColumn<String>(
|
||||
'source_id', aliasedName, false,
|
||||
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||
static const VerificationMeta _sourceTypeMeta =
|
||||
const VerificationMeta('sourceType');
|
||||
@override
|
||||
late final GeneratedColumnWithTypeConverter<SourceType, String> sourceType =
|
||||
GeneratedColumn<String>('source_type', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
defaultValue: Constant(SourceType.youtube.name))
|
||||
.withConverter<SourceType>(
|
||||
$SourceMatchTableTable.$convertersourceType);
|
||||
static const VerificationMeta _createdAtMeta =
|
||||
const VerificationMeta('createdAt');
|
||||
@override
|
||||
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
|
||||
'created_at', aliasedName, false,
|
||||
type: DriftSqlType.dateTime,
|
||||
requiredDuringInsert: false,
|
||||
defaultValue: currentDateAndTime);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns =>
|
||||
[id, trackId, sourceId, sourceType, createdAt];
|
||||
@override
|
||||
String get aliasedName => _alias ?? actualTableName;
|
||||
@override
|
||||
String get actualTableName => $name;
|
||||
static const String $name = 'source_match_table';
|
||||
@override
|
||||
VerificationContext validateIntegrity(
|
||||
Insertable<SourceMatchTableData> 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('track_id')) {
|
||||
context.handle(_trackIdMeta,
|
||||
trackId.isAcceptableOrUnknown(data['track_id']!, _trackIdMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_trackIdMeta);
|
||||
}
|
||||
if (data.containsKey('source_id')) {
|
||||
context.handle(_sourceIdMeta,
|
||||
sourceId.isAcceptableOrUnknown(data['source_id']!, _sourceIdMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_sourceIdMeta);
|
||||
}
|
||||
context.handle(_sourceTypeMeta, const VerificationResult.success());
|
||||
if (data.containsKey('created_at')) {
|
||||
context.handle(_createdAtMeta,
|
||||
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta));
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
SourceMatchTableData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||
return SourceMatchTableData(
|
||||
id: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
|
||||
trackId: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.string, data['${effectivePrefix}track_id'])!,
|
||||
sourceId: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.string, data['${effectivePrefix}source_id'])!,
|
||||
sourceType: $SourceMatchTableTable.$convertersourceType.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string, data['${effectivePrefix}source_type'])!),
|
||||
createdAt: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
$SourceMatchTableTable createAlias(String alias) {
|
||||
return $SourceMatchTableTable(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
static JsonTypeConverter2<SourceType, String, String> $convertersourceType =
|
||||
const EnumNameConverter<SourceType>(SourceType.values);
|
||||
}
|
||||
|
||||
class SourceMatchTableData extends DataClass
|
||||
implements Insertable<SourceMatchTableData> {
|
||||
final int id;
|
||||
final String trackId;
|
||||
final String sourceId;
|
||||
final SourceType sourceType;
|
||||
final DateTime createdAt;
|
||||
const SourceMatchTableData(
|
||||
{required this.id,
|
||||
required this.trackId,
|
||||
required this.sourceId,
|
||||
required this.sourceType,
|
||||
required this.createdAt});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['id'] = Variable<int>(id);
|
||||
map['track_id'] = Variable<String>(trackId);
|
||||
map['source_id'] = Variable<String>(sourceId);
|
||||
{
|
||||
map['source_type'] = Variable<String>(
|
||||
$SourceMatchTableTable.$convertersourceType.toSql(sourceType));
|
||||
}
|
||||
map['created_at'] = Variable<DateTime>(createdAt);
|
||||
return map;
|
||||
}
|
||||
|
||||
SourceMatchTableCompanion toCompanion(bool nullToAbsent) {
|
||||
return SourceMatchTableCompanion(
|
||||
id: Value(id),
|
||||
trackId: Value(trackId),
|
||||
sourceId: Value(sourceId),
|
||||
sourceType: Value(sourceType),
|
||||
createdAt: Value(createdAt),
|
||||
);
|
||||
}
|
||||
|
||||
factory SourceMatchTableData.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return SourceMatchTableData(
|
||||
id: serializer.fromJson<int>(json['id']),
|
||||
trackId: serializer.fromJson<String>(json['trackId']),
|
||||
sourceId: serializer.fromJson<String>(json['sourceId']),
|
||||
sourceType: $SourceMatchTableTable.$convertersourceType
|
||||
.fromJson(serializer.fromJson<String>(json['sourceType'])),
|
||||
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'id': serializer.toJson<int>(id),
|
||||
'trackId': serializer.toJson<String>(trackId),
|
||||
'sourceId': serializer.toJson<String>(sourceId),
|
||||
'sourceType': serializer.toJson<String>(
|
||||
$SourceMatchTableTable.$convertersourceType.toJson(sourceType)),
|
||||
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||
};
|
||||
}
|
||||
|
||||
SourceMatchTableData copyWith(
|
||||
{int? id,
|
||||
String? trackId,
|
||||
String? sourceId,
|
||||
SourceType? sourceType,
|
||||
DateTime? createdAt}) =>
|
||||
SourceMatchTableData(
|
||||
id: id ?? this.id,
|
||||
trackId: trackId ?? this.trackId,
|
||||
sourceId: sourceId ?? this.sourceId,
|
||||
sourceType: sourceType ?? this.sourceType,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('SourceMatchTableData(')
|
||||
..write('id: $id, ')
|
||||
..write('trackId: $trackId, ')
|
||||
..write('sourceId: $sourceId, ')
|
||||
..write('sourceType: $sourceType, ')
|
||||
..write('createdAt: $createdAt')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(id, trackId, sourceId, sourceType, createdAt);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is SourceMatchTableData &&
|
||||
other.id == this.id &&
|
||||
other.trackId == this.trackId &&
|
||||
other.sourceId == this.sourceId &&
|
||||
other.sourceType == this.sourceType &&
|
||||
other.createdAt == this.createdAt);
|
||||
}
|
||||
|
||||
class SourceMatchTableCompanion extends UpdateCompanion<SourceMatchTableData> {
|
||||
final Value<int> id;
|
||||
final Value<String> trackId;
|
||||
final Value<String> sourceId;
|
||||
final Value<SourceType> sourceType;
|
||||
final Value<DateTime> createdAt;
|
||||
const SourceMatchTableCompanion({
|
||||
this.id = const Value.absent(),
|
||||
this.trackId = const Value.absent(),
|
||||
this.sourceId = const Value.absent(),
|
||||
this.sourceType = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
});
|
||||
SourceMatchTableCompanion.insert({
|
||||
this.id = const Value.absent(),
|
||||
required String trackId,
|
||||
required String sourceId,
|
||||
this.sourceType = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
}) : trackId = Value(trackId),
|
||||
sourceId = Value(sourceId);
|
||||
static Insertable<SourceMatchTableData> custom({
|
||||
Expression<int>? id,
|
||||
Expression<String>? trackId,
|
||||
Expression<String>? sourceId,
|
||||
Expression<String>? sourceType,
|
||||
Expression<DateTime>? createdAt,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (id != null) 'id': id,
|
||||
if (trackId != null) 'track_id': trackId,
|
||||
if (sourceId != null) 'source_id': sourceId,
|
||||
if (sourceType != null) 'source_type': sourceType,
|
||||
if (createdAt != null) 'created_at': createdAt,
|
||||
});
|
||||
}
|
||||
|
||||
SourceMatchTableCompanion copyWith(
|
||||
{Value<int>? id,
|
||||
Value<String>? trackId,
|
||||
Value<String>? sourceId,
|
||||
Value<SourceType>? sourceType,
|
||||
Value<DateTime>? createdAt}) {
|
||||
return SourceMatchTableCompanion(
|
||||
id: id ?? this.id,
|
||||
trackId: trackId ?? this.trackId,
|
||||
sourceId: sourceId ?? this.sourceId,
|
||||
sourceType: sourceType ?? this.sourceType,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (id.present) {
|
||||
map['id'] = Variable<int>(id.value);
|
||||
}
|
||||
if (trackId.present) {
|
||||
map['track_id'] = Variable<String>(trackId.value);
|
||||
}
|
||||
if (sourceId.present) {
|
||||
map['source_id'] = Variable<String>(sourceId.value);
|
||||
}
|
||||
if (sourceType.present) {
|
||||
map['source_type'] = Variable<String>(
|
||||
$SourceMatchTableTable.$convertersourceType.toSql(sourceType.value));
|
||||
}
|
||||
if (createdAt.present) {
|
||||
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('SourceMatchTableCompanion(')
|
||||
..write('id: $id, ')
|
||||
..write('trackId: $trackId, ')
|
||||
..write('sourceId: $sourceId, ')
|
||||
..write('sourceType: $sourceType, ')
|
||||
..write('createdAt: $createdAt')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class $SkipSegmentTableTable extends SkipSegmentTable
|
||||
with TableInfo<$SkipSegmentTableTable, SkipSegmentTableData> {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
$SkipSegmentTableTable(this.attachedDatabase, [this._alias]);
|
||||
static const VerificationMeta _idMeta = const VerificationMeta('id');
|
||||
@override
|
||||
late final GeneratedColumn<int> id = GeneratedColumn<int>(
|
||||
'id', aliasedName, false,
|
||||
hasAutoIncrement: true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
|
||||
static const VerificationMeta _startMeta = const VerificationMeta('start');
|
||||
@override
|
||||
late final GeneratedColumn<int> start = GeneratedColumn<int>(
|
||||
'start', aliasedName, false,
|
||||
type: DriftSqlType.int, requiredDuringInsert: true);
|
||||
static const VerificationMeta _endMeta = const VerificationMeta('end');
|
||||
@override
|
||||
late final GeneratedColumn<int> end = GeneratedColumn<int>(
|
||||
'end', aliasedName, false,
|
||||
type: DriftSqlType.int, requiredDuringInsert: true);
|
||||
static const VerificationMeta _trackIdMeta =
|
||||
const VerificationMeta('trackId');
|
||||
@override
|
||||
late final GeneratedColumn<String> trackId = GeneratedColumn<String>(
|
||||
'track_id', aliasedName, false,
|
||||
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||
static const VerificationMeta _createdAtMeta =
|
||||
const VerificationMeta('createdAt');
|
||||
@override
|
||||
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
|
||||
'created_at', aliasedName, false,
|
||||
type: DriftSqlType.dateTime,
|
||||
requiredDuringInsert: false,
|
||||
defaultValue: currentDateAndTime);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, start, end, trackId, createdAt];
|
||||
@override
|
||||
String get aliasedName => _alias ?? actualTableName;
|
||||
@override
|
||||
String get actualTableName => $name;
|
||||
static const String $name = 'skip_segment_table';
|
||||
@override
|
||||
VerificationContext validateIntegrity(
|
||||
Insertable<SkipSegmentTableData> 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('start')) {
|
||||
context.handle(
|
||||
_startMeta, start.isAcceptableOrUnknown(data['start']!, _startMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_startMeta);
|
||||
}
|
||||
if (data.containsKey('end')) {
|
||||
context.handle(
|
||||
_endMeta, end.isAcceptableOrUnknown(data['end']!, _endMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_endMeta);
|
||||
}
|
||||
if (data.containsKey('track_id')) {
|
||||
context.handle(_trackIdMeta,
|
||||
trackId.isAcceptableOrUnknown(data['track_id']!, _trackIdMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_trackIdMeta);
|
||||
}
|
||||
if (data.containsKey('created_at')) {
|
||||
context.handle(_createdAtMeta,
|
||||
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta));
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
SkipSegmentTableData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||
return SkipSegmentTableData(
|
||||
id: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
|
||||
start: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.int, data['${effectivePrefix}start'])!,
|
||||
end: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.int, data['${effectivePrefix}end'])!,
|
||||
trackId: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.string, data['${effectivePrefix}track_id'])!,
|
||||
createdAt: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
$SkipSegmentTableTable createAlias(String alias) {
|
||||
return $SkipSegmentTableTable(attachedDatabase, alias);
|
||||
}
|
||||
}
|
||||
|
||||
class SkipSegmentTableData extends DataClass
|
||||
implements Insertable<SkipSegmentTableData> {
|
||||
final int id;
|
||||
final int start;
|
||||
final int end;
|
||||
final String trackId;
|
||||
final DateTime createdAt;
|
||||
const SkipSegmentTableData(
|
||||
{required this.id,
|
||||
required this.start,
|
||||
required this.end,
|
||||
required this.trackId,
|
||||
required this.createdAt});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['id'] = Variable<int>(id);
|
||||
map['start'] = Variable<int>(start);
|
||||
map['end'] = Variable<int>(end);
|
||||
map['track_id'] = Variable<String>(trackId);
|
||||
map['created_at'] = Variable<DateTime>(createdAt);
|
||||
return map;
|
||||
}
|
||||
|
||||
SkipSegmentTableCompanion toCompanion(bool nullToAbsent) {
|
||||
return SkipSegmentTableCompanion(
|
||||
id: Value(id),
|
||||
start: Value(start),
|
||||
end: Value(end),
|
||||
trackId: Value(trackId),
|
||||
createdAt: Value(createdAt),
|
||||
);
|
||||
}
|
||||
|
||||
factory SkipSegmentTableData.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return SkipSegmentTableData(
|
||||
id: serializer.fromJson<int>(json['id']),
|
||||
start: serializer.fromJson<int>(json['start']),
|
||||
end: serializer.fromJson<int>(json['end']),
|
||||
trackId: serializer.fromJson<String>(json['trackId']),
|
||||
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'id': serializer.toJson<int>(id),
|
||||
'start': serializer.toJson<int>(start),
|
||||
'end': serializer.toJson<int>(end),
|
||||
'trackId': serializer.toJson<String>(trackId),
|
||||
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||
};
|
||||
}
|
||||
|
||||
SkipSegmentTableData copyWith(
|
||||
{int? id,
|
||||
int? start,
|
||||
int? end,
|
||||
String? trackId,
|
||||
DateTime? createdAt}) =>
|
||||
SkipSegmentTableData(
|
||||
id: id ?? this.id,
|
||||
start: start ?? this.start,
|
||||
end: end ?? this.end,
|
||||
trackId: trackId ?? this.trackId,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('SkipSegmentTableData(')
|
||||
..write('id: $id, ')
|
||||
..write('start: $start, ')
|
||||
..write('end: $end, ')
|
||||
..write('trackId: $trackId, ')
|
||||
..write('createdAt: $createdAt')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(id, start, end, trackId, createdAt);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is SkipSegmentTableData &&
|
||||
other.id == this.id &&
|
||||
other.start == this.start &&
|
||||
other.end == this.end &&
|
||||
other.trackId == this.trackId &&
|
||||
other.createdAt == this.createdAt);
|
||||
}
|
||||
|
||||
class SkipSegmentTableCompanion extends UpdateCompanion<SkipSegmentTableData> {
|
||||
final Value<int> id;
|
||||
final Value<int> start;
|
||||
final Value<int> end;
|
||||
final Value<String> trackId;
|
||||
final Value<DateTime> createdAt;
|
||||
const SkipSegmentTableCompanion({
|
||||
this.id = const Value.absent(),
|
||||
this.start = const Value.absent(),
|
||||
this.end = const Value.absent(),
|
||||
this.trackId = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
});
|
||||
SkipSegmentTableCompanion.insert({
|
||||
this.id = const Value.absent(),
|
||||
required int start,
|
||||
required int end,
|
||||
required String trackId,
|
||||
this.createdAt = const Value.absent(),
|
||||
}) : start = Value(start),
|
||||
end = Value(end),
|
||||
trackId = Value(trackId);
|
||||
static Insertable<SkipSegmentTableData> custom({
|
||||
Expression<int>? id,
|
||||
Expression<int>? start,
|
||||
Expression<int>? end,
|
||||
Expression<String>? trackId,
|
||||
Expression<DateTime>? createdAt,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (id != null) 'id': id,
|
||||
if (start != null) 'start': start,
|
||||
if (end != null) 'end': end,
|
||||
if (trackId != null) 'track_id': trackId,
|
||||
if (createdAt != null) 'created_at': createdAt,
|
||||
});
|
||||
}
|
||||
|
||||
SkipSegmentTableCompanion copyWith(
|
||||
{Value<int>? id,
|
||||
Value<int>? start,
|
||||
Value<int>? end,
|
||||
Value<String>? trackId,
|
||||
Value<DateTime>? createdAt}) {
|
||||
return SkipSegmentTableCompanion(
|
||||
id: id ?? this.id,
|
||||
start: start ?? this.start,
|
||||
end: end ?? this.end,
|
||||
trackId: trackId ?? this.trackId,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (id.present) {
|
||||
map['id'] = Variable<int>(id.value);
|
||||
}
|
||||
if (start.present) {
|
||||
map['start'] = Variable<int>(start.value);
|
||||
}
|
||||
if (end.present) {
|
||||
map['end'] = Variable<int>(end.value);
|
||||
}
|
||||
if (trackId.present) {
|
||||
map['track_id'] = Variable<String>(trackId.value);
|
||||
}
|
||||
if (createdAt.present) {
|
||||
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('SkipSegmentTableCompanion(')
|
||||
..write('id: $id, ')
|
||||
..write('start: $start, ')
|
||||
..write('end: $end, ')
|
||||
..write('trackId: $trackId, ')
|
||||
..write('createdAt: $createdAt')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _$AppDatabase extends GeneratedDatabase {
|
||||
_$AppDatabase(QueryExecutor e) : super(e);
|
||||
_$AppDatabaseManager get managers => _$AppDatabaseManager(this);
|
||||
late final $PreferencesTableTable preferencesTable =
|
||||
$PreferencesTableTable(this);
|
||||
late final $SourceMatchTableTable sourceMatchTable =
|
||||
$SourceMatchTableTable(this);
|
||||
late final $SkipSegmentTableTable skipSegmentTable =
|
||||
$SkipSegmentTableTable(this);
|
||||
late final Index uniqTrackMatch = Index('uniq_track_match',
|
||||
'CREATE UNIQUE INDEX uniq_track_match ON source_match_table (track_id, source_id, source_type)');
|
||||
@override
|
||||
Iterable<TableInfo<Table, Object?>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [preferencesTable];
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[preferencesTable, sourceMatchTable, skipSegmentTable, uniqTrackMatch];
|
||||
}
|
||||
|
||||
typedef $$PreferencesTableTableInsertCompanionBuilder
|
||||
@ -1699,9 +2291,293 @@ class $$PreferencesTableTableOrderingComposer
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
}
|
||||
|
||||
typedef $$SourceMatchTableTableInsertCompanionBuilder
|
||||
= SourceMatchTableCompanion Function({
|
||||
Value<int> id,
|
||||
required String trackId,
|
||||
required String sourceId,
|
||||
Value<SourceType> sourceType,
|
||||
Value<DateTime> createdAt,
|
||||
});
|
||||
typedef $$SourceMatchTableTableUpdateCompanionBuilder
|
||||
= SourceMatchTableCompanion Function({
|
||||
Value<int> id,
|
||||
Value<String> trackId,
|
||||
Value<String> sourceId,
|
||||
Value<SourceType> sourceType,
|
||||
Value<DateTime> createdAt,
|
||||
});
|
||||
|
||||
class $$SourceMatchTableTableTableManager extends RootTableManager<
|
||||
_$AppDatabase,
|
||||
$SourceMatchTableTable,
|
||||
SourceMatchTableData,
|
||||
$$SourceMatchTableTableFilterComposer,
|
||||
$$SourceMatchTableTableOrderingComposer,
|
||||
$$SourceMatchTableTableProcessedTableManager,
|
||||
$$SourceMatchTableTableInsertCompanionBuilder,
|
||||
$$SourceMatchTableTableUpdateCompanionBuilder> {
|
||||
$$SourceMatchTableTableTableManager(
|
||||
_$AppDatabase db, $SourceMatchTableTable table)
|
||||
: super(TableManagerState(
|
||||
db: db,
|
||||
table: table,
|
||||
filteringComposer:
|
||||
$$SourceMatchTableTableFilterComposer(ComposerState(db, table)),
|
||||
orderingComposer:
|
||||
$$SourceMatchTableTableOrderingComposer(ComposerState(db, table)),
|
||||
getChildManagerBuilder: (p) =>
|
||||
$$SourceMatchTableTableProcessedTableManager(p),
|
||||
getUpdateCompanionBuilder: ({
|
||||
Value<int> id = const Value.absent(),
|
||||
Value<String> trackId = const Value.absent(),
|
||||
Value<String> sourceId = const Value.absent(),
|
||||
Value<SourceType> sourceType = const Value.absent(),
|
||||
Value<DateTime> createdAt = const Value.absent(),
|
||||
}) =>
|
||||
SourceMatchTableCompanion(
|
||||
id: id,
|
||||
trackId: trackId,
|
||||
sourceId: sourceId,
|
||||
sourceType: sourceType,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
getInsertCompanionBuilder: ({
|
||||
Value<int> id = const Value.absent(),
|
||||
required String trackId,
|
||||
required String sourceId,
|
||||
Value<SourceType> sourceType = const Value.absent(),
|
||||
Value<DateTime> createdAt = const Value.absent(),
|
||||
}) =>
|
||||
SourceMatchTableCompanion.insert(
|
||||
id: id,
|
||||
trackId: trackId,
|
||||
sourceId: sourceId,
|
||||
sourceType: sourceType,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
class $$SourceMatchTableTableProcessedTableManager
|
||||
extends ProcessedTableManager<
|
||||
_$AppDatabase,
|
||||
$SourceMatchTableTable,
|
||||
SourceMatchTableData,
|
||||
$$SourceMatchTableTableFilterComposer,
|
||||
$$SourceMatchTableTableOrderingComposer,
|
||||
$$SourceMatchTableTableProcessedTableManager,
|
||||
$$SourceMatchTableTableInsertCompanionBuilder,
|
||||
$$SourceMatchTableTableUpdateCompanionBuilder> {
|
||||
$$SourceMatchTableTableProcessedTableManager(super.$state);
|
||||
}
|
||||
|
||||
class $$SourceMatchTableTableFilterComposer
|
||||
extends FilterComposer<_$AppDatabase, $SourceMatchTableTable> {
|
||||
$$SourceMatchTableTableFilterComposer(super.$state);
|
||||
ColumnFilters<int> get id => $state.composableBuilder(
|
||||
column: $state.table.id,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnFilters<String> get trackId => $state.composableBuilder(
|
||||
column: $state.table.trackId,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnFilters<String> get sourceId => $state.composableBuilder(
|
||||
column: $state.table.sourceId,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnWithTypeConverterFilters<SourceType, SourceType, String>
|
||||
get sourceType => $state.composableBuilder(
|
||||
column: $state.table.sourceType,
|
||||
builder: (column, joinBuilders) => ColumnWithTypeConverterFilters(
|
||||
column,
|
||||
joinBuilders: joinBuilders));
|
||||
|
||||
ColumnFilters<DateTime> get createdAt => $state.composableBuilder(
|
||||
column: $state.table.createdAt,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||
}
|
||||
|
||||
class $$SourceMatchTableTableOrderingComposer
|
||||
extends OrderingComposer<_$AppDatabase, $SourceMatchTableTable> {
|
||||
$$SourceMatchTableTableOrderingComposer(super.$state);
|
||||
ColumnOrderings<int> get id => $state.composableBuilder(
|
||||
column: $state.table.id,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnOrderings<String> get trackId => $state.composableBuilder(
|
||||
column: $state.table.trackId,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnOrderings<String> get sourceId => $state.composableBuilder(
|
||||
column: $state.table.sourceId,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnOrderings<String> get sourceType => $state.composableBuilder(
|
||||
column: $state.table.sourceType,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnOrderings<DateTime> get createdAt => $state.composableBuilder(
|
||||
column: $state.table.createdAt,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
}
|
||||
|
||||
typedef $$SkipSegmentTableTableInsertCompanionBuilder
|
||||
= SkipSegmentTableCompanion Function({
|
||||
Value<int> id,
|
||||
required int start,
|
||||
required int end,
|
||||
required String trackId,
|
||||
Value<DateTime> createdAt,
|
||||
});
|
||||
typedef $$SkipSegmentTableTableUpdateCompanionBuilder
|
||||
= SkipSegmentTableCompanion Function({
|
||||
Value<int> id,
|
||||
Value<int> start,
|
||||
Value<int> end,
|
||||
Value<String> trackId,
|
||||
Value<DateTime> createdAt,
|
||||
});
|
||||
|
||||
class $$SkipSegmentTableTableTableManager extends RootTableManager<
|
||||
_$AppDatabase,
|
||||
$SkipSegmentTableTable,
|
||||
SkipSegmentTableData,
|
||||
$$SkipSegmentTableTableFilterComposer,
|
||||
$$SkipSegmentTableTableOrderingComposer,
|
||||
$$SkipSegmentTableTableProcessedTableManager,
|
||||
$$SkipSegmentTableTableInsertCompanionBuilder,
|
||||
$$SkipSegmentTableTableUpdateCompanionBuilder> {
|
||||
$$SkipSegmentTableTableTableManager(
|
||||
_$AppDatabase db, $SkipSegmentTableTable table)
|
||||
: super(TableManagerState(
|
||||
db: db,
|
||||
table: table,
|
||||
filteringComposer:
|
||||
$$SkipSegmentTableTableFilterComposer(ComposerState(db, table)),
|
||||
orderingComposer:
|
||||
$$SkipSegmentTableTableOrderingComposer(ComposerState(db, table)),
|
||||
getChildManagerBuilder: (p) =>
|
||||
$$SkipSegmentTableTableProcessedTableManager(p),
|
||||
getUpdateCompanionBuilder: ({
|
||||
Value<int> id = const Value.absent(),
|
||||
Value<int> start = const Value.absent(),
|
||||
Value<int> end = const Value.absent(),
|
||||
Value<String> trackId = const Value.absent(),
|
||||
Value<DateTime> createdAt = const Value.absent(),
|
||||
}) =>
|
||||
SkipSegmentTableCompanion(
|
||||
id: id,
|
||||
start: start,
|
||||
end: end,
|
||||
trackId: trackId,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
getInsertCompanionBuilder: ({
|
||||
Value<int> id = const Value.absent(),
|
||||
required int start,
|
||||
required int end,
|
||||
required String trackId,
|
||||
Value<DateTime> createdAt = const Value.absent(),
|
||||
}) =>
|
||||
SkipSegmentTableCompanion.insert(
|
||||
id: id,
|
||||
start: start,
|
||||
end: end,
|
||||
trackId: trackId,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
class $$SkipSegmentTableTableProcessedTableManager
|
||||
extends ProcessedTableManager<
|
||||
_$AppDatabase,
|
||||
$SkipSegmentTableTable,
|
||||
SkipSegmentTableData,
|
||||
$$SkipSegmentTableTableFilterComposer,
|
||||
$$SkipSegmentTableTableOrderingComposer,
|
||||
$$SkipSegmentTableTableProcessedTableManager,
|
||||
$$SkipSegmentTableTableInsertCompanionBuilder,
|
||||
$$SkipSegmentTableTableUpdateCompanionBuilder> {
|
||||
$$SkipSegmentTableTableProcessedTableManager(super.$state);
|
||||
}
|
||||
|
||||
class $$SkipSegmentTableTableFilterComposer
|
||||
extends FilterComposer<_$AppDatabase, $SkipSegmentTableTable> {
|
||||
$$SkipSegmentTableTableFilterComposer(super.$state);
|
||||
ColumnFilters<int> get id => $state.composableBuilder(
|
||||
column: $state.table.id,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnFilters<int> get start => $state.composableBuilder(
|
||||
column: $state.table.start,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnFilters<int> get end => $state.composableBuilder(
|
||||
column: $state.table.end,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnFilters<String> get trackId => $state.composableBuilder(
|
||||
column: $state.table.trackId,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnFilters<DateTime> get createdAt => $state.composableBuilder(
|
||||
column: $state.table.createdAt,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||
}
|
||||
|
||||
class $$SkipSegmentTableTableOrderingComposer
|
||||
extends OrderingComposer<_$AppDatabase, $SkipSegmentTableTable> {
|
||||
$$SkipSegmentTableTableOrderingComposer(super.$state);
|
||||
ColumnOrderings<int> get id => $state.composableBuilder(
|
||||
column: $state.table.id,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnOrderings<int> get start => $state.composableBuilder(
|
||||
column: $state.table.start,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnOrderings<int> get end => $state.composableBuilder(
|
||||
column: $state.table.end,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnOrderings<String> get trackId => $state.composableBuilder(
|
||||
column: $state.table.trackId,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
|
||||
ColumnOrderings<DateTime> get createdAt => $state.composableBuilder(
|
||||
column: $state.table.createdAt,
|
||||
builder: (column, joinBuilders) =>
|
||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||
}
|
||||
|
||||
class _$AppDatabaseManager {
|
||||
final _$AppDatabase _db;
|
||||
_$AppDatabaseManager(this._db);
|
||||
$$PreferencesTableTableTableManager get preferencesTable =>
|
||||
$$PreferencesTableTableTableManager(_db, _db.preferencesTable);
|
||||
$$SourceMatchTableTableTableManager get sourceMatchTable =>
|
||||
$$SourceMatchTableTableTableManager(_db, _db.sourceMatchTable);
|
||||
$$SkipSegmentTableTableTableManager get skipSegmentTable =>
|
||||
$$SkipSegmentTableTableTableManager(_db, _db.skipSegmentTable);
|
||||
}
|
||||
|
9
lib/models/database/tables/skip_segment.dart
Normal file
9
lib/models/database/tables/skip_segment.dart
Normal file
@ -0,0 +1,9 @@
|
||||
part of '../database.dart';
|
||||
|
||||
class SkipSegmentTable extends Table {
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
IntColumn get start => integer()();
|
||||
IntColumn get end => integer()();
|
||||
TextColumn get trackId => text()();
|
||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||
}
|
25
lib/models/database/tables/source_match.dart
Normal file
25
lib/models/database/tables/source_match.dart
Normal file
@ -0,0 +1,25 @@
|
||||
part of '../database.dart';
|
||||
|
||||
enum SourceType {
|
||||
youtube._("YouTube"),
|
||||
youtubeMusic._("YouTube Music"),
|
||||
jiosaavn._("JioSaavn");
|
||||
|
||||
final String label;
|
||||
|
||||
const SourceType._(this.label);
|
||||
}
|
||||
|
||||
@TableIndex(
|
||||
name: "uniq_track_match",
|
||||
columns: {#trackId, #sourceId, #sourceType},
|
||||
unique: true,
|
||||
)
|
||||
class SourceMatchTable extends Table {
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
TextColumn get trackId => text()();
|
||||
TextColumn get sourceId => text()();
|
||||
TextColumn get sourceType =>
|
||||
textEnum<SourceType>().withDefault(Constant(SourceType.youtube.name))();
|
||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'skip_segment.g.dart';
|
||||
|
||||
@HiveType(typeId: 2)
|
||||
class SkipSegment {
|
||||
@HiveField(0)
|
||||
final int start;
|
||||
@HiveField(1)
|
||||
final int end;
|
||||
SkipSegment(this.start, this.end);
|
||||
|
||||
static String version = 'v1';
|
||||
static final boxName = "oss.krtirtho.spotube.skip_segments.$version";
|
||||
static LazyBox get box => Hive.lazyBox(boxName);
|
||||
|
||||
SkipSegment.fromJson(Map<String, dynamic> json)
|
||||
: start = json['start'],
|
||||
end = json['end'];
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'start': start,
|
||||
'end': end,
|
||||
};
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'skip_segment.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// TypeAdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class SkipSegmentAdapter extends TypeAdapter<SkipSegment> {
|
||||
@override
|
||||
final int typeId = 2;
|
||||
|
||||
@override
|
||||
SkipSegment read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return SkipSegment(
|
||||
fields[0] as int,
|
||||
fields[1] as int,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, SkipSegment obj) {
|
||||
writer
|
||||
..writeByte(2)
|
||||
..writeByte(0)
|
||||
..write(obj.start)
|
||||
..writeByte(1)
|
||||
..write(obj.end);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is SkipSegmentAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'source_match.g.dart';
|
||||
|
||||
@JsonEnum()
|
||||
@HiveType(typeId: 5)
|
||||
enum SourceType {
|
||||
@HiveField(0)
|
||||
youtube._("YouTube"),
|
||||
|
||||
@HiveField(1)
|
||||
youtubeMusic._("YouTube Music"),
|
||||
|
||||
@HiveField(2)
|
||||
jiosaavn._("JioSaavn");
|
||||
|
||||
final String label;
|
||||
|
||||
const SourceType._(this.label);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
@HiveType(typeId: 6)
|
||||
class SourceMatch {
|
||||
@HiveField(0)
|
||||
String id;
|
||||
|
||||
@HiveField(1)
|
||||
String sourceId;
|
||||
|
||||
@HiveField(2)
|
||||
SourceType sourceType;
|
||||
|
||||
@HiveField(3)
|
||||
DateTime createdAt;
|
||||
|
||||
SourceMatch({
|
||||
required this.id,
|
||||
required this.sourceId,
|
||||
required this.sourceType,
|
||||
required this.createdAt,
|
||||
});
|
||||
|
||||
factory SourceMatch.fromJson(Map<String, dynamic> json) =>
|
||||
_$SourceMatchFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$SourceMatchToJson(this);
|
||||
|
||||
static String version = 'v1';
|
||||
static final boxName = "oss.krtirtho.spotube.source_matches.$version";
|
||||
|
||||
static LazyBox<SourceMatch> get box => Hive.lazyBox<SourceMatch>(boxName);
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'source_match.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// TypeAdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class SourceMatchAdapter extends TypeAdapter<SourceMatch> {
|
||||
@override
|
||||
final int typeId = 6;
|
||||
|
||||
@override
|
||||
SourceMatch read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return SourceMatch(
|
||||
id: fields[0] as String,
|
||||
sourceId: fields[1] as String,
|
||||
sourceType: fields[2] as SourceType,
|
||||
createdAt: fields[3] as DateTime,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, SourceMatch obj) {
|
||||
writer
|
||||
..writeByte(4)
|
||||
..writeByte(0)
|
||||
..write(obj.id)
|
||||
..writeByte(1)
|
||||
..write(obj.sourceId)
|
||||
..writeByte(2)
|
||||
..write(obj.sourceType)
|
||||
..writeByte(3)
|
||||
..write(obj.createdAt);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is SourceMatchAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
||||
|
||||
class SourceTypeAdapter extends TypeAdapter<SourceType> {
|
||||
@override
|
||||
final int typeId = 5;
|
||||
|
||||
@override
|
||||
SourceType read(BinaryReader reader) {
|
||||
switch (reader.readByte()) {
|
||||
case 0:
|
||||
return SourceType.youtube;
|
||||
case 1:
|
||||
return SourceType.youtubeMusic;
|
||||
case 2:
|
||||
return SourceType.jiosaavn;
|
||||
default:
|
||||
return SourceType.youtube;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, SourceType obj) {
|
||||
switch (obj) {
|
||||
case SourceType.youtube:
|
||||
writer.writeByte(0);
|
||||
break;
|
||||
case SourceType.youtubeMusic:
|
||||
writer.writeByte(1);
|
||||
break;
|
||||
case SourceType.jiosaavn:
|
||||
writer.writeByte(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is SourceTypeAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
SourceMatch _$SourceMatchFromJson(Map json) => SourceMatch(
|
||||
id: json['id'] as String,
|
||||
sourceId: json['sourceId'] as String,
|
||||
sourceType: $enumDecode(_$SourceTypeEnumMap, json['sourceType']),
|
||||
createdAt: DateTime.parse(json['createdAt'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SourceMatchToJson(SourceMatch instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'sourceId': instance.sourceId,
|
||||
'sourceType': _$SourceTypeEnumMap[instance.sourceType]!,
|
||||
'createdAt': instance.createdAt.toIso8601String(),
|
||||
};
|
||||
|
||||
const _$SourceTypeEnumMap = {
|
||||
SourceType.youtube: 'youtube',
|
||||
SourceType.youtubeMusic: 'youtubeMusic',
|
||||
SourceType.jiosaavn: 'jiosaavn',
|
||||
};
|
@ -1,8 +1,8 @@
|
||||
import 'package:spotube/models/database/database.dart';
|
||||
import 'package:spotube/provider/database/database.dart';
|
||||
import 'package:spotube/services/logger/logger.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:spotube/models/skip_segment.dart';
|
||||
import 'package:spotube/provider/server/active_sourced_track.dart';
|
||||
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
||||
|
||||
@ -10,24 +10,21 @@ import 'package:spotube/services/dio/dio.dart';
|
||||
|
||||
class SourcedSegments {
|
||||
final String source;
|
||||
final List<SkipSegment> segments;
|
||||
final List<SkipSegmentTableData> segments;
|
||||
|
||||
SourcedSegments({required this.source, required this.segments});
|
||||
}
|
||||
|
||||
Future<List<SkipSegment>> getAndCacheSkipSegments(String id) async {
|
||||
Future<List<SkipSegmentTableData>> getAndCacheSkipSegments(
|
||||
String id, Ref ref) async {
|
||||
final database = ref.read(databaseProvider);
|
||||
try {
|
||||
final cached = await SkipSegment.box.get(id) as List?;
|
||||
if (cached != null && cached.isNotEmpty) {
|
||||
return List.castFrom<dynamic, SkipSegment>(
|
||||
cached
|
||||
.map(
|
||||
(json) => SkipSegment.fromJson(
|
||||
Map.castFrom<dynamic, dynamic, String, dynamic>(json),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
final cached = await (database.select(database.skipSegmentTable)
|
||||
..where((s) => s.trackId.equals(id)))
|
||||
.get();
|
||||
|
||||
if (cached.isNotEmpty) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
final res = await globalDio.getUri(
|
||||
@ -55,25 +52,30 @@ Future<List<SkipSegment>> getAndCacheSkipSegments(String id) async {
|
||||
);
|
||||
|
||||
if (res.data == "Not Found") {
|
||||
return List.castFrom<dynamic, SkipSegment>([]);
|
||||
return List.castFrom<dynamic, SkipSegmentTableData>([]);
|
||||
}
|
||||
|
||||
final data = res.data as List;
|
||||
final segments = data.map((obj) {
|
||||
final start = obj["segment"].first.toInt();
|
||||
final end = obj["segment"].last.toInt();
|
||||
return SkipSegment(start, end);
|
||||
return SkipSegmentTableCompanion.insert(
|
||||
trackId: id,
|
||||
start: start,
|
||||
end: end,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
await SkipSegment.box.put(
|
||||
id,
|
||||
segments.map((e) => e.toJson()).toList(),
|
||||
);
|
||||
return List.castFrom<dynamic, SkipSegment>(segments);
|
||||
await database.batch((b) {
|
||||
b.insertAll(database.skipSegmentTable, segments);
|
||||
});
|
||||
|
||||
return await (database.select(database.skipSegmentTable)
|
||||
..where((s) => s.trackId.equals(id)))
|
||||
.get();
|
||||
} catch (e, stack) {
|
||||
await SkipSegment.box.put(id, []);
|
||||
AppLogger.reportError(e, stack);
|
||||
return List.castFrom<dynamic, SkipSegment>([]);
|
||||
return List.castFrom<dynamic, SkipSegmentTableData>([]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +102,7 @@ final segmentProvider = FutureProvider<SourcedSegments?>(
|
||||
);
|
||||
}
|
||||
|
||||
final segments = await getAndCacheSkipSegments(track.sourceInfo.id);
|
||||
final segments = await getAndCacheSkipSegments(track.sourceInfo.id, ref);
|
||||
|
||||
return SourcedSegments(
|
||||
source: track.sourceInfo.id,
|
||||
|
@ -1,7 +1,9 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/models/source_match.dart';
|
||||
import 'package:spotube/models/database/database.dart';
|
||||
import 'package:spotube/provider/database/database.dart';
|
||||
import 'package:spotube/services/sourced_track/enums.dart';
|
||||
import 'package:spotube/services/sourced_track/exceptions.dart';
|
||||
import 'package:spotube/services/sourced_track/models/source_info.dart';
|
||||
@ -39,7 +41,10 @@ class JioSaavnSourcedTrack extends SourcedTrack {
|
||||
required Ref ref,
|
||||
bool weakMatch = false,
|
||||
}) async {
|
||||
final cachedSource = await SourceMatch.box.get(track.id);
|
||||
final database = ref.read(databaseProvider);
|
||||
final cachedSource = await (database.select(database.sourceMatchTable)
|
||||
..where((s) => s.trackId.equals(track.id!)))
|
||||
.getSingleOrNull();
|
||||
|
||||
if (cachedSource == null ||
|
||||
cachedSource.sourceType != SourceType.jiosaavn) {
|
||||
@ -50,15 +55,13 @@ class JioSaavnSourcedTrack extends SourcedTrack {
|
||||
throw TrackNotFoundError(track);
|
||||
}
|
||||
|
||||
await SourceMatch.box.put(
|
||||
track.id!,
|
||||
SourceMatch(
|
||||
id: track.id!,
|
||||
sourceType: SourceType.jiosaavn,
|
||||
createdAt: DateTime.now(),
|
||||
sourceId: siblings.first.info.id,
|
||||
),
|
||||
);
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
trackId: track.id!,
|
||||
sourceId: siblings.first.info.id,
|
||||
sourceType: const Value(SourceType.jiosaavn),
|
||||
),
|
||||
);
|
||||
|
||||
return JioSaavnSourcedTrack(
|
||||
ref: ref,
|
||||
@ -206,15 +209,14 @@ class JioSaavnSourcedTrack extends SourcedTrack {
|
||||
|
||||
final (:info, :source) = toSiblingType(item);
|
||||
|
||||
await SourceMatch.box.put(
|
||||
id!,
|
||||
SourceMatch(
|
||||
id: id!,
|
||||
sourceType: SourceType.jiosaavn,
|
||||
createdAt: DateTime.now(),
|
||||
sourceId: info.id,
|
||||
),
|
||||
);
|
||||
final database = ref.read(databaseProvider);
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
trackId: id!,
|
||||
sourceId: info.id,
|
||||
sourceType: const Value(SourceType.jiosaavn),
|
||||
),
|
||||
);
|
||||
|
||||
return JioSaavnSourcedTrack(
|
||||
ref: ref,
|
||||
|
@ -1,9 +1,10 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:piped_client/piped_client.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/models/database/database.dart';
|
||||
import 'package:spotube/models/source_match.dart';
|
||||
import 'package:spotube/provider/database/database.dart';
|
||||
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
||||
|
||||
import 'package:spotube/services/sourced_track/enums.dart';
|
||||
@ -49,7 +50,10 @@ class PipedSourcedTrack extends SourcedTrack {
|
||||
required Track track,
|
||||
required Ref ref,
|
||||
}) async {
|
||||
final cachedSource = await SourceMatch.box.get(track.id);
|
||||
final database = ref.read(databaseProvider);
|
||||
final cachedSource = await (database.select(database.sourceMatchTable)
|
||||
..where((s) => s.trackId.equals(track.id!)))
|
||||
.getSingleOrNull();
|
||||
final preferences = ref.read(userPreferencesProvider);
|
||||
final pipedClient = ref.read(pipedProvider);
|
||||
|
||||
@ -59,17 +63,17 @@ class PipedSourcedTrack extends SourcedTrack {
|
||||
throw TrackNotFoundError(track);
|
||||
}
|
||||
|
||||
await SourceMatch.box.put(
|
||||
track.id!,
|
||||
SourceMatch(
|
||||
id: track.id!,
|
||||
sourceType: preferences.searchMode == SearchMode.youtube
|
||||
? SourceType.youtube
|
||||
: SourceType.youtubeMusic,
|
||||
createdAt: DateTime.now(),
|
||||
sourceId: siblings.first.info.id,
|
||||
),
|
||||
);
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
trackId: track.id!,
|
||||
sourceId: siblings.first.info.id,
|
||||
sourceType: Value(
|
||||
preferences.searchMode == SearchMode.youtube
|
||||
? SourceType.youtube
|
||||
: SourceType.youtubeMusic,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return PipedSourcedTrack(
|
||||
ref: ref,
|
||||
@ -268,15 +272,14 @@ class PipedSourcedTrack extends SourcedTrack {
|
||||
|
||||
final manifest = await pipedClient.streams(newSourceInfo.id);
|
||||
|
||||
await SourceMatch.box.put(
|
||||
id!,
|
||||
SourceMatch(
|
||||
id: id!,
|
||||
sourceType: SourceType.jiosaavn,
|
||||
createdAt: DateTime.now(),
|
||||
sourceId: newSourceInfo.id,
|
||||
),
|
||||
);
|
||||
final database = ref.read(databaseProvider);
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
trackId: id!,
|
||||
sourceId: newSourceInfo.id,
|
||||
sourceType: const Value(SourceType.youtube),
|
||||
),
|
||||
);
|
||||
|
||||
return PipedSourcedTrack(
|
||||
ref: ref,
|
||||
|
@ -1,8 +1,10 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/models/source_match.dart';
|
||||
import 'package:spotube/models/database/database.dart';
|
||||
import 'package:spotube/provider/database/database.dart';
|
||||
import 'package:spotube/services/logger/logger.dart';
|
||||
import 'package:spotube/services/song_link/song_link.dart';
|
||||
import 'package:spotube/services/sourced_track/enums.dart';
|
||||
@ -46,7 +48,10 @@ class YoutubeSourcedTrack extends SourcedTrack {
|
||||
required Track track,
|
||||
required Ref ref,
|
||||
}) async {
|
||||
final cachedSource = await SourceMatch.box.get(track.id);
|
||||
final database = ref.read(databaseProvider);
|
||||
final cachedSource = await (database.select(database.sourceMatchTable)
|
||||
..where((s) => s.trackId.equals(track.id!)))
|
||||
.getSingleOrNull();
|
||||
|
||||
if (cachedSource == null || cachedSource.sourceType != SourceType.youtube) {
|
||||
final siblings = await fetchSiblings(ref: ref, track: track);
|
||||
@ -54,15 +59,13 @@ class YoutubeSourcedTrack extends SourcedTrack {
|
||||
throw TrackNotFoundError(track);
|
||||
}
|
||||
|
||||
await SourceMatch.box.put(
|
||||
track.id!,
|
||||
SourceMatch(
|
||||
id: track.id!,
|
||||
sourceType: SourceType.youtube,
|
||||
createdAt: DateTime.now(),
|
||||
sourceId: siblings.first.info.id,
|
||||
),
|
||||
);
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
trackId: track.id!,
|
||||
sourceId: siblings.first.info.id,
|
||||
sourceType: const Value(SourceType.youtube),
|
||||
),
|
||||
);
|
||||
|
||||
return YoutubeSourcedTrack(
|
||||
ref: ref,
|
||||
@ -283,15 +286,14 @@ class YoutubeSourcedTrack extends SourcedTrack {
|
||||
onTimeout: () => throw ClientException("Timeout"),
|
||||
);
|
||||
|
||||
await SourceMatch.box.put(
|
||||
id!,
|
||||
SourceMatch(
|
||||
id: id!,
|
||||
sourceType: SourceType.jiosaavn,
|
||||
createdAt: DateTime.now(),
|
||||
sourceId: newSourceInfo.id,
|
||||
),
|
||||
);
|
||||
final database = ref.read(databaseProvider);
|
||||
await database.into(database.sourceMatchTable).insert(
|
||||
SourceMatchTableCompanion.insert(
|
||||
trackId: id!,
|
||||
sourceId: newSourceInfo.id,
|
||||
sourceType: const Value(SourceType.youtube),
|
||||
),
|
||||
);
|
||||
|
||||
return YoutubeSourcedTrack(
|
||||
ref: ref,
|
||||
|
@ -6,6 +6,7 @@ import 'package:spotube/modules/library/user_local_tracks.dart';
|
||||
import 'package:spotube/modules/root/update_dialog.dart';
|
||||
import 'package:spotube/models/logger.dart';
|
||||
import 'package:spotube/models/lyrics.dart';
|
||||
import 'package:spotube/provider/database/database.dart';
|
||||
import 'package:spotube/services/dio/dio.dart';
|
||||
import 'package:spotube/services/sourced_track/sourced_track.dart';
|
||||
|
||||
@ -20,7 +21,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:spotube/collections/env.dart';
|
||||
|
||||
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
||||
import 'package:version/version.dart';
|
||||
|
||||
abstract class ServiceUtils {
|
||||
@ -392,7 +392,14 @@ abstract class ServiceUtils {
|
||||
WidgetRef ref,
|
||||
) async {
|
||||
if (!Env.enableUpdateChecker) return;
|
||||
if (!ref.read(userPreferencesProvider.select((s) => s.checkUpdate))) return;
|
||||
final database = ref.read(databaseProvider);
|
||||
final checkUpdate = await (database.selectOnly(database.preferencesTable)
|
||||
..addColumns([database.preferencesTable.checkUpdate])
|
||||
..where(database.preferencesTable.id.equals(0)))
|
||||
.map((row) => row.read(database.preferencesTable.checkUpdate))
|
||||
.getSingleOrNull();
|
||||
|
||||
if (checkUpdate == false) return;
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
|
||||
if (Env.releaseChannel == ReleaseChannel.nightly) {
|
||||
|
Loading…
Reference in New Issue
Block a user