container pinning
This commit is contained in:
+10
-1
@@ -59,6 +59,7 @@ import 'package:weblibre/features/user/domain/repositories/general_settings.dart
|
||||
import 'package:weblibre/features/web_search/domain/controllers/sandbox_capture_controller.dart';
|
||||
import 'package:weblibre/presentation/widgets/selectable_chips.dart';
|
||||
import 'package:weblibre/presentation/widgets/url_icon.dart';
|
||||
import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
|
||||
|
||||
class BrowserTopAppBar extends StatelessWidget {
|
||||
final bool showMainToolbar;
|
||||
@@ -705,7 +706,15 @@ class QuickTabSwitcher extends HookConsumerWidget {
|
||||
hierarchical: false,
|
||||
sortPinnedFirst: sortPinnedFirst,
|
||||
);
|
||||
if (result == null) return;
|
||||
if (result == null) {
|
||||
if (context.mounted) {
|
||||
ui_helper.showInfoMessage(
|
||||
context,
|
||||
'Tab cannot be moved here',
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
await ref
|
||||
.read(tabDataRepositoryProvider.notifier)
|
||||
.reorderTabs(
|
||||
|
||||
+36
-6
@@ -97,6 +97,7 @@ class ContainerEditScreen extends HookConsumerWidget {
|
||||
);
|
||||
final clearDataOnExit = useState(initialContainer.metadata.clearDataOnExit);
|
||||
final assignedSites = useState(initialContainer.metadata.assignedSites);
|
||||
final isPinned = useState(initialContainer.isPinned);
|
||||
|
||||
final textController = useTextEditingController(
|
||||
text: initialContainer.name,
|
||||
@@ -108,6 +109,7 @@ class ContainerEditScreen extends HookConsumerWidget {
|
||||
return initialContainer.copyWith(
|
||||
name: name.isNotEmpty ? name : null,
|
||||
color: selectedColor.value,
|
||||
isPinned: isPinned.value,
|
||||
metadata: initialContainer.metadata.copyWith(
|
||||
contextualIdentity: contextualIdentity.value,
|
||||
iconData: selectedIcon.value,
|
||||
@@ -123,15 +125,18 @@ class ContainerEditScreen extends HookConsumerWidget {
|
||||
|
||||
Future<ContainerData> saveContainer() async {
|
||||
final container = buildContainer();
|
||||
final repository = ref.read(containerRepositoryProvider.notifier);
|
||||
switch (_mode) {
|
||||
case _DialogMode.create:
|
||||
await ref
|
||||
.read(containerRepositoryProvider.notifier)
|
||||
.addContainer(container);
|
||||
await repository.addContainer(container);
|
||||
case _DialogMode.edit:
|
||||
await ref
|
||||
.read(containerRepositoryProvider.notifier)
|
||||
.replaceContainer(container);
|
||||
await repository.replaceContainer(container);
|
||||
}
|
||||
if (isPinned.value != initialContainer.isPinned) {
|
||||
await repository.setContainerPinned(
|
||||
container.id,
|
||||
isPinned: isPinned.value,
|
||||
);
|
||||
}
|
||||
return container;
|
||||
}
|
||||
@@ -341,6 +346,31 @@ class ContainerEditScreen extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 28),
|
||||
Text(
|
||||
'Display',
|
||||
style: theme.textTheme.titleSmall?.copyWith(
|
||||
color: colorScheme.primary,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Card.filled(
|
||||
margin: EdgeInsets.zero,
|
||||
color: colorScheme.surfaceContainer,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: SwitchListTile.adaptive(
|
||||
value: isPinned.value,
|
||||
title: const Text('Pin Container'),
|
||||
subtitle: const Text(
|
||||
'Keep this container at the top of the list',
|
||||
),
|
||||
secondary: const Icon(MdiIcons.pin),
|
||||
onChanged: (value) {
|
||||
isPinned.value = value;
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
'Privacy & Security',
|
||||
style: theme.textTheme.titleSmall?.copyWith(
|
||||
|
||||
+6
@@ -21,6 +21,7 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:skeletonizer/skeletonizer.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
@@ -246,6 +247,11 @@ class _ContainerCard extends HookConsumerWidget {
|
||||
label:
|
||||
'$tabCount ${tabCount == 1 ? 'tab' : 'tabs'}',
|
||||
),
|
||||
if (container.isPinned)
|
||||
const _ContainerInfoChip(
|
||||
icon: MdiIcons.pin,
|
||||
label: 'Pinned',
|
||||
),
|
||||
if (container.metadata.contextualIdentity != null)
|
||||
const _ContainerInfoChip(
|
||||
icon: Icons.cookie_outlined,
|
||||
|
||||
+5
@@ -18,6 +18,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
import 'package:nullability/nullability.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/data/models/container_data.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/presentation/widgets/container_title.dart';
|
||||
@@ -62,6 +63,10 @@ Widget buildContainerChipLabel(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (container.isPinned) ...[
|
||||
Icon(MdiIcons.pin, size: 14, color: foregroundColor),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
Flexible(child: ContainerTitle(container: container)),
|
||||
if (trailing != null) ...[const SizedBox(width: 6), trailing],
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user