feat: add warning to note options menu if note size is >0.5mb (#851)
This commit is contained in:
5
app/assets/icons/ic-warning.svg
Normal file
5
app/assets/icons/ic-warning.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<svg viewBox="0 0 20 20" fill="#fff" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M10.8333 10.8337H9.16663V5.83366H10.8333V10.8337ZM10.8333 14.167H9.16663V12.5003H10.8333V14.167ZM9.99996 1.66699C8.90561 1.66699 7.82198 1.88254 6.81093 2.30133C5.79988 2.72012 4.88122 3.33395 4.1074 4.10777C2.5446 5.67057 1.66663 7.79019 1.66663 10.0003C1.66663 12.2105 2.5446 14.3301 4.1074 15.8929C4.88122 16.6667 5.79988 17.2805 6.81093 17.6993C7.82198 18.1181 8.90561 18.3337 9.99996 18.3337C12.2101 18.3337 14.3297 17.4557 15.8925 15.8929C17.4553 14.3301 18.3333 12.2105 18.3333 10.0003C18.3333 8.90598 18.1177 7.82234 17.699 6.8113C17.2802 5.80025 16.6663 4.88159 15.8925 4.10777C15.1187 3.33395 14.2 2.72012 13.189 2.30133C12.1779 1.88254 11.0943 1.66699 9.99996 1.66699Z"
|
||||||
|
fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 802 B |
@@ -62,6 +62,7 @@ import UnarchiveIcon from '../../icons/ic-unarchive.svg';
|
|||||||
import UnpinIcon from '../../icons/ic-pin-off.svg';
|
import UnpinIcon from '../../icons/ic-pin-off.svg';
|
||||||
import UserIcon from '../../icons/ic-user.svg';
|
import UserIcon from '../../icons/ic-user.svg';
|
||||||
import UserSwitch from '../../icons/ic-user-switch.svg';
|
import UserSwitch from '../../icons/ic-user-switch.svg';
|
||||||
|
import WarningIcon from '../../icons/ic-warning.svg';
|
||||||
import WindowIcon from '../../icons/ic-window.svg';
|
import WindowIcon from '../../icons/ic-window.svg';
|
||||||
|
|
||||||
import { FunctionalComponent } from 'preact';
|
import { FunctionalComponent } from 'preact';
|
||||||
@@ -133,6 +134,7 @@ const ICONS = {
|
|||||||
unarchive: UnarchiveIcon,
|
unarchive: UnarchiveIcon,
|
||||||
unpin: UnpinIcon,
|
unpin: UnpinIcon,
|
||||||
user: UserIcon,
|
user: UserIcon,
|
||||||
|
warning: WarningIcon,
|
||||||
window: WindowIcon,
|
window: WindowIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -672,9 +672,7 @@ export class NoteView extends PureComponent<Props, State> {
|
|||||||
this.application.alertService.alert(STRING_DELETE_LOCKED_ATTEMPT);
|
this.application.alertService.alert(STRING_DELETE_LOCKED_ATTEMPT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const title = this.note.safeTitle().length
|
const title = this.note.title.length ? `'${this.note.title}'` : 'this note';
|
||||||
? `'${this.note.title}'`
|
|
||||||
: 'this note';
|
|
||||||
const text = StringDeleteNote(title, permanently);
|
const text = StringDeleteNote(title, permanently);
|
||||||
if (
|
if (
|
||||||
await confirmDialog({
|
await confirmDialog({
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export const NotesContextMenu = observer(({ application, appState }: Props) => {
|
|||||||
return contextMenuOpen ? (
|
return contextMenuOpen ? (
|
||||||
<div
|
<div
|
||||||
ref={contextMenuRef}
|
ref={contextMenuRef}
|
||||||
className="sn-dropdown min-w-80 max-h-120 max-w-xs flex flex-col py-2 overflow-y-auto fixed"
|
className="sn-dropdown min-w-80 max-h-120 max-w-xs flex flex-col pt-2 overflow-y-auto fixed"
|
||||||
style={{
|
style={{
|
||||||
...contextMenuPosition,
|
...contextMenuPosition,
|
||||||
maxHeight: contextMenuMaxHeight,
|
maxHeight: contextMenuMaxHeight,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { ChangeEditorOption } from './ChangeEditorOption';
|
|||||||
import {
|
import {
|
||||||
MENU_MARGIN_FROM_APP_BORDER,
|
MENU_MARGIN_FROM_APP_BORDER,
|
||||||
MAX_MENU_SIZE_MULTIPLIER,
|
MAX_MENU_SIZE_MULTIPLIER,
|
||||||
|
BYTES_IN_ONE_MEGABYTE,
|
||||||
} from '@/views/constants';
|
} from '@/views/constants';
|
||||||
|
|
||||||
export type NotesOptionsProps = {
|
export type NotesOptionsProps = {
|
||||||
@@ -119,7 +120,7 @@ const NoteAttributes: FunctionComponent<{
|
|||||||
const format = editor?.package_info?.file_type || 'txt';
|
const format = editor?.package_info?.file_type || 'txt';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="px-3 pt-1.5 pb-1 text-xs color-neutral font-medium">
|
<div className="px-3 pt-1.5 pb-2.5 text-xs color-neutral font-medium">
|
||||||
{typeof words === 'number' && (format === 'txt' || format === 'md') ? (
|
{typeof words === 'number' && (format === 'txt' || format === 'md') ? (
|
||||||
<>
|
<>
|
||||||
<div className="mb-1">
|
<div className="mb-1">
|
||||||
@@ -185,6 +186,24 @@ const SpellcheckOptions: FunctionComponent<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const NOTE_SIZE_WARNING_THRESHOLD = 0.5 * BYTES_IN_ONE_MEGABYTE;
|
||||||
|
|
||||||
|
const NoteSizeWarning: FunctionComponent<{
|
||||||
|
note: SNNote;
|
||||||
|
}> = ({ note }) =>
|
||||||
|
new Blob([note.text]).size > NOTE_SIZE_WARNING_THRESHOLD ? (
|
||||||
|
<div className="flex items-center px-3 py-3.5 relative bg-note-size-warning">
|
||||||
|
<Icon
|
||||||
|
type="warning"
|
||||||
|
className="color-accessory-tint-3 flex-shrink-0 mr-3"
|
||||||
|
/>
|
||||||
|
<div className="color-grey-0 select-none">
|
||||||
|
This note may have trouble syncing to the mobile application due to its
|
||||||
|
size.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null;
|
||||||
|
|
||||||
export const NotesOptions = observer(
|
export const NotesOptions = observer(
|
||||||
({
|
({
|
||||||
application,
|
application,
|
||||||
@@ -570,6 +589,7 @@ export const NotesOptions = observer(
|
|||||||
<SpellcheckOptions appState={appState} note={notes[0]} />
|
<SpellcheckOptions appState={appState} note={notes[0]} />
|
||||||
<div className="min-h-1px my-2 bg-border"></div>
|
<div className="min-h-1px my-2 bg-border"></div>
|
||||||
<NoteAttributes application={application} note={notes[0]} />
|
<NoteAttributes application={application} note={notes[0]} />
|
||||||
|
<NoteSizeWarning note={notes[0]} />
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export const NotesOptionsPanel = observer(
|
|||||||
...position,
|
...position,
|
||||||
maxHeight,
|
maxHeight,
|
||||||
}}
|
}}
|
||||||
className="sn-dropdown sn-dropdown--animated min-w-80 max-h-120 max-w-xs flex flex-col py-2 overflow-y-auto fixed"
|
className="sn-dropdown sn-dropdown--animated min-w-80 max-h-120 max-w-xs flex flex-col pt-2 overflow-y-auto fixed"
|
||||||
onBlur={closeOnBlur}
|
onBlur={closeOnBlur}
|
||||||
>
|
>
|
||||||
{open && (
|
{open && (
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ export class NotesState {
|
|||||||
let noteTitle = undefined;
|
let noteTitle = undefined;
|
||||||
if (this.selectedNotesCount === 1) {
|
if (this.selectedNotesCount === 1) {
|
||||||
const selectedNote = Object.values(this.selectedNotes)[0];
|
const selectedNote = Object.values(this.selectedNotes)[0];
|
||||||
noteTitle = selectedNote.safeTitle().length
|
noteTitle = selectedNote.title.length
|
||||||
? `'${selectedNote.title}'`
|
? `'${selectedNote.title}'`
|
||||||
: 'this note';
|
: 'this note';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,3 +9,5 @@ export const MAX_MENU_SIZE_MULTIPLIER = 30;
|
|||||||
|
|
||||||
export const FOCUSABLE_BUT_NOT_TABBABLE = -1;
|
export const FOCUSABLE_BUT_NOT_TABBABLE = -1;
|
||||||
export const NOTES_LIST_SCROLL_THRESHOLD = 200;
|
export const NOTES_LIST_SCROLL_THRESHOLD = 200;
|
||||||
|
|
||||||
|
export const BYTES_IN_ONE_MEGABYTE = 1000000;
|
||||||
|
|||||||
@@ -514,6 +514,11 @@
|
|||||||
padding-bottom: 0.625rem;
|
padding-bottom: 0.625rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.py-3\.5 {
|
||||||
|
padding-top: 0.875rem;
|
||||||
|
padding-bottom: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
.py-9 {
|
.py-9 {
|
||||||
padding-top: 2.25rem;
|
padding-top: 2.25rem;
|
||||||
padding-bottom: 2.25rem;
|
padding-bottom: 2.25rem;
|
||||||
@@ -835,6 +840,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex-shrink-0 {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.dimmed {
|
.dimmed {
|
||||||
opacity: .5;
|
opacity: .5;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
@@ -844,3 +853,7 @@
|
|||||||
.hide-if-last-child:last-child {
|
.hide-if-last-child:last-child {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-note-size-warning {
|
||||||
|
background-color: rgba(235, 173, 0, 0.08);
|
||||||
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
"@reach/tooltip": "^0.16.2",
|
"@reach/tooltip": "^0.16.2",
|
||||||
"@standardnotes/components": "1.5.0",
|
"@standardnotes/components": "1.5.0",
|
||||||
"@standardnotes/features": "1.27.0",
|
"@standardnotes/features": "1.27.0",
|
||||||
"@standardnotes/snjs": "2.51.1",
|
"@standardnotes/snjs": "2.51.2",
|
||||||
"@standardnotes/settings": "^1.11.3",
|
"@standardnotes/settings": "^1.11.3",
|
||||||
"@standardnotes/sncrypto-web": "1.6.2",
|
"@standardnotes/sncrypto-web": "1.6.2",
|
||||||
"mobx": "^6.3.5",
|
"mobx": "^6.3.5",
|
||||||
|
|||||||
@@ -2650,10 +2650,10 @@
|
|||||||
buffer "^6.0.3"
|
buffer "^6.0.3"
|
||||||
libsodium-wrappers "^0.7.9"
|
libsodium-wrappers "^0.7.9"
|
||||||
|
|
||||||
"@standardnotes/snjs@2.51.1":
|
"@standardnotes/snjs@2.51.2":
|
||||||
version "2.51.1"
|
version "2.51.2"
|
||||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.51.1.tgz#404f0a407b0c0eb19ac847081336c1ce9deeee5f"
|
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.51.2.tgz#9804e27071a8d139bf72095d94231a1e29a61593"
|
||||||
integrity sha512-Aeeh++8nEg/FdV4Pxjbm9XmeLNRM57V+mvtVt08U8O+k11XndfjZIDWmPaOfcRBqQtBx47NcvxbXagABz2XSqA==
|
integrity sha512-sxS/QnDnOqUx88Mv8BVR2sd4UAvrBQj0Daa9rH5+INryY5qkLdlTod6MqDfxy+MRkyioVpDAE+yYuBJbcPyqQw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/auth" "^3.15.3"
|
"@standardnotes/auth" "^3.15.3"
|
||||||
"@standardnotes/common" "^1.8.0"
|
"@standardnotes/common" "^1.8.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user