improve tab reorder logic
This commit is contained in:
@@ -15,6 +15,7 @@ targets:
|
||||
lexo_rank_next: "text (int, text null)"
|
||||
lexo_rank_previous: "text (int, text null)"
|
||||
lexo_rank_reorder_after: "text (text null, text null)"
|
||||
lexo_rank_reorder_before: "text (text null, text null)"
|
||||
modules:
|
||||
- json1
|
||||
- fts5
|
||||
|
||||
@@ -40,6 +40,19 @@ String _reorderAfter(List<Object?> args) {
|
||||
}
|
||||
}
|
||||
|
||||
String _reorderBefore(List<Object?> args) {
|
||||
final first = args[0].mapNotNull((arg) => LexoRank.parse(arg as String));
|
||||
final last = args[1].mapNotNull((arg) => LexoRank.parse(arg as String));
|
||||
|
||||
if (first == null) {
|
||||
throw Exception('Tab not found');
|
||||
} else if (last == null) {
|
||||
return first.genPrev().value;
|
||||
} else {
|
||||
return last.genBetween(first).value;
|
||||
}
|
||||
}
|
||||
|
||||
void registerLexorankFunctions(CommonDatabase database) {
|
||||
database.createFunction(
|
||||
functionName: 'lexo_rank_next',
|
||||
@@ -56,4 +69,9 @@ void registerLexorankFunctions(CommonDatabase database) {
|
||||
argumentCount: const AllowedArgumentCount(2),
|
||||
function: _reorderAfter,
|
||||
);
|
||||
database.createFunction(
|
||||
functionName: 'lexo_rank_reorder_before',
|
||||
argumentCount: const AllowedArgumentCount(2),
|
||||
function: _reorderBefore,
|
||||
);
|
||||
}
|
||||
|
||||
+21
-10
@@ -300,6 +300,8 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
Expanded(
|
||||
child: HookConsumer(
|
||||
builder: (context, ref, child) {
|
||||
final gridViewKey = useMemoized(() => GlobalKey());
|
||||
|
||||
final container = ref.watch(selectedContainerProvider);
|
||||
|
||||
final filteredTabEntities = ref.watch(
|
||||
@@ -387,10 +389,11 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
child: ReorderableBuilder(
|
||||
child: ReorderableBuilder.builder(
|
||||
//Rebuild when cross axis count changes
|
||||
key: ValueKey(crossAxisCount),
|
||||
scrollController: sheetScrollController,
|
||||
itemCount: tabs.length,
|
||||
onDragStarted: (index) {
|
||||
ref.read(willAcceptDropProvider.notifier).clear();
|
||||
},
|
||||
@@ -423,19 +426,27 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
containerId,
|
||||
);
|
||||
} else {
|
||||
final orderAfterIndex = newIndex;
|
||||
key = await containerRepository.getOrderKeyAfterTab(
|
||||
filteredTabEntities.value[orderAfterIndex].tabId,
|
||||
containerId,
|
||||
);
|
||||
if (newIndex < oldIndex) {
|
||||
key = await containerRepository.getOrderKeyAfterTab(
|
||||
filteredTabEntities.value[newIndex - 1].tabId,
|
||||
containerId,
|
||||
);
|
||||
} else {
|
||||
key = await containerRepository
|
||||
.getOrderKeyBeforeTab(
|
||||
filteredTabEntities.value[newIndex + 1].tabId,
|
||||
containerId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await ref
|
||||
.read(tabDataRepositoryProvider.notifier)
|
||||
.assignOrderKey(tabId, key);
|
||||
},
|
||||
builder: (children) {
|
||||
childBuilder: (itemBuilder) {
|
||||
return GridView.builder(
|
||||
key: gridViewKey,
|
||||
controller: sheetScrollController,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
//Sync values for itemHeight calculation _calculateItemHeight
|
||||
@@ -444,11 +455,11 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
crossAxisSpacing: 8.0,
|
||||
crossAxisCount: crossAxisCount,
|
||||
),
|
||||
itemCount: children.length,
|
||||
itemBuilder: (context, index) => children[index],
|
||||
itemCount: tabs.length,
|
||||
itemBuilder: (context, index) =>
|
||||
itemBuilder(tabs[index], index),
|
||||
);
|
||||
},
|
||||
children: tabs,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -96,4 +96,11 @@ class ContainerDao extends DatabaseAccessor<TabDatabase>
|
||||
) {
|
||||
return db.orderKeyAfterTab(containerId: containerId, tabId: tabId);
|
||||
}
|
||||
|
||||
SingleSelectable<String> generateOrderKeyBeforeTabId(
|
||||
String? containerId,
|
||||
String tabId,
|
||||
) {
|
||||
return db.orderKeyBeforeTab(containerId: containerId, tabId: tabId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,18 @@ orderKeyAfterTab(:tab_id AS TEXT, :container_id AS TEXT OR NULL):
|
||||
FROM ordered_table
|
||||
WHERE id = :tab_id;
|
||||
|
||||
orderKeyBeforeTab(:tab_id AS TEXT, :container_id AS TEXT OR NULL):
|
||||
WITH ordered_table AS (
|
||||
SELECT id,
|
||||
order_key,
|
||||
LAG(order_key) OVER (ORDER BY order_key) AS prev_order_key
|
||||
FROM tab
|
||||
WHERE container_id IS :container_id
|
||||
)
|
||||
SELECT lexo_rank_reorder_before(order_key, prev_order_key)
|
||||
FROM ordered_table
|
||||
WHERE id = :tab_id;
|
||||
|
||||
queryTabsBasic WITH TabQueryResult:
|
||||
WITH weights AS (
|
||||
SELECT
|
||||
|
||||
@@ -1165,6 +1165,17 @@ abstract class _$TabDatabase extends GeneratedDatabase {
|
||||
).map((QueryRow row) => row.read<String>('_c0'));
|
||||
}
|
||||
|
||||
Selectable<String> orderKeyBeforeTab({
|
||||
String? containerId,
|
||||
required String tabId,
|
||||
}) {
|
||||
return customSelect(
|
||||
'WITH ordered_table AS (SELECT id, order_key, LAG(order_key)OVER (ORDER BY order_key RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) AS prev_order_key FROM tab WHERE container_id IS ?1) SELECT lexo_rank_reorder_before(order_key, prev_order_key) AS _c0 FROM ordered_table WHERE id = ?2',
|
||||
variables: [Variable<String>(containerId), Variable<String>(tabId)],
|
||||
readsFrom: {tab},
|
||||
).map((QueryRow row) => row.read<String>('_c0'));
|
||||
}
|
||||
|
||||
Selectable<TabQueryResult> queryTabsBasic({required String query}) {
|
||||
return customSelect(
|
||||
'WITH weights AS (SELECT 10.0 AS title_weight, 5.0 AS url_weight) SELECT t.id, t.title, CAST(t.url AS TEXT) AS url, t.url AS clean_url, bm25(tab_fts, weights.title_weight, weights.url_weight) AS weighted_rank FROM tab_fts AS fts INNER JOIN tab AS t ON t."rowid" = fts."rowid" CROSS JOIN weights WHERE fts.title LIKE ?1 OR fts.url LIKE ?1 ORDER BY weighted_rank ASC, t.timestamp DESC',
|
||||
|
||||
@@ -83,6 +83,14 @@ class ContainerRepository extends _$ContainerRepository {
|
||||
.getSingle();
|
||||
}
|
||||
|
||||
Future<String> getOrderKeyBeforeTab(String tabId, String? containerId) {
|
||||
return ref
|
||||
.read(tabDatabaseProvider)
|
||||
.containerDao
|
||||
.generateOrderKeyBeforeTabId(containerId, tabId)
|
||||
.getSingle();
|
||||
}
|
||||
|
||||
Future<Color> unusedRandomContainerColor() async {
|
||||
final allColors = colorTypes.flattened.toList();
|
||||
final usedColors = await getDistinctColors();
|
||||
|
||||
@@ -7,7 +7,7 @@ part of 'container.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$containerRepositoryHash() =>
|
||||
r'5344ecde33c1c80c1fa2bc8383faca181da91593';
|
||||
r'af4ccf6cc12eebae2313df6c8f9ca63db842ffe5';
|
||||
|
||||
/// See also [ContainerRepository].
|
||||
@ProviderFor(ContainerRepository)
|
||||
|
||||
+4
-1
@@ -24,7 +24,10 @@ dependencies:
|
||||
flutter_material_design_icons: ^1.1.7447
|
||||
flutter_mozilla_components:
|
||||
path: ../packages/flutter_mozilla_components
|
||||
flutter_reorderable_grid_view: ^5.5.0
|
||||
flutter_reorderable_grid_view:
|
||||
git:
|
||||
url: https://github.com/FaFre/flutter-reorderable-grid-view.git
|
||||
ref: fix_builder_assert
|
||||
flutter_secure_storage: ^10.0.0-beta.4
|
||||
flutter_slidable: ^4.0.0
|
||||
flutter_svg: ^2.2.0
|
||||
|
||||
Reference in New Issue
Block a user