Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions app/app.android.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ button[variant='contained'] {
.cardChip {
background-color: var(--colorPrimaryContainer);
border-color: transparent;
border-radius: 10;
border-radius: 11;
border-width: 1;
}

Expand All @@ -40,27 +40,27 @@ textfield[variant='outline'] {
stroke-inactive-color: var(--colorOutline);
}

// the floating buttons are fully round
// the floating buttons: a small tonal add button above the extended Scan button, both with the elevation of floating controls
.addFab {
background-color: var(--colorSecondaryContainer);
border-radius: 12;
color: var(--colorOnSecondaryContainer);
elevation: 2;
elevation: 6;
font-size: 24;
height: 48;
margin: 8;
height: 40;
horizontal-align: right;
margin: 0 16 12 16;
padding: 0;
shape: round;
vertical-align: center;
width: 48;
width: 40;
}

.scanFab {
elevation: 3;
font-size: 16;
font-weight: 600;
border-radius: 18;
elevation: 6;
font-size: 14;
font-weight: 500;
height: 56;
margin: 16;
horizontal-align: right;
margin: 0 16 16 16;
padding: 0 20;
shape: round;
vertical-align: center;
}
6 changes: 3 additions & 3 deletions app/app.common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,11 @@ textfield,
}

.cardChip {
height: 22;
horizontal-align: left;
min-height: 24;
min-width: 24;
min-width: 22;
padding: 0;
vertical-align: middle;
padding: 4 8;
}

