refactor tabs

This commit is contained in:
Fabian Freund
2025-10-01 12:57:00 +02:00
parent aff82ce4ae
commit 004532d8ae
2 changed files with 80 additions and 124 deletions
@@ -50,6 +50,39 @@ import 'package:weblibre/presentation/hooks/listenable_callback.dart';
import 'package:weblibre/presentation/widgets/speech_to_text_button.dart';
import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
int calculateCrossAxisItemCount({
required double screenWidth,
required double horizontalPadding,
required double crossAxisSpacing,
}) {
final totalHorizontalPadding = horizontalPadding * 2;
final availableWidth =
screenWidth - totalHorizontalPadding - crossAxisSpacing;
final crossAxisCount = availableWidth ~/ 180.0;
return crossAxisCount;
}
double calculateItemHeight({
required double screenWidth,
required double childAspectRatio,
required double horizontalPadding,
required double mainAxisSpacing,
required double crossAxisSpacing,
required int crossAxisCount,
}) {
final totalHorizontalPadding = horizontalPadding * 2;
final totalCrossAxisSpacing = crossAxisSpacing * (crossAxisCount - 1);
final availableWidth =
screenWidth - totalHorizontalPadding - totalCrossAxisSpacing;
final itemWidth = availableWidth / crossAxisCount;
final itemHeight = itemWidth / childAspectRatio;
final totalItemHeight = itemHeight + mainAxisSpacing;
return totalItemHeight;
}
class _TabDraggable extends HookConsumerWidget {
final TabEntity entity;
final String? suggestedContainerId;
@@ -84,7 +117,17 @@ class _TabDraggable extends HookConsumerWidget {
key: ValueKey(entity.tabId),
tabId: entity.tabId,
activeTabId: activeTab,
containerId: suggestedContainerId!,
onTap: () async {
final containerData = await ref
.read(containerRepositoryProvider.notifier)
.getContainerData(suggestedContainerId!);
if (containerData != null) {
await ref
.read(tabDataRepositoryProvider.notifier)
.assignContainer(entity.tabId, containerData);
}
},
)
: SingleTabPreview(
key: ValueKey(entity.tabId),
@@ -331,39 +374,6 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
super.key,
});
int _calculateCrossAxisItemCount({
required double screenWidth,
required double horizontalPadding,
required double crossAxisSpacing,
}) {
final totalHorizontalPadding = horizontalPadding * 2;
final availableWidth =
screenWidth - totalHorizontalPadding - crossAxisSpacing;
final crossAxisCount = availableWidth ~/ 180.0;
return crossAxisCount;
}
double _calculateItemHeight({
required double screenWidth,
required double childAspectRatio,
required double horizontalPadding,
required double mainAxisSpacing,
required double crossAxisSpacing,
required int crossAxisCount,
}) {
final totalHorizontalPadding = horizontalPadding * 2;
final totalCrossAxisSpacing = crossAxisSpacing * (crossAxisCount - 1);
final availableWidth =
screenWidth - totalHorizontalPadding - totalCrossAxisSpacing;
final itemWidth = availableWidth / crossAxisCount;
final itemHeight = itemWidth / childAspectRatio;
final totalItemHeight = itemHeight + mainAxisSpacing;
return totalItemHeight;
}
@override
Widget build(BuildContext context, WidgetRef ref) {
return Stack(
@@ -423,7 +433,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
final activeTab = ref.watch(selectedTabProvider);
final crossAxisCount = useMemoized(() {
final calculatedCount = _calculateCrossAxisItemCount(
final calculatedCount = calculateCrossAxisItemCount(
screenWidth: screenWidth,
horizontalPadding: 4.0,
crossAxisSpacing: 8.0,
@@ -433,7 +443,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
}, [screenWidth, itemCount]);
final itemHeight = useMemoized(
() => _calculateItemHeight(
() => calculateItemHeight(
screenWidth: screenWidth,
childAspectRatio: 0.75,
horizontalPadding: 4.0,
@@ -628,37 +638,6 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
super.key,
});
int _calculateCrossAxisItemCount({
required double screenWidth,
required double horizontalPadding,
required double crossAxisSpacing,
}) {
final totalHorizontalPadding = horizontalPadding * 2;
final availableWidth =
screenWidth - totalHorizontalPadding - crossAxisSpacing;
final crossAxisCount = availableWidth ~/ 180.0;
return crossAxisCount;
}
Size _calculateItemSize({
required double screenWidth,
required double childAspectRatio,
required double horizontalPadding,
required double crossAxisSpacing,
required int crossAxisCount,
}) {
final totalHorizontalPadding = horizontalPadding * 2;
final totalCrossAxisSpacing = crossAxisSpacing * (crossAxisCount - 1);
final availableWidth =
screenWidth - totalHorizontalPadding - totalCrossAxisSpacing;
final itemWidth = availableWidth / crossAxisCount;
final itemHeight = itemWidth / childAspectRatio;
return Size(itemWidth, itemHeight);
}
@override
Widget build(BuildContext context, WidgetRef ref) {
return Stack(
@@ -670,6 +649,8 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
Expanded(
child: HookConsumer(
builder: (context, ref, child) {
final screenWidth = MediaQuery.of(context).size.width;
final filteredTabEntities = ref.watch(
seamlessFilteredTabEntitiesProvider(
searchPartition: TabSearchPartition.preview,
@@ -682,40 +663,32 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
final activeTab = ref.watch(selectedTabProvider);
final crossAxisCount = useMemoized(
() {
final calculatedCount = _calculateCrossAxisItemCount(
screenWidth: MediaQuery.of(context).size.width,
horizontalPadding: 4.0,
crossAxisSpacing: 8.0,
);
final crossAxisCount = useMemoized(() {
final calculatedCount = calculateCrossAxisItemCount(
screenWidth: screenWidth,
horizontalPadding: 4.0,
crossAxisSpacing: 8.0,
);
return math.max(
math.min(
calculatedCount,
filteredTabEntities.value.length,
),
2,
);
},
[
MediaQuery.of(context).size.width,
filteredTabEntities.value.length,
],
);
return math.max(
math.min(
calculatedCount,
filteredTabEntities.value.length,
),
2,
);
}, [screenWidth, filteredTabEntities.value.length]);
final itemSize = useMemoized(
() =>
_calculateItemSize(
screenWidth: MediaQuery.of(context).size.width,
childAspectRatio: 0.75,
horizontalPadding: 4.0,
crossAxisSpacing: 8.0,
crossAxisCount: crossAxisCount,
) +
//mainAxisSpacing
const Offset(0, 8.0),
[MediaQuery.of(context).size.width, crossAxisCount],
final itemHeight = useMemoized(
() => calculateItemHeight(
screenWidth: screenWidth,
childAspectRatio: 0.75,
horizontalPadding: 4.0,
crossAxisSpacing: 8.0,
crossAxisCount: crossAxisCount,
mainAxisSpacing: 8.0,
),
[screenWidth, crossAxisCount],
);
useEffect(() {
@@ -724,7 +697,7 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
);
if (index > -1) {
final offset = (index ~/ 2) * itemSize.height;
final offset = (index ~/ 2) * itemHeight;
if (offset != sheetScrollController.offset) {
unawaited(
@@ -33,7 +33,6 @@ import 'package:weblibre/features/geckoview/features/find_in_page/domain/entitie
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_entity.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
import 'package:weblibre/presentation/hooks/menu_controller.dart';
import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
@@ -380,46 +379,30 @@ class SingleTabPreview extends HookConsumerWidget {
}
}
class SuggestedSingleTabPreview extends HookConsumerWidget {
class SuggestedSingleTabPreview extends StatelessWidget {
final String tabId;
final String containerId;
final String? activeTabId;
final void Function()? onTap;
const SuggestedSingleTabPreview({
required this.tabId,
required this.containerId,
required this.activeTabId,
this.onTap,
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final hasTabState = ref.watch(
tabStateProvider(tabId).select((value) => value != null),
);
if (!hasTabState) {
return const SizedBox.shrink();
}
Widget build(BuildContext context) {
return Opacity(
opacity: 0.5,
child: TabPreview(
tabId: tabId,
isActive: tabId == activeTabId,
onTap: () async {
final containerData = await ref
.read(containerRepositoryProvider.notifier)
.getContainerData(containerId);
if (containerData != null) {
await ref
.read(tabDataRepositoryProvider.notifier)
.assignContainer(tabId, containerData);
}
},
onTap: onTap,
trailingChild: const IconButton(
visualDensity: VisualDensity(horizontal: -4.0, vertical: -4.0),
icon: Icon(MdiIcons.creation),
onPressed: null,
),