reorganize menus
This commit is contained in:
+7
-7
@@ -349,13 +349,6 @@ class BrowserBottomAppBar extends HookConsumerWidget {
|
|||||||
leadingIcon: const Icon(Icons.settings),
|
leadingIcon: const Icon(Icons.settings),
|
||||||
child: const Text('Settings'),
|
child: const Text('Settings'),
|
||||||
),
|
),
|
||||||
MenuItemButton(
|
|
||||||
onPressed: () async {
|
|
||||||
await const HistoryRoute().push(context);
|
|
||||||
},
|
|
||||||
leadingIcon: const Icon(Icons.history),
|
|
||||||
child: const Text('History'),
|
|
||||||
),
|
|
||||||
Consumer(
|
Consumer(
|
||||||
builder: (context, childRef, child) {
|
builder: (context, childRef, child) {
|
||||||
final browserExtensions = childRef.watch(
|
final browserExtensions = childRef.watch(
|
||||||
@@ -437,6 +430,13 @@ class BrowserBottomAppBar extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
MenuItemButton(
|
||||||
|
onPressed: () async {
|
||||||
|
await const HistoryRoute().push(context);
|
||||||
|
},
|
||||||
|
leadingIcon: const Icon(Icons.history),
|
||||||
|
child: const Text('History'),
|
||||||
|
),
|
||||||
MenuItemButton(
|
MenuItemButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await BookmarkListRoute(
|
await BookmarkListRoute(
|
||||||
|
|||||||
@@ -130,41 +130,17 @@ class TabMenu extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
MenuItemButton(
|
Visibility(
|
||||||
onPressed: () async {
|
visible: showFeeds.value,
|
||||||
await ref
|
replacement: MenuItemButton(
|
||||||
.read(tabRepositoryProvider.notifier)
|
closeOnActivate: false,
|
||||||
.closeTab(selectedTabId);
|
leadingIcon: const Icon(Icons.rss_feed),
|
||||||
|
child: const Text('Fetch Feeds'),
|
||||||
if (context.mounted) {
|
onPressed: () {
|
||||||
ui_helper.showTabUndoClose(
|
showFeeds.value = true;
|
||||||
context,
|
},
|
||||||
ref.read(tabRepositoryProvider.notifier).undoClose,
|
),
|
||||||
);
|
child: WebsiteFeedMenuButton(selectedTabId),
|
||||||
}
|
|
||||||
},
|
|
||||||
leadingIcon: const Icon(Icons.close),
|
|
||||||
child: const Text('Close Tab'),
|
|
||||||
),
|
|
||||||
MenuItemButton(
|
|
||||||
leadingIcon: const Icon(MdiIcons.contentCopy),
|
|
||||||
child: const Text('Copy address'),
|
|
||||||
onPressed: () async {
|
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
|
||||||
|
|
||||||
await Clipboard.setData(
|
|
||||||
ClipboardData(text: tabState.url.toString()),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
MenuItemButton(
|
|
||||||
leadingIcon: const Icon(Icons.open_in_browser),
|
|
||||||
child: const Text('Launch External'),
|
|
||||||
onPressed: () async {
|
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
|
||||||
|
|
||||||
await ui_helper.launchUrlFeedback(context, tabState.url);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
MenuItemButton(
|
MenuItemButton(
|
||||||
leadingIcon: const Icon(MdiIcons.bookmarkPlus),
|
leadingIcon: const Icon(MdiIcons.bookmarkPlus),
|
||||||
@@ -182,205 +158,251 @@ class TabMenu extends HookConsumerWidget {
|
|||||||
).push(context);
|
).push(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MenuItemButton(
|
SubmenuButton(
|
||||||
leadingIcon: const Icon(MdiIcons.tabPlus),
|
menuChildren: [
|
||||||
child: const Text('Clone tab'),
|
MenuItemButton(
|
||||||
onPressed: () async {
|
leadingIcon: const Icon(MdiIcons.tabPlus),
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
child: const Text('Regular'),
|
||||||
|
onPressed: () async {
|
||||||
final tabId = await ref
|
|
||||||
.read(tabRepositoryProvider.notifier)
|
|
||||||
.addTab(url: tabState.url, private: false, selectTab: false);
|
|
||||||
|
|
||||||
if (context.mounted) {
|
|
||||||
//save reference before pop `ref` gets disposed
|
|
||||||
final repo = ref.read(tabRepositoryProvider.notifier);
|
|
||||||
|
|
||||||
ui_helper.showTabSwitchMessage(
|
|
||||||
context,
|
|
||||||
onSwitch: () async {
|
|
||||||
await repo.selectTab(tabId);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
MenuItemButton(
|
|
||||||
leadingIcon: const Icon(MdiIcons.tabUnselected),
|
|
||||||
child: const Text('Clone as private tab'),
|
|
||||||
onPressed: () async {
|
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
|
||||||
|
|
||||||
final tabId = await ref
|
|
||||||
.read(tabRepositoryProvider.notifier)
|
|
||||||
.addTab(url: tabState.url, private: true, selectTab: false);
|
|
||||||
|
|
||||||
if (context.mounted) {
|
|
||||||
//save reference before pop `ref` gets disposed
|
|
||||||
final repo = ref.read(tabRepositoryProvider.notifier);
|
|
||||||
|
|
||||||
ui_helper.showTabSwitchMessage(
|
|
||||||
context,
|
|
||||||
onSwitch: () async {
|
|
||||||
await repo.selectTab(tabId);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
MenuItemButton(
|
|
||||||
leadingIcon: const Icon(MdiIcons.folderArrowUpDownOutline),
|
|
||||||
child: const Text('Assign container'),
|
|
||||||
onPressed: () async {
|
|
||||||
final targetContainerId = await const ContainerSelectionRoute()
|
|
||||||
.push<String?>(context);
|
|
||||||
|
|
||||||
if (targetContainerId != null) {
|
|
||||||
final containerData = await ref
|
|
||||||
.read(containerRepositoryProvider.notifier)
|
|
||||||
.getContainerData(targetContainerId);
|
|
||||||
|
|
||||||
if (containerData != null) {
|
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||||
|
|
||||||
await ref
|
final tabId = await ref
|
||||||
.read(tabDataRepositoryProvider.notifier)
|
.read(tabRepositoryProvider.notifier)
|
||||||
.assignContainer(tabState.id, containerData);
|
.addTab(
|
||||||
}
|
url: tabState.url,
|
||||||
}
|
private: false,
|
||||||
},
|
selectTab: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
|
//save reference before pop `ref` gets disposed
|
||||||
|
final repo = ref.read(tabRepositoryProvider.notifier);
|
||||||
|
|
||||||
|
ui_helper.showTabSwitchMessage(
|
||||||
|
context,
|
||||||
|
onSwitch: () async {
|
||||||
|
await repo.selectTab(tabId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
MenuItemButton(
|
||||||
|
leadingIcon: const Icon(MdiIcons.tabUnselected),
|
||||||
|
child: const Text('Private'),
|
||||||
|
onPressed: () async {
|
||||||
|
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||||
|
|
||||||
|
final tabId = await ref
|
||||||
|
.read(tabRepositoryProvider.notifier)
|
||||||
|
.addTab(url: tabState.url, private: true, selectTab: false);
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
|
//save reference before pop `ref` gets disposed
|
||||||
|
final repo = ref.read(tabRepositoryProvider.notifier);
|
||||||
|
|
||||||
|
ui_helper.showTabSwitchMessage(
|
||||||
|
context,
|
||||||
|
onSwitch: () async {
|
||||||
|
await repo.selectTab(tabId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
leadingIcon: const Icon(MdiIcons.tabPlus),
|
||||||
|
child: const Text('Clone Tab'),
|
||||||
),
|
),
|
||||||
Consumer(
|
SubmenuButton(
|
||||||
child: MenuItemButton(
|
menuChildren: [
|
||||||
leadingIcon: const Icon(MdiIcons.webPlus),
|
MenuItemButton(
|
||||||
child: const Text('Assign Site to Container'),
|
leadingIcon: const Icon(MdiIcons.folderArrowUpDownOutline),
|
||||||
onPressed: () async {
|
child: const Text('Assign Container'),
|
||||||
final targetContainerId = await const ContainerSelectionRoute()
|
onPressed: () async {
|
||||||
.push<String?>(context);
|
final targetContainerId = await const ContainerSelectionRoute()
|
||||||
|
.push<String?>(context);
|
||||||
|
|
||||||
if (targetContainerId != null) {
|
if (targetContainerId != null) {
|
||||||
final containerData = await ref
|
final containerData = await ref
|
||||||
.read(containerRepositoryProvider.notifier)
|
.read(containerRepositoryProvider.notifier)
|
||||||
.getContainerData(targetContainerId);
|
.getContainerData(targetContainerId);
|
||||||
|
|
||||||
if (containerData != null) {
|
if (containerData != null) {
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId));
|
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||||
final origin = tabState?.url.origin.mapNotNull(Uri.parse);
|
|
||||||
|
|
||||||
if (origin != null) {
|
|
||||||
await ref
|
await ref
|
||||||
.read(containerRepositoryProvider.notifier)
|
.read(tabDataRepositoryProvider.notifier)
|
||||||
.replaceContainer(
|
.assignContainer(tabState.id, containerData);
|
||||||
containerData.copyWith.metadata(
|
|
||||||
containerData.metadata.copyWith.assignedSites([
|
|
||||||
...?containerData.metadata.assignedSites,
|
|
||||||
origin,
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
),
|
||||||
),
|
Consumer(
|
||||||
builder: (context, ref, child) {
|
child: MenuItemButton(
|
||||||
final isSiteAssigned = ref.watch(
|
leadingIcon: const Icon(MdiIcons.webPlus),
|
||||||
watchIsCurrentSiteAssignedToContainerProvider,
|
child: const Text('URL relation'),
|
||||||
);
|
onPressed: () async {
|
||||||
|
final targetContainerId =
|
||||||
|
await const ContainerSelectionRoute().push<String?>(
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
|
||||||
return Visibility(
|
if (targetContainerId != null) {
|
||||||
visible: isSiteAssigned.hasValue && !isSiteAssigned.requireValue,
|
final containerData = await ref
|
||||||
child: child!,
|
.read(containerRepositoryProvider.notifier)
|
||||||
);
|
.getContainerData(targetContainerId);
|
||||||
},
|
|
||||||
),
|
|
||||||
Consumer(
|
|
||||||
child: MenuItemButton(
|
|
||||||
leadingIcon: const Icon(MdiIcons.folderCancelOutline),
|
|
||||||
child: const Text('Unassign container'),
|
|
||||||
onPressed: () async {
|
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
|
||||||
|
|
||||||
await ref
|
if (containerData != null) {
|
||||||
.read(tabDataRepositoryProvider.notifier)
|
final tabState = ref.read(
|
||||||
.unassignContainer(tabState.id);
|
tabStateProvider(selectedTabId),
|
||||||
},
|
);
|
||||||
),
|
final origin = tabState?.url.origin.mapNotNull(Uri.parse);
|
||||||
builder: (context, ref, child) {
|
|
||||||
final containerId = ref.watch(
|
|
||||||
watchContainerTabIdProvider(
|
|
||||||
selectedTabId,
|
|
||||||
).select((value) => value.value),
|
|
||||||
);
|
|
||||||
|
|
||||||
return Visibility(visible: containerId != null, child: child!);
|
if (origin != null) {
|
||||||
},
|
await ref
|
||||||
),
|
.read(containerRepositoryProvider.notifier)
|
||||||
MenuItemButton(
|
.replaceContainer(
|
||||||
leadingIcon: const Icon(Icons.share),
|
containerData.copyWith.metadata(
|
||||||
onPressed: () async {
|
containerData.metadata.copyWith.assignedSites([
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
...?containerData.metadata.assignedSites,
|
||||||
|
origin,
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
builder: (context, ref, child) {
|
||||||
|
final isSiteAssigned = ref.watch(
|
||||||
|
watchIsCurrentSiteAssignedToContainerProvider,
|
||||||
|
);
|
||||||
|
|
||||||
await SharePlus.instance.share(ShareParams(uri: tabState.url));
|
return Visibility(
|
||||||
},
|
visible:
|
||||||
trailingIcon: Row(
|
isSiteAssigned.hasValue && !isSiteAssigned.requireValue,
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: child!,
|
||||||
children: [
|
);
|
||||||
const VerticalDivider(indent: 4, endIndent: 4),
|
},
|
||||||
IconButton(
|
),
|
||||||
icon: const Icon(Icons.qr_code),
|
Consumer(
|
||||||
|
child: MenuItemButton(
|
||||||
|
leadingIcon: const Icon(MdiIcons.folderCancelOutline),
|
||||||
|
child: const Text('Unassign Container'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||||
|
|
||||||
await showQrCode(context, tabState.url.toString());
|
await ref
|
||||||
controller.close();
|
.read(tabDataRepositoryProvider.notifier)
|
||||||
|
.unassignContainer(tabState.id);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
builder: (context, ref, child) {
|
||||||
),
|
final containerId = ref.watch(
|
||||||
child: const Text('Share link'),
|
watchContainerTabIdProvider(
|
||||||
),
|
selectedTabId,
|
||||||
MenuItemButton(
|
).select((value) => value.value),
|
||||||
leadingIcon: const Icon(Icons.mobile_screen_share),
|
|
||||||
child: const Text('Share screenshot'),
|
|
||||||
onPressed: () async {
|
|
||||||
final screenshot = await ref
|
|
||||||
.read(selectedTabSessionProvider)
|
|
||||||
.requestScreenshot();
|
|
||||||
|
|
||||||
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
|
||||||
|
|
||||||
if (screenshot != null) {
|
|
||||||
ui.decodeImageFromList(screenshot, (result) async {
|
|
||||||
final png = await result.toByteData(
|
|
||||||
format: ui.ImageByteFormat.png,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (png != null) {
|
return Visibility(visible: containerId != null, child: child!);
|
||||||
final file = XFile.fromData(
|
},
|
||||||
png.buffer.asUint8List(),
|
),
|
||||||
mimeType: 'image/png',
|
],
|
||||||
);
|
leadingIcon: const Icon(MdiIcons.folder),
|
||||||
|
child: const Text('Container'),
|
||||||
|
),
|
||||||
|
SubmenuButton(
|
||||||
|
menuChildren: [
|
||||||
|
MenuItemButton(
|
||||||
|
leadingIcon: const Icon(Icons.open_in_browser),
|
||||||
|
child: const Text('Launch External'),
|
||||||
|
onPressed: () async {
|
||||||
|
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||||
|
|
||||||
await SharePlus.instance.share(
|
await ui_helper.launchUrlFeedback(context, tabState.url);
|
||||||
ShareParams(files: [file], subject: tabState.title),
|
},
|
||||||
);
|
),
|
||||||
|
MenuItemButton(
|
||||||
|
leadingIcon: const Icon(Icons.mobile_screen_share),
|
||||||
|
child: const Text('Share Screenshot'),
|
||||||
|
onPressed: () async {
|
||||||
|
final screenshot = await ref
|
||||||
|
.read(selectedTabSessionProvider)
|
||||||
|
.requestScreenshot();
|
||||||
|
|
||||||
|
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||||
|
|
||||||
|
if (screenshot != null) {
|
||||||
|
ui.decodeImageFromList(screenshot, (result) async {
|
||||||
|
final png = await result.toByteData(
|
||||||
|
format: ui.ImageByteFormat.png,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (png != null) {
|
||||||
|
final file = XFile.fromData(
|
||||||
|
png.buffer.asUint8List(),
|
||||||
|
mimeType: 'image/png',
|
||||||
|
);
|
||||||
|
|
||||||
|
await SharePlus.instance.share(
|
||||||
|
ShareParams(files: [file], subject: tabState.title),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
}
|
),
|
||||||
|
MenuItemButton(
|
||||||
|
leadingIcon: const Icon(Icons.share),
|
||||||
|
onPressed: () async {
|
||||||
|
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||||
|
|
||||||
|
await SharePlus.instance.share(ShareParams(uri: tabState.url));
|
||||||
|
},
|
||||||
|
child: const Text('Share Link'),
|
||||||
|
),
|
||||||
|
MenuItemButton(
|
||||||
|
leadingIcon: const Icon(Icons.qr_code),
|
||||||
|
onPressed: () async {
|
||||||
|
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||||
|
|
||||||
|
await showQrCode(context, tabState.url.toString());
|
||||||
|
controller.close();
|
||||||
|
},
|
||||||
|
child: const Text('Show QR Code'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
leadingIcon: const Icon(Icons.share),
|
||||||
|
child: const Text('Share'),
|
||||||
|
),
|
||||||
|
MenuItemButton(
|
||||||
|
leadingIcon: const Icon(MdiIcons.contentCopy),
|
||||||
|
child: const Text('Copy Address'),
|
||||||
|
onPressed: () async {
|
||||||
|
final tabState = ref.read(tabStateProvider(selectedTabId))!;
|
||||||
|
|
||||||
|
await Clipboard.setData(
|
||||||
|
ClipboardData(text: tabState.url.toString()),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Visibility(
|
MenuItemButton(
|
||||||
visible: showFeeds.value,
|
onPressed: () async {
|
||||||
replacement: MenuItemButton(
|
await ref
|
||||||
closeOnActivate: false,
|
.read(tabRepositoryProvider.notifier)
|
||||||
leadingIcon: const Icon(Icons.rss_feed),
|
.closeTab(selectedTabId);
|
||||||
child: const Text('Fetch Feeds'),
|
|
||||||
onPressed: () {
|
if (context.mounted) {
|
||||||
showFeeds.value = true;
|
ui_helper.showTabUndoClose(
|
||||||
},
|
context,
|
||||||
),
|
ref.read(tabRepositoryProvider.notifier).undoClose,
|
||||||
child: WebsiteFeedMenuButton(selectedTabId),
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
leadingIcon: const Icon(Icons.close),
|
||||||
|
child: const Text('Close Tab'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: child,
|
child: child,
|
||||||
|
|||||||
Reference in New Issue
Block a user