refactor tab draggables
This commit is contained in:
+77
-66
@@ -1,7 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
@@ -27,6 +26,64 @@ import 'package:weblibre/features/tor/presentation/controllers/start_tor_proxy.d
|
|||||||
import 'package:weblibre/presentation/hooks/listenable_callback.dart';
|
import 'package:weblibre/presentation/hooks/listenable_callback.dart';
|
||||||
import 'package:weblibre/presentation/widgets/speech_to_text_button.dart';
|
import 'package:weblibre/presentation/widgets/speech_to_text_button.dart';
|
||||||
|
|
||||||
|
class _TabDraggable extends HookConsumerWidget {
|
||||||
|
final TabEntity entity;
|
||||||
|
final VoidCallback onClose;
|
||||||
|
|
||||||
|
const _TabDraggable({
|
||||||
|
required super.key,
|
||||||
|
required this.entity,
|
||||||
|
required this.onClose,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final activeTab = ref.watch(selectedTabProvider);
|
||||||
|
|
||||||
|
final dragData = ref.watch(
|
||||||
|
willAcceptDropProvider.select((value) {
|
||||||
|
final dragTabId = switch (value) {
|
||||||
|
ContainerDropData() => value.tabId,
|
||||||
|
DeleteDropData() => value.tabId,
|
||||||
|
null => null,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (dragTabId == entity.tabId) ? value : null;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
final tab = SingleTabPreview(
|
||||||
|
tabId: entity.tabId,
|
||||||
|
activeTabId: activeTab,
|
||||||
|
onClose: onClose,
|
||||||
|
sourceSearchQuery: switch (entity) {
|
||||||
|
DefaultTabEntity _ => null,
|
||||||
|
final SearchResultTabEntity entity => entity.searchQuery,
|
||||||
|
TabTreeEntity _ => throw UnimplementedError(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return CustomDraggable(
|
||||||
|
key: Key(entity.tabId),
|
||||||
|
data: TabDragData(entity.tabId),
|
||||||
|
child: switch (dragData) {
|
||||||
|
ContainerDropData() => Opacity(
|
||||||
|
opacity: 0.3,
|
||||||
|
child: Transform.scale(scale: 0.9, child: tab),
|
||||||
|
),
|
||||||
|
DeleteDropData() => Opacity(
|
||||||
|
opacity: 0.3,
|
||||||
|
child: ColorFiltered(
|
||||||
|
colorFilter: const ColorFilter.mode(Colors.red, BlendMode.modulate),
|
||||||
|
child: tab,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
null => tab,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _TabSheetHeader extends HookConsumerWidget {
|
class _TabSheetHeader extends HookConsumerWidget {
|
||||||
static const headerSize = 124.0;
|
static const headerSize = 124.0;
|
||||||
|
|
||||||
@@ -245,7 +302,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
builder: (context, ref, child) {
|
builder: (context, ref, child) {
|
||||||
final container = ref.watch(selectedContainerProvider);
|
final container = ref.watch(selectedContainerProvider);
|
||||||
|
|
||||||
final filteredTabIds = ref.watch(
|
final filteredTabEntities = ref.watch(
|
||||||
seamlessFilteredTabEntitiesProvider(
|
seamlessFilteredTabEntitiesProvider(
|
||||||
searchPartition: TabSearchPartition.preview,
|
searchPartition: TabSearchPartition.preview,
|
||||||
// ignore: document_ignores using fast equatable
|
// ignore: document_ignores using fast equatable
|
||||||
@@ -268,13 +325,16 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return math.max(
|
return math.max(
|
||||||
math.min(calculatedCount, filteredTabIds.value.length),
|
math.min(
|
||||||
|
calculatedCount,
|
||||||
|
filteredTabEntities.value.length,
|
||||||
|
),
|
||||||
2,
|
2,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
MediaQuery.of(context).size.width,
|
MediaQuery.of(context).size.width,
|
||||||
filteredTabIds.value.length,
|
filteredTabEntities.value.length,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -291,7 +351,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
final index = filteredTabIds.value.indexWhere(
|
final index = filteredTabEntities.value.indexWhere(
|
||||||
(entity) => entity.tabId == activeTab,
|
(entity) => entity.tabId == activeTab,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -310,69 +370,20 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}, [filteredTabIds, activeTab]);
|
}, [filteredTabEntities, activeTab]);
|
||||||
|
|
||||||
final tabs = useMemoized(() {
|
final tabs = useMemoized(() {
|
||||||
return filteredTabIds.value
|
return filteredTabEntities.value
|
||||||
.where((entity) => entity is! TabTreeEntity)
|
.where((entity) => entity is! TabTreeEntity)
|
||||||
.mapIndexed((index, entity) {
|
.map(
|
||||||
final child = Consumer(
|
(entity) => _TabDraggable(
|
||||||
child: SingleTabPreview(
|
|
||||||
tabId: entity.tabId,
|
|
||||||
activeTabId: activeTab,
|
|
||||||
onClose: onClose,
|
|
||||||
sourceSearchQuery: switch (entity) {
|
|
||||||
DefaultTabEntity() => null,
|
|
||||||
SearchResultTabEntity() => entity.searchQuery,
|
|
||||||
TabTreeEntity() => throw UnimplementedError(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
builder: (context, ref, child) {
|
|
||||||
final dragData = ref.watch(
|
|
||||||
willAcceptDropProvider.select((value) {
|
|
||||||
final dragTabId = switch (value) {
|
|
||||||
ContainerDropData() => value.tabId,
|
|
||||||
DeleteDropData() => value.tabId,
|
|
||||||
null => null,
|
|
||||||
};
|
|
||||||
|
|
||||||
return (dragTabId == entity.tabId)
|
|
||||||
? value
|
|
||||||
: null;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
return switch (dragData) {
|
|
||||||
ContainerDropData() => Opacity(
|
|
||||||
opacity: 0.3,
|
|
||||||
child: Transform.scale(
|
|
||||||
scale: 0.9,
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
DeleteDropData() => Opacity(
|
|
||||||
opacity: 0.3,
|
|
||||||
child: ColorFiltered(
|
|
||||||
colorFilter: const ColorFilter.mode(
|
|
||||||
Colors.red,
|
|
||||||
BlendMode.modulate,
|
|
||||||
),
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
null => child!,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return CustomDraggable(
|
|
||||||
key: Key(entity.tabId),
|
key: Key(entity.tabId),
|
||||||
data: TabDragData(entity.tabId),
|
entity: entity,
|
||||||
child: child,
|
onClose: onClose,
|
||||||
);
|
),
|
||||||
})
|
)
|
||||||
.toList();
|
.toList();
|
||||||
}, [filteredTabIds, activeTab]);
|
}, [filteredTabEntities]);
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
@@ -396,7 +407,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
containerRepositoryProvider.notifier,
|
containerRepositoryProvider.notifier,
|
||||||
);
|
);
|
||||||
|
|
||||||
final tabId = filteredTabIds.value[oldIndex].tabId;
|
final tabId = filteredTabEntities.value[oldIndex].tabId;
|
||||||
final containerId = await ref
|
final containerId = await ref
|
||||||
.read(tabDataRepositoryProvider.notifier)
|
.read(tabDataRepositoryProvider.notifier)
|
||||||
.containerTabId(tabId);
|
.containerTabId(tabId);
|
||||||
@@ -407,14 +418,14 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
containerId,
|
containerId,
|
||||||
);
|
);
|
||||||
} else if (newIndex >=
|
} else if (newIndex >=
|
||||||
filteredTabIds.value.length - 1) {
|
filteredTabEntities.value.length - 1) {
|
||||||
key = await containerRepository.getTrailingOrderKey(
|
key = await containerRepository.getTrailingOrderKey(
|
||||||
containerId,
|
containerId,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final orderAfterIndex = newIndex;
|
final orderAfterIndex = newIndex;
|
||||||
key = await containerRepository.getOrderKeyAfterTab(
|
key = await containerRepository.getOrderKeyAfterTab(
|
||||||
filteredTabIds.value[orderAfterIndex].tabId,
|
filteredTabEntities.value[orderAfterIndex].tabId,
|
||||||
containerId,
|
containerId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user