|
74 | 74 | showSnack, |
75 | 75 | transformPages |
76 | 76 | } from '~/utils/ui'; |
77 | | - import { colors, fontScale, hasCamera, isLandscape, onFontScaleChanged, screenHeightDips, screenWidthDips, windowInset } from '~/variables'; |
| 77 | + import { colors, fontScale, fonts, hasCamera, isLandscape, onFontScaleChanged, screenHeightDips, screenWidthDips, windowInset } from '~/variables'; |
78 | 78 | import EditNameActionBar from '~/components/common/EditNameActionBar.svelte'; |
79 | 79 | import IconButton from '~/components/common/IconButton.svelte'; |
80 | 80 | import ListItemAutoSize from '~/components/common/ListItemAutoSize.svelte'; |
|
373 | 373 | function unselectAll() { |
374 | 374 | if (items) { |
375 | 375 | nbSelected = 0; |
376 | | - items.splice(0, items.length, ...items.map((i) => ({ page: i.page, selected: false, index: i.index }))); |
| 376 | + items.splice(0, items.length, ...items.map((i) => ({ ...i, selected: false }))); |
| 377 | + } |
| 378 | + } |
| 379 | + function selectAll() { |
| 380 | + if (items) { |
| 381 | + items.splice(0, items.length, ...items.map((i) => ({ ...i, selected: true }))); |
| 382 | + nbSelected = items.length; |
377 | 383 | } |
378 | 384 | } |
379 | 385 | function toggleSelection(item: Item) { |
|
383 | 389 | selectItem(item); |
384 | 390 | } |
385 | 391 | } |
| 392 | + let inEditMode = false; |
| 393 | + function switchEditMode() { |
| 394 | + inEditMode = !inEditMode; |
| 395 | + collectionView?.nativeElement?.refreshVisibleItems(); |
| 396 | + } |
386 | 397 | let longPressTimer: NodeJS.Timeout; |
387 | 398 | let currentLongPressItem: Item; |
388 | 399 | let dragStarted = false; |
389 | 400 | function onItemLongPress(item: Item, event?) { |
| 401 | + if (inEditMode) { |
| 402 | + startDragging(item, event); |
| 403 | + return; |
| 404 | + } |
| 405 | + if (dragStarted) { |
| 406 | + return; |
| 407 | + } |
390 | 408 | if (nbSelected > 0) { |
391 | 409 | toggleSelection(item); |
392 | 410 | return; |
|
404 | 422 | toggleSelection(item); |
405 | 423 | } |
406 | 424 | currentLongPressItem = null; |
407 | | - }, 400); |
| 425 | + }, 200); |
408 | 426 | } |
409 | 427 | async function onPan(item: Item, event) { |
410 | 428 | if (!currentLongPressItem) { |
|
430 | 448 | currentLongPressItem = null; |
431 | 449 | } |
432 | 450 | } |
| 451 | + async function onTouch(item: Item, event?) { |
| 452 | + if (!inEditMode) { |
| 453 | + return; |
| 454 | + } |
| 455 | + switch (event.action) { |
| 456 | + case 'down': { |
| 457 | + startDragging(item, event); |
| 458 | + break; |
| 459 | + } |
| 460 | + } |
| 461 | + } |
433 | 462 | async function onItemTap(item: Item) { |
434 | 463 | try { |
435 | 464 | if (nbSelected > 0) { |
|
474 | 503 | const onAndroidBackButton = (data: AndroidActivityBackPressedEventData) => |
475 | 504 | onBackButton(page?.nativeView, () => { |
476 | 505 | data.cancel = true; |
477 | | - if (nbSelected > 0) { |
| 506 | + if (inEditMode) { |
| 507 | + switchEditMode(); |
| 508 | + } else if (nbSelected > 0) { |
478 | 509 | unselectAll(); |
479 | 510 | } else { |
480 | 511 | onGoBack(); |
|
762 | 793 | // Filter options based on PKPass document |
763 | 794 | const allOptions = [ |
764 | 795 | { id: 'rename', name: lc('rename'), icon: 'mdi-rename' }, |
| 796 | + { id: 'select_all', name: lc('select_all'), icon: 'mdi-select-all' }, |
| 797 | + { id: 'reorder', name: lc('reorder_pages'), icon: 'mdi-reorder-horizontal' }, |
765 | 798 | { id: 'transform', name: lc('transform_images'), icon: 'mdi-auto-fix' }, |
766 | 799 | { id: 'ocr', name: lc('ocr_document'), icon: 'mdi-text-recognition' }, |
767 | 800 | { id: 'delete', name: lc('delete'), icon: 'mdi-delete', color: colorError } |
|
779 | 812 | case 'rename': |
780 | 813 | editingTitle = true; |
781 | 814 | break; |
| 815 | + case 'select_all': |
| 816 | + selectAll(); |
| 817 | + break; |
782 | 818 | case 'ocr': |
783 | 819 | await detectOCR({ documents: [document] }); |
784 | 820 | unselectAll(); |
|
790 | 826 | case 'delete': |
791 | 827 | await deleteDoc(); |
792 | 828 | break; |
| 829 | + case 'reorder': |
| 830 | + unselectAll(); |
| 831 | + switchEditMode(); |
| 832 | + break; |
793 | 833 | } |
794 | 834 | } |
795 | 835 | }); |
|
1203 | 1243 | backgroundColor={getItemBackgroundColor(item)} |
1204 | 1244 | elevation={isEInk ? 0 : 6} |
1205 | 1245 | longPressGestureOptions={(view, tag, rootTag) => ({ |
1206 | | - simultaneousHandlers: [rootTag, view['PAN_HANDLER_TAG']] |
| 1246 | + simultaneousHandlers: [rootTag, view['PAN_HANDLER_TAG']], |
| 1247 | + minDurationMs: 300 |
1207 | 1248 | })} |
1208 | 1249 | margin={12} |
1209 | 1250 | panGestureOptions={(view, tag, rootTag) => ({ |
| 1251 | + simultaneousHandlers: [rootTag, view['LONGPRESS_HANDLER_TAG']], |
1210 | 1252 | minDist: 20 |
1211 | 1253 | })} |
1212 | 1254 | rippleColor={colorSurface} |
1213 | 1255 | on:tap={() => onItemTap(item)} |
| 1256 | + on:touch={(e) => onTouch(item, e)} |
1214 | 1257 | on:longPress={(e) => onItemLongPress(item, e)} |
1215 | 1258 | on:pan={(e) => onPan(item, e)}> |
1216 | 1259 | <RotableImageView |
|
1235 | 1278 | verticalTextAlignment="center" |
1236 | 1279 | visibility={item.page.imagePath ? 'hidden' : 'visible'} /> |
1237 | 1280 | <SelectedIndicator rowSpan={2} selected={item.selected} /> |
| 1281 | + <label fontFamily={$fonts.mdi} fontSize={24} padding={10} text="mdi-reorder-horizontal" verticalAlignment="bottom" visibility={inEditMode ? 'visible' : 'hidden'} /> |
1238 | 1282 | <PageIndicator horizontalAlignment="right" margin={2} rowSpan={2} scale={$fontScale} text={index + 1} /> |
1239 | 1283 | </gridlayout> |
1240 | 1284 | </Template> |
|
1353 | 1397 | backgroundColor={topBackgroundColor} |
1354 | 1398 | buttonsDefaultVisualState={statusBarStyle} |
1355 | 1399 | colSpan={2} |
1356 | | - forceCanGoBack={nbSelected > 0} |
| 1400 | + forceCanGoBack={inEditMode || nbSelected > 0} |
1357 | 1401 | labelsDefaultVisualState={statusBarStyle} |
1358 | | - onGoBack={nbSelected ? unselectAll : null} |
| 1402 | + onGoBack={nbSelected ? unselectAll : inEditMode ? switchEditMode : null} |
1359 | 1403 | onTitleTap={() => (editingTitle = true)} |
1360 | | - title={nbSelected ? lc('selected', nbSelected) : document.name} |
| 1404 | + title={inEditMode ? lc('reorder_pages') : nbSelected ? lc('selected', nbSelected) : document.name} |
1361 | 1405 | titleProps={{ padding: 0, color: statusBarStyle === 'dark' ? 'white' : 'black' }}> |
1362 | 1406 | <!-- {#if editing} |
1363 | 1407 | <mdbutton class="actionBarButton" defaultVisualState={statusBarStyle} text="mdi-close" variant="text" on:tap={cancelEdit} /> |
|
0 commit comments