.cardsEmptyIcon {
Expand Down
27 changes: 21 additions & 6 deletions app/components/common/CardChip.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,37 @@
import CardIcon from '~/components/common/CardIcon.svelte';
import { colors } from '~/variables';

interface ChipSegment {
icon?: string;
text?: string;
}

export let text: string = null;
export let icon: string = null;
/** several segments are one pill with a hairline between them */
export let segments: ChipSegment[] = null;
export let fontWeight: any = '600';
let { colorOnPrimaryContainer, colorOnSurface } = $colors;
$: ({ colorOnPrimaryContainer, colorOnSurface } = $colors);
$: color = __IOS__ ? colorOnSurface : colorOnPrimaryContainer;
$: parts = segments ?? [{ icon, text }];
</script>

<!-- glass on iOS, tonal on Android (see the cardChip class): legible on any image -->
<uisurface class="cardChip" android:variant="clear" {...$$restProps}>
<stacklayout orientation="horizontal">
{#if icon}
<CardIcon {color} marginRight={text ? 2 : 0} size={12} src={icon} verticalAlignment="center" />
{/if}
{#if text}
<label {color} fontSize={12} {fontWeight} lineBreak="end" maxLines={1} {text} verticalAlignment="center" />
{/if}
{#each parts as part, index}
{#if index > 0}
<absolutelayout backgroundColor={color} height={12} opacity={0.25} verticalAlignment="center" width={1} />
{/if}
<stacklayout minWidth={22} orientation="horizontal" padding={part.text ? '0 8' : 0}>
{#if part.icon}
<CardIcon {color} horizontalAlignment="center" marginRight={part.text ? 4 : 0} size={12} src={part.icon} verticalAlignment="center" />
{/if}
{#if part.text}
<label {color} fontSize={11} {fontWeight} lineBreak="end" maxLines={1} text={part.text} verticalAlignment="center" />
{/if}
</stacklayout>
{/each}
</stacklayout>
</uisurface>
43 changes: 25 additions & 18 deletions app/components/list/CardListCell.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
</script>

<script lang="ts">
let { colorBackground, colorOnSurface, colorOnSurfaceVariant, colorPrimary, colorSurfaceContainerLow } = $colors;
$: ({ colorBackground, colorOnSurface, colorOnSurfaceVariant, colorPrimary, colorSurfaceContainerLow } = $colors);
let { colorBackground, colorOnSurface, colorOnSurfaceVariant, colorPrimary, colorSecondaryContainer, colorSurfaceContainerLow } = $colors;
$: ({ colorBackground, colorOnSurface, colorOnSurfaceVariant, colorPrimary, colorSecondaryContainer, colorSurfaceContainerLow } = $colors);

export let collectionView: NativeViewElementNode<CollectionViewWithSwipeMenu>;
export let itemWidth: number;
Expand Down Expand Up @@ -125,18 +125,23 @@
// the default name is a timestamp: a tile only shows its date
$: autoName = !item.doc.name || /\d+:\d+:\d+/.test(item.doc.name);
$: label = autoName ? dayjs(item.doc.createdDate).format('ll') : item.doc.name;
$: infoSegments = [
...(item.doc.pages.length > 1 ? [{ icon: appIcon('pages'), text: item.doc.pages.length + '' }] : []),
...(hasCode ? [{ icon: appIcon('qrcode') }] : []),
...(item.doc.favorite === 1 ? [{ icon: appIcon('favorite_on') }] : [])
];
$: showLabel = !hasImage || !autoName || alwaysShowNames;
$: cardColor = isEInk ? null : pickCardColor(item.doc.extra?.color, [page?.extra?.color, ...(page?.colors ?? [])]);
$: tile = getTileColors(cardColor, colorPrimary);
$: subtitle = pkPassCell ? lc('wallet_pass') : hasImage ? lcp('photos_count', item.doc.pages.length) : hasCode ? '' : lc('details_only');
$: subtitle = pkPassCell ? lc('wallet_pass') : hasImage ? lcp('photos_count', item.doc.pages.length) : '';

function getItemHolderParams(layout, item: Item, nbColumns, tileFill: string, selected: boolean) {
const imagePage = item.doc.pages[0];
const result = {
backgroundColor: isEInk ? null : imagePage?.imagePath ? new Color(imagePage.extra?.color ?? imagePage.colors?.[1] ?? colorBackground) : new Color(tileFill),
borderRadius: tileRadius,
scaleX: selected ? 0.95 : 1,
scaleY: selected ? 0.95 : 1
scaleX: selected && layout === 'columns' ? 0.95 : 1,
scaleY: selected && layout === 'columns' ? 0.95 : 1
};
switch (layout) {
case 'cardholder':
Expand Down Expand Up @@ -221,7 +226,7 @@
<gridlayout {height} width="100%" {...$$restProps}>
{#if layout === 'list'}
<gridlayout
backgroundColor={isEInk ? 'transparent' : colorSurfaceContainerLow}
backgroundColor={isEInk ? 'transparent' : item.selected ? colorSecondaryContainer : colorSurfaceContainerLow}
borderRadius={__IOS__ ? 14 : 6}
columns="auto,*,auto,auto,auto"
margin="1 16"
Expand All @@ -232,24 +237,24 @@
>
<gridlayout
backgroundColor={pkPassCell ? (page?.pkpass?.passData?.backgroundColor ?? tile.fill) : hasImage ? null : tile.fill}
borderRadius={10}
height={56}
borderRadius={11}
height={60}
verticalAlignment="center"
width={88}
width={96}
>
{#if hasImage}
<RotableImageView {...getItemRotableImageParams(item)} borderRadius={10} decodeWidth={Utils.layout.toDevicePixels(88)} />
<RotableImageView {...getItemRotableImageParams(item)} borderRadius={11} decodeWidth={Utils.layout.toDevicePixels(96)} />
{:else if !pkPassCell}
<label color={tile.text} fontSize={12} fontWeight="bold" lineBreak="end" margin="4 6" maxLines={3} text={label} textAlignment="center" verticalAlignment="center" />
{/if}
</gridlayout>
<label col={1} color={colorOnSurface} lineBreak="end" margin="0 12" textWrap={true} verticalAlignment="center">
<span fontSize={17} fontWeight="600" text={item.doc.name || label} />
<span color={colorOnSurfaceVariant} fontSize={13} text={subtitle ? '\n' + subtitle : ''} />
<span fontSize={__IOS__ ? 17 : 16} fontWeight={__IOS__ ? '600' : '500'} text={item.doc.name || label} />
<span color={colorOnSurfaceVariant} fontSize={14} text={subtitle ? '\n' + subtitle : ''} />
</label>
<CardIcon col={2} color={colorOnSurfaceVariant} marginRight={8} size={16} src={appIcon('qrcode')} verticalAlignment="center" visibility={hasCode ? 'visible' : 'collapsed'} />
<CardIcon col={3} color={colorPrimary} marginRight={8} size={16} src={appIcon('favorite_on')} verticalAlignment="center" visibility={item.doc.favorite === 1 ? 'visible' : 'collapsed'} />
<CardIcon col={4} color={colorOnSurfaceVariant} size={16} src={appIcon('chevron')} verticalAlignment="center" visibility={$selectionMode ? 'collapsed' : 'visible'} />
<CardIcon col={4} color={colorOnSurfaceVariant} size={16} src={appIcon('chevron')} verticalAlignment="center" visibility={$selectionMode || __ANDROID__ ? 'collapsed' : 'visible'} />
<SelectedIndicator margin="12 0 0 12" selected={item.selected} />
</gridlayout>
{:else}
Expand All @@ -268,10 +273,9 @@
verticalAlignment={stacked ? 'top' : 'bottom'}
/>
{/if}
<stacklayout horizontalAlignment="right" margin={8} marginRight={stacked && item.doc.favorite === 1 ? 38 : 8} orientation="horizontal" verticalAlignment={stacked ? 'top' : 'bottom'}>
<CardChip icon={appIcon('pages')} marginRight={hasCode ? 4 : 0} text={item.doc.pages.length + ''} visibility={item.doc.pages.length > 1 ? 'visible' : 'collapsed'} />
<CardChip icon={appIcon('qrcode')} visibility={hasCode ? 'visible' : 'collapsed'} />
</stacklayout>
{#if infoSegments.length}
<CardChip horizontalAlignment="right" margin={8} segments={infoSegments} verticalAlignment="top" />
{/if}
{:else}
<label
color={tile.text}
Expand All @@ -291,16 +295,19 @@
color={tile.text}
horizontalAlignment="right"
margin={10}
marginRight={stacked && item.doc.favorite === 1 ? 40 : 10}
opacity={0.75}
size={18}
src={appIcon('qrcode')}
verticalAlignment={stacked ? 'top' : 'bottom'}
visibility={hasCode ? 'visible' : 'collapsed'}
/>
{#if item.doc.favorite === 1}
<CardChip horizontalAlignment="right" icon={appIcon('favorite_on')} margin={8} verticalAlignment="top" />
{/if}
{/if}
<SelectedIndicator selected={item.selected} />
<SyncIndicator {syncColors} verticalAlignment="top" visible={syncEnabled} />
<CardChip horizontalAlignment="right" icon={appIcon('favorite_on')} margin={8} verticalAlignment="top" visibility={item.doc.favorite === 1 ? 'visible' : 'collapsed'} />
</gridlayout>
<!-- <uibutton prop:rightDrawer class="mdi" fontSize={40} height={60} text="mdi-fullscreen" variant="text" verticalAlignment="center" width={60} on:tap={() => showImages(item)} />
</swipemenu> -->
Expand Down
4 changes: 2 additions & 2 deletions app/components/list/CardsList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@
case 'cardholder':
return itemHeight * (isLandscape ? 0.6 : 0.4);
case 'list':
return isLandscape ? itemHeight : 72;
return isLandscape ? itemHeight : 74;
default:
return itemHeight;
}
Expand Down Expand Up @@ -472,7 +472,7 @@
/>
</Template>

<stacklayout bind:this={fabHolder} slot="fab" class="fabHolder" marginBottom={Math.min(60, $windowInset.bottom)} orientation="horizontal">
<stacklayout bind:this={fabHolder} slot="fab" class="fabHolder" marginBottom={Math.min(60, $windowInset.bottom)}>
<uibutton class="addFab" {...{ src: appIcon('add') }} variant="contained" verticalAlignment="center" on:tap={throttle(() => onAddButton(), 500)} />
{#if $hasCamera}
<!-- the button puts no space between its icon and its text -->
Expand Down
14 changes: 7 additions & 7 deletions app/components/list/FolderCell.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
const iconSize = 32;
import { lcp } from '@nativescript-community/l';
import { Color } from '@nativescript/core';
import CardIcon from '~/components/common/CardIcon.svelte';
Expand All @@ -17,9 +18,8 @@
$: ({ colorOnSurface, colorOnSurfaceVariant, colorOutlineVariant, colorPrimary, colorSurfaceContainerLow } = $colors);

$: iconColor = item.folder.color || colorPrimary;
// the folder icon sits in a circle of its color at 20% over the tile
$: iconBackground = Color.mix(new Color(colorSurfaceContainerLow), new Color(iconColor), 20);
$: iconSize = tile ? 32 : 30;
// the folder icon sits in a circle of its color at 16% over the tile
$: iconBackground = Color.mix(new Color(colorSurfaceContainerLow), new Color(iconColor), 16);
</script>

<gridlayout
Expand All @@ -28,23 +28,23 @@
borderRadius={tile ? (__IOS__ ? 16 : 20) : 14}
borderWidth={isEInk ? 1 : 0}
columns={tile ? 'auto,*' : 'auto,*,auto,auto'}
height={tile ? 54 : 46}
height={tile ? 54 : 52}
padding={tile ? '0 10' : '0 14'}
rippleColor={colorOnSurface}
{...$$restProps}
on:tap
on:longPress
>
<gridlayout backgroundColor={iconBackground.hex} borderRadius={iconSize / 2} height={iconSize} verticalAlignment="center" width={iconSize}>
<CardIcon color={iconColor} horizontalAlignment="center" size={tile ? 18 : 17} src={appIcon('folder_outline')} verticalAlignment="center" />
<CardIcon color={iconColor} horizontalAlignment="center" size={20} src={appIcon('folder_outline')} verticalAlignment="center" />
</gridlayout>
<label col={1} color={colorOnSurface} lineBreak="end" marginLeft={tile ? 8 : 10} maxLines={tile ? 2 : 1} verticalAlignment="center">
<span fontSize={tile ? 13 : 14} fontWeight="600" text={name} />
<span fontSize={tile ? 13 : 16} fontWeight={tile ? '600' : '500'} text={name} />
<span color={colorOnSurfaceVariant} fontSize={11} text={tile ? '\n' + lcp('documents_count', item.folder.count) : ''} />
</label>
{#if !tile}
<label col={2} color={colorOnSurfaceVariant} fontSize={12} text={item.folder.count + ''} verticalAlignment="center" />
<CardIcon col={3} color={colorOnSurfaceVariant} marginLeft={6} size={16} src={appIcon('chevron')} verticalAlignment="center" visibility={$selectionMode ? 'collapsed' : 'visible'} />
<CardIcon col={3} color={colorOnSurfaceVariant} marginLeft={6} size={16} src={appIcon('chevron')} verticalAlignment="center" visibility={$selectionMode || __ANDROID__ ? 'collapsed' : 'visible'} />
{/if}
<SelectedIndicator horizontalAlignment="right" margin={tile ? 2 : 0} selected={item.selected} verticalAlignment="top" />
</gridlayout>
40 changes: 33 additions & 7 deletions app/components/list/MainList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -1357,19 +1357,37 @@
$: primaryAction = actions.find((action) => action.primary);
$: secondaryActions = actions.filter((action) => !action.primary);
$: plusMenu = secondaryActions.map((action) => ({ title: action.text, icon: appIcon(action.icon), onSelect: action.onTap }));
// the main actions of the selection, in order: the rest goes to the more menu
function getSelectionActionIds() {
if (isTrash) {
return ['select_all', 'restore', 'delete_permanently'];
}
return CARD_APP ? (__IOS__ ? ['share', 'favorite', 'move_folder', 'delete'] : ['favorite', 'move_folder', 'delete']) : ['pdf', 'share', 'delete'];
}
function splitSelectionOptions(options: OptionType[]) {
const toolbarIds = getSelectionActionIds();
return {
main: toolbarIds.map((id) => options.find((option) => option.id === id)).filter(Boolean),
more: options.filter((option) => !toolbarIds.includes(option.id))
};
}
const onSelectionAction = (option: OptionType) => handleSelectionAction({ object: collectionView?.nativeView }, option);
// Android: the actions are in the top bar while selecting, iOS: in the bottom toolbar
$: selectionOptions = nbSelected > 0 ? splitSelectionOptions(getSelectionToolbarOptions()) : { main: [], more: [] };
$: selectionMoreMenu = optionsToMenuItems(selectionOptions.more, onSelectionAction);
function getSelectionBottomItems(options: OptionType[]) {
const toolbarIds = isTrash ? options.map((option) => option.id) : ['pdf', 'share', 'delete'];
const toolbarOptions = options.filter((option) => toolbarIds.includes(option.id));
const menuOptions = options.filter((option) => !toolbarIds.includes(option.id));
const onAction = (option: OptionType) => handleSelectionAction({ object: collectionView?.nativeView }, option);
const items: any[] = toolbarOptions.flatMap((option) => [{ spacer: true }, { text: option.name, icon: appIcon(option.id), onTap: () => onAction(option) }]);
if (menuOptions.length) {
if (__ANDROID__) {
return [];
}
const { main, more } = splitSelectionOptions(options);
const items: any[] = main.flatMap((option) => [{ spacer: true }, { text: option.name, icon: appIcon(option.id), onTap: () => onSelectionAction(option) }]);
if (more.length) {
items.push(
{ spacer: true },
{
text: lc('more_options'),
icon: appIcon('more'),
menu: optionsToMenuItems(menuOptions, onAction)
menu: optionsToMenuItems(more, onSelectionAction)
}
);
}
Expand Down Expand Up @@ -1427,6 +1445,7 @@
<appPage bind:this={page} id="documentList" on:navigatedTo={onNavigatedTo} on:navigatingFrom={onNavigatingFrom}>
<appBar
bind:this={appBar}
android:backgroundColor={nbSelected > 0 ? colorPrimaryContainer : undefined}
scrollBehavior="lift"
searchable={!isTrash && !onlyForImport && nbSelected === 0}
scrollTargetId="documentsCollectionView"
Expand Down Expand Up @@ -1476,6 +1495,13 @@
{/if}
{:else if __IOS__}
<appBarItem ios.position="right" prominent={true} text={lc('cancel')} on:tap={unselectAll} />
{:else}
{#each selectionOptions.main as option (option.id)}
<appBarItem icon={appIcon(option.id)} text={option.name} on:tap={() => onSelectionAction(option)} />
{/each}
{#if selectionMoreMenu.length}
<appBarItem icon={appIcon('more')} menu={selectionMoreMenu} />
{/if}
{/if}
</appBar>
<gridlayout class="pageContent" rows="auto,auto,*">
Expand Down
Loading