improved tab & topic handling

This commit is contained in:
Fabian Freund
2024-08-28 16:00:39 +02:00
parent 95dd254484
commit 0a7e84236f
43 changed files with 2035 additions and 847 deletions
+12 -16
View File
@@ -1,19 +1,14 @@
import 'dart:ui';
import 'package:collection/collection.dart';
import 'package:lensai/features/topics/data/database/database.dart';
import 'package:lensai/features/topics/data/models/topic_data.dart';
import 'package:lensai/features/topics/data/providers.dart';
import 'package:lensai/features/topics/domain/repositories/topic.dart';
import 'package:lensai/features/topics/utils/color_palette.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'providers.g.dart';
@Riverpod()
Stream<List<TopicData>> topicList(TopicListRef ref) {
final repository = ref.watch(topicRepositoryProvider.notifier);
return repository.watchTopics();
}
@Riverpod(keepAlive: true)
class SelectedTopic extends _$SelectedTopic {
void setTopic(String id) {
@@ -40,21 +35,22 @@ class SelectedTopic extends _$SelectedTopic {
@Riverpod()
Stream<TopicData?> selectedTopicData(SelectedTopicDataRef ref) {
final repository = ref.watch(topicRepositoryProvider.notifier);
final selectedBangTrigger = ref.watch(selectedTopicProvider);
return repository.watchTopic(selectedBangTrigger);
}
final db = ref.watch(tabDatabaseProvider);
final selectedTopic = ref.watch(selectedTopicProvider);
@Riverpod()
Future<Set<Color>> distinctTopicColors(DistinctTopicColorsRef ref) {
final repository = ref.watch(topicRepositoryProvider.notifier);
return repository.getDistinctColors();
if (selectedTopic != null) {
return db.topicDao.getTopicData(selectedTopic).watchSingleOrNull();
}
return Stream.value(null);
}
@Riverpod()
Future<Color> unusedRandomTopicColor(UnusedRandomTopicColorRef ref) async {
final repository = ref.watch(topicRepositoryProvider.notifier);
final allColors = colorTypes.flattened.toList();
final usedColors = await ref.read(distinctTopicColorsProvider.future);
final usedColors = await repository.getDistinctColors();
Color randomColor;
do {
@@ -6,21 +6,7 @@ part of 'providers.dart';
// RiverpodGenerator
// **************************************************************************
String _$topicListHash() => r'7220aef5653bb3c2b44b016ce4f083f20896b353';
/// See also [topicList].
@ProviderFor(topicList)
final topicListProvider = AutoDisposeStreamProvider<List<TopicData>>.internal(
topicList,
name: r'topicListProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$topicListHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef TopicListRef = AutoDisposeStreamProviderRef<List<TopicData>>;
String _$selectedTopicDataHash() => r'191ad088ab90ef2348a836593f92b48d095afdc8';
String _$selectedTopicDataHash() => r'fa450784052498014f592c356bde4ff5ec675281';
/// See also [selectedTopicData].
@ProviderFor(selectedTopicData)
@@ -36,25 +22,8 @@ final selectedTopicDataProvider =
);
typedef SelectedTopicDataRef = AutoDisposeStreamProviderRef<TopicData?>;
String _$distinctTopicColorsHash() =>
r'c671f349615313d3b17e93e9e46fae12889e5e1f';
/// See also [distinctTopicColors].
@ProviderFor(distinctTopicColors)
final distinctTopicColorsProvider =
AutoDisposeFutureProvider<Set<Color>>.internal(
distinctTopicColors,
name: r'distinctTopicColorsProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$distinctTopicColorsHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef DistinctTopicColorsRef = AutoDisposeFutureProviderRef<Set<Color>>;
String _$unusedRandomTopicColorHash() =>
r'8f6907bb50a5bf2ac0320e93531d9e61616337b9';
r'099730b0d987cc37bcae4ef5c999cbebfa67d7da';
/// See also [unusedRandomTopicColor].
@ProviderFor(unusedRandomTopicColor)
@@ -1,5 +1,7 @@
import 'package:drift/drift.dart';
import 'package:lensai/features/topics/data/database/database.dart';
import 'package:lensai/features/topics/data/providers.dart';
import 'package:lensai/features/web_view/domain/entities/abstract/tab.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'tab.g.dart';
@@ -9,7 +11,49 @@ class TabRepository extends _$TabRepository {
late TabDatabase _db;
@override
void build() {
Stream<List<TabData>> build() {
_db = ref.watch(tabDatabaseProvider);
return _db.tabDao.watchTabs();
}
Future<void> updateTab(
String id, {
Value<Uri> url = const Value.absent(),
Value<String?> title = const Value.absent(),
Value<String?> topicId = const Value.absent(),
Value<Uint8List?> screenshot = const Value.absent(),
}) {
return _db.tabDao.updateTab(
id,
timestamp: DateTime.now(),
url: url,
title: title,
topicId: topicId,
screenshot: screenshot,
);
}
Future<void> deleteTab(String id) {
return _db.tabDao.deleteTab(id);
}
}
@Riverpod()
class TopicTabRepository extends _$TopicTabRepository {
late TabDatabase _db;
@override
Stream<List<String>> build(String? topicId) {
_db = ref.watch(tabDatabaseProvider);
return _db.tabDao.watchTopicTabs(topicId);
}
Future<void> addTab(ITab tab) {
assert(tab.topicId == topicId);
return _db.tabDao.upsertTab(tab, DateTime.now());
}
Future<void> closeAllTabs() {
return _db.tabDao.deleteTopicTabs(topicId);
}
}
@@ -6,11 +6,12 @@ part of 'tab.dart';
// RiverpodGenerator
// **************************************************************************
String _$tabRepositoryHash() => r'3f564f553e9586df34e927b20fe4bc860e0814e9';
String _$tabRepositoryHash() => r'454e182a99910512be72279f68caa0af125ed165';
/// See also [TabRepository].
@ProviderFor(TabRepository)
final tabRepositoryProvider = NotifierProvider<TabRepository, void>.internal(
final tabRepositoryProvider =
StreamNotifierProvider<TabRepository, List<TabData>>.internal(
TabRepository.new,
name: r'tabRepositoryProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
@@ -20,6 +21,172 @@ final tabRepositoryProvider = NotifierProvider<TabRepository, void>.internal(
allTransitiveDependencies: null,
);
typedef _$TabRepository = Notifier<void>;
typedef _$TabRepository = StreamNotifier<List<TabData>>;
String _$topicTabRepositoryHash() =>
r'52ceb013e0b31046fdd0a00d031392ba84b9ecda';
/// Copied from Dart SDK
class _SystemHash {
_SystemHash._();
static int combine(int hash, int value) {
// ignore: parameter_assignments
hash = 0x1fffffff & (hash + value);
// ignore: parameter_assignments
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
return hash ^ (hash >> 6);
}
static int finish(int hash) {
// ignore: parameter_assignments
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
// ignore: parameter_assignments
hash = hash ^ (hash >> 11);
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
}
}
abstract class _$TopicTabRepository
extends BuildlessAutoDisposeStreamNotifier<List<String>> {
late final String? topicId;
Stream<List<String>> build(
String? topicId,
);
}
/// See also [TopicTabRepository].
@ProviderFor(TopicTabRepository)
const topicTabRepositoryProvider = TopicTabRepositoryFamily();
/// See also [TopicTabRepository].
class TopicTabRepositoryFamily extends Family<AsyncValue<List<String>>> {
/// See also [TopicTabRepository].
const TopicTabRepositoryFamily();
/// See also [TopicTabRepository].
TopicTabRepositoryProvider call(
String? topicId,
) {
return TopicTabRepositoryProvider(
topicId,
);
}
@override
TopicTabRepositoryProvider getProviderOverride(
covariant TopicTabRepositoryProvider provider,
) {
return call(
provider.topicId,
);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'topicTabRepositoryProvider';
}
/// See also [TopicTabRepository].
class TopicTabRepositoryProvider extends AutoDisposeStreamNotifierProviderImpl<
TopicTabRepository, List<String>> {
/// See also [TopicTabRepository].
TopicTabRepositoryProvider(
String? topicId,
) : this._internal(
() => TopicTabRepository()..topicId = topicId,
from: topicTabRepositoryProvider,
name: r'topicTabRepositoryProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$topicTabRepositoryHash,
dependencies: TopicTabRepositoryFamily._dependencies,
allTransitiveDependencies:
TopicTabRepositoryFamily._allTransitiveDependencies,
topicId: topicId,
);
TopicTabRepositoryProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.topicId,
}) : super.internal();
final String? topicId;
@override
Stream<List<String>> runNotifierBuild(
covariant TopicTabRepository notifier,
) {
return notifier.build(
topicId,
);
}
@override
Override overrideWith(TopicTabRepository Function() create) {
return ProviderOverride(
origin: this,
override: TopicTabRepositoryProvider._internal(
() => create()..topicId = topicId,
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
topicId: topicId,
),
);
}
@override
AutoDisposeStreamNotifierProviderElement<TopicTabRepository, List<String>>
createElement() {
return _TopicTabRepositoryProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is TopicTabRepositoryProvider && other.topicId == topicId;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, topicId.hashCode);
return _SystemHash.finish(hash);
}
}
mixin TopicTabRepositoryRef
on AutoDisposeStreamNotifierProviderRef<List<String>> {
/// The parameter `topicId` of this provider.
String? get topicId;
}
class _TopicTabRepositoryProviderElement
extends AutoDisposeStreamNotifierProviderElement<TopicTabRepository,
List<String>> with TopicTabRepositoryRef {
_TopicTabRepositoryProviderElement(super.provider);
@override
String? get topicId => (origin as TopicTabRepositoryProvider).topicId;
}
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
@@ -1,6 +1,7 @@
import 'dart:ui';
import 'package:lensai/features/topics/data/database/database.dart';
import 'package:lensai/features/topics/data/models/topic_data.dart';
import 'package:lensai/features/topics/data/providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -11,8 +12,9 @@ class TopicRepository extends _$TopicRepository {
late TabDatabase _db;
@override
void build() {
Stream<List<TopicDataWithCount>> build() {
_db = ref.watch(tabDatabaseProvider);
return _db.topicsWithCount().watch();
}
Future<void> addTopic({required String? name, required Color color}) {
@@ -31,18 +33,6 @@ class TopicRepository extends _$TopicRepository {
return _db.topicDao.deleteTopic(id);
}
Stream<List<TopicData>> watchTopics() {
return _db.topics().watch();
}
Stream<TopicData?> watchTopic(String? id) {
if (id != null) {
return _db.topicDao.getTopicData(id).watchSingleOrNull();
} else {
return Stream.value(null);
}
}
Future<Set<Color>> getDistinctColors() {
return _db.topicDao
.getDistinctColors()
@@ -6,12 +6,12 @@ part of 'topic.dart';
// RiverpodGenerator
// **************************************************************************
String _$topicRepositoryHash() => r'f0e8d3170d3706a79decfbe4700f20fcdebfae2c';
String _$topicRepositoryHash() => r'3b75c5fb1a081ba6d90e2ccb781469d0aa87c415';
/// See also [TopicRepository].
@ProviderFor(TopicRepository)
final topicRepositoryProvider =
NotifierProvider<TopicRepository, void>.internal(
StreamNotifierProvider<TopicRepository, List<TopicDataWithCount>>.internal(
TopicRepository.new,
name: r'topicRepositoryProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
@@ -21,6 +21,6 @@ final topicRepositoryProvider =
allTransitiveDependencies: null,
);
typedef _$TopicRepository = Notifier<void>;
typedef _$TopicRepository = StreamNotifier<List<TopicDataWithCount>>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member