feat: sort files by name (#1001)

This commit is contained in:
Aman Harwara
2022-04-28 00:49:27 +05:30
committed by GitHub
parent 96be0d578d
commit 99d83af3ba
11 changed files with 52 additions and 108 deletions

View File

@@ -8,7 +8,7 @@ import { FunctionComponent } from 'preact'
import { useCallback, useEffect, useRef, useState } from 'preact/hooks' import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
import { Icon } from '@/Components/Icon' import { Icon } from '@/Components/Icon'
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
import { ChallengeReason, ContentType, SNFile } from '@standardnotes/snjs' import { ChallengeReason, CollectionSort, ContentType, SNFile } from '@standardnotes/snjs'
import { confirmDialog } from '@/Services/AlertService' import { confirmDialog } from '@/Services/AlertService'
import { addToast, dismissToast, ToastType } from '@standardnotes/stylekit' import { addToast, dismissToast, ToastType } from '@standardnotes/stylekit'
import { StreamingFileReader } from '@standardnotes/filepicker' import { StreamingFileReader } from '@standardnotes/filepicker'
@@ -39,8 +39,7 @@ const removeDragOverlay = () => {
} }
const isHandlingFileDrag = (event: DragEvent) => const isHandlingFileDrag = (event: DragEvent) =>
event.dataTransfer?.items && event.dataTransfer?.items && Array.from(event.dataTransfer.items).some((item) => item.kind === 'file')
Array.from(event.dataTransfer.items).some((item) => item.kind === 'file')
export const AttachedFilesButton: FunctionComponent<Props> = observer( export const AttachedFilesButton: FunctionComponent<Props> = observer(
({ application, appState, onClickPreprocessing }) => { ({ application, appState, onClickPreprocessing }) => {
@@ -66,17 +65,11 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
const attachedFilesCount = attachedFiles.length const attachedFilesCount = attachedFiles.length
useEffect(() => { useEffect(() => {
application.items.setDisplayOptions(ContentType.File, CollectionSort.Title, 'dsc')
const unregisterFileStream = application.streamItems(ContentType.File, () => { const unregisterFileStream = application.streamItems(ContentType.File, () => {
setAllFiles( setAllFiles(application.items.getDisplayableItems<SNFile>(ContentType.File))
application.items setAttachedFiles(application.items.getFilesForNote(note))
.getItems<SNFile>(ContentType.File)
.sort((a, b) => (a.created_at < b.created_at ? 1 : -1)),
)
setAttachedFiles(
application.items
.getFilesForNote(note)
.sort((a, b) => (a.created_at < b.created_at ? 1 : -1)),
)
}) })
return () => { return () => {
@@ -162,14 +155,8 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
return isProtected return isProtected
} }
const authorizeProtectedActionForFile = async ( const authorizeProtectedActionForFile = async (file: SNFile, challengeReason: ChallengeReason) => {
file: SNFile, const authorizedFiles = await application.protections.authorizeProtectedActionForFiles([file], challengeReason)
challengeReason: ChallengeReason,
) => {
const authorizedFiles = await application.protections.authorizeProtectedActionForFiles(
[file],
challengeReason,
)
const isAuthorized = authorizedFiles.length > 0 && authorizedFiles.includes(file) const isAuthorized = authorizedFiles.length > 0 && authorizedFiles.includes(file)
return isAuthorized return isAuthorized
} }
@@ -179,16 +166,12 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
} }
const handleFileAction = async (action: PopoverFileItemAction) => { const handleFileAction = async (action: PopoverFileItemAction) => {
const file = const file = action.type !== PopoverFileItemActionType.RenameFile ? action.payload : action.payload.file
action.type !== PopoverFileItemActionType.RenameFile ? action.payload : action.payload.file
let isAuthorizedForAction = true let isAuthorizedForAction = true
if (file.protected && action.type !== PopoverFileItemActionType.ToggleFileProtection) { if (file.protected && action.type !== PopoverFileItemActionType.ToggleFileProtection) {
keepMenuOpen(true) keepMenuOpen(true)
isAuthorizedForAction = await authorizeProtectedActionForFile( isAuthorizedForAction = await authorizeProtectedActionForFile(file, ChallengeReason.AccessProtectedFile)
file,
ChallengeReason.AccessProtectedFile,
)
keepMenuOpen(false) keepMenuOpen(false)
buttonRef.current?.focus() buttonRef.current?.focus()
} }
@@ -219,10 +202,7 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
await renameFile(file, action.payload.name) await renameFile(file, action.payload.name)
break break
case PopoverFileItemActionType.PreviewFile: case PopoverFileItemActionType.PreviewFile:
filePreviewModal.activate( filePreviewModal.activate(file, currentTab === PopoverTabs.AllFiles ? allFiles : attachedFiles)
file,
currentTab === PopoverTabs.AllFiles ? allFiles : attachedFiles,
)
break break
} }
@@ -353,9 +333,7 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
} }
}} }}
ref={buttonRef} ref={buttonRef}
className={`sn-icon-button border-contrast ${ className={`sn-icon-button border-contrast ${attachedFilesCount > 0 ? 'py-1 px-3' : ''}`}
attachedFilesCount > 0 ? 'py-1 px-3' : ''
}`}
onBlur={closeOnBlur} onBlur={closeOnBlur}
> >
<VisuallyHidden>Attached files</VisuallyHidden> <VisuallyHidden>Attached files</VisuallyHidden>

View File

@@ -47,9 +47,7 @@ export const AttachedFilesPopover: FunctionComponent<Props> = observer(
const filteredList = const filteredList =
searchQuery.length > 0 searchQuery.length > 0
? filesList.filter( ? filesList.filter((file) => file.name.toLowerCase().indexOf(searchQuery.toLowerCase()) !== -1)
(file) => file.name.toLowerCase().indexOf(searchQuery.toLowerCase()) !== -1,
)
: filesList : filesList
const handleAttachFilesClick = async () => { const handleAttachFilesClick = async () => {
@@ -78,9 +76,7 @@ export const AttachedFilesPopover: FunctionComponent<Props> = observer(
<div className="flex border-0 border-b-1 border-solid border-main"> <div className="flex border-0 border-b-1 border-solid border-main">
<button <button
className={`bg-default border-0 cursor-pointer px-3 py-2.5 relative focus:bg-info-backdrop focus:shadow-bottom ${ className={`bg-default border-0 cursor-pointer px-3 py-2.5 relative focus:bg-info-backdrop focus:shadow-bottom ${
currentTab === PopoverTabs.AttachedFiles currentTab === PopoverTabs.AttachedFiles ? 'color-info font-medium shadow-bottom' : 'color-text'
? 'color-info font-medium shadow-bottom'
: 'color-text'
}`} }`}
onClick={() => { onClick={() => {
setCurrentTab(PopoverTabs.AttachedFiles) setCurrentTab(PopoverTabs.AttachedFiles)
@@ -91,9 +87,7 @@ export const AttachedFilesPopover: FunctionComponent<Props> = observer(
</button> </button>
<button <button
className={`bg-default border-0 cursor-pointer px-3 py-2.5 relative focus:bg-info-backdrop focus:shadow-bottom ${ className={`bg-default border-0 cursor-pointer px-3 py-2.5 relative focus:bg-info-backdrop focus:shadow-bottom ${
currentTab === PopoverTabs.AllFiles currentTab === PopoverTabs.AllFiles ? 'color-info font-medium shadow-bottom' : 'color-text'
? 'color-info font-medium shadow-bottom'
: 'color-text'
}`} }`}
onClick={() => { onClick={() => {
setCurrentTab(PopoverTabs.AllFiles) setCurrentTab(PopoverTabs.AllFiles)

View File

@@ -22,12 +22,7 @@ type Props = {
onDismiss: () => void onDismiss: () => void
} }
export const FilePreviewModal: FunctionComponent<Props> = ({ export const FilePreviewModal: FunctionComponent<Props> = ({ application, files, file, onDismiss }) => {
application,
files,
file,
onDismiss,
}) => {
const context = useFilePreviewModal() const context = useFilePreviewModal()
const [objectUrl, setObjectUrl] = useState<string>() const [objectUrl, setObjectUrl] = useState<string>()
@@ -94,8 +89,7 @@ export const FilePreviewModal: FunctionComponent<Props> = ({
switch (event.key) { switch (event.key) {
case KeyboardKey.Left: { case KeyboardKey.Left: {
const previousFileIndex = const previousFileIndex = currentFileIndex - 1 >= 0 ? currentFileIndex - 1 : files.length - 1
currentFileIndex - 1 >= 0 ? currentFileIndex - 1 : files.length - 1
const previousFile = files[previousFileIndex] const previousFile = files[previousFileIndex]
if (previousFile) { if (previousFile) {
context.setCurrentFile(previousFile) context.setCurrentFile(previousFile)
@@ -184,8 +178,8 @@ export const FilePreviewModal: FunctionComponent<Props> = ({
{isFilePreviewable ? ( {isFilePreviewable ? (
<> <>
<div className="text-sm text-center color-grey-0 mb-4 max-w-35ch"> <div className="text-sm text-center color-grey-0 mb-4 max-w-35ch">
There was an error loading the file. Try again, or download the file and open There was an error loading the file. Try again, or download the file and open it using another
it using another application. application.
</div> </div>
<div className="flex items-center"> <div className="flex items-center">
<Button <Button

View File

@@ -44,12 +44,7 @@ export const FilePreviewModalProvider: FunctionComponent<{
<> <>
<FilePreviewModalContext.Provider value={{ activate, setCurrentFile }}> <FilePreviewModalContext.Provider value={{ activate, setCurrentFile }}>
{isOpen && currentFile && ( {isOpen && currentFile && (
<FilePreviewModal <FilePreviewModal application={application} files={files} file={currentFile} onDismiss={close} />
application={application}
files={files}
file={currentFile}
onDismiss={close}
/>
)} )}
{children} {children}
</FilePreviewModalContext.Provider> </FilePreviewModalContext.Provider>

View File

@@ -25,9 +25,7 @@ export const AccountPreferences = observer(({ application, appState }: Props) =>
</> </>
)} )}
<Subscription application={application} appState={appState} /> <Subscription application={application} appState={appState} />
{application.hasAccount() && appState.features.isEntitledToFiles && ( {application.hasAccount() && appState.features.isEntitledToFiles && <FilesSection application={application} />}
<FilesSection application={application} />
)}
<SignOutWrapper application={application} appState={appState} /> <SignOutWrapper application={application} appState={appState} />
</PreferencesPane> </PreferencesPane>
)) ))

View File

@@ -6,8 +6,6 @@ export function isDesktopDevice(x: DeviceInterface): x is DesktopDeviceInterface
return x.environment === Environment.Desktop return x.environment === Environment.Desktop
} }
export interface DesktopDeviceInterface export interface DesktopDeviceInterface extends WebOrDesktopDeviceInterface, WebClientRequiresDesktopMethods {
extends WebOrDesktopDeviceInterface,
WebClientRequiresDesktopMethods {
environment: Environment.Desktop environment: Environment.Desktop
} }

View File

@@ -32,10 +32,7 @@ export interface DesktopClientRequiresWebMethods {
windowLostFocus(): void windowLostFocus(): void
onComponentInstallationComplete( onComponentInstallationComplete(componentData: DecryptedTransferPayload, error: unknown): Promise<void>
componentData: DecryptedTransferPayload,
error: unknown,
): Promise<void>
requestBackupFile(): Promise<string | undefined> requestBackupFile(): Promise<string | undefined>

View File

@@ -113,10 +113,7 @@ export class DesktopManager
this.webApplication.notifyWebEvent(WebAppEvent.DesktopWindowLostFocus) this.webApplication.notifyWebEvent(WebAppEvent.DesktopWindowLostFocus)
} }
async onComponentInstallationComplete( async onComponentInstallationComplete(componentData: DecryptedTransferPayload<ComponentContent>, error: unknown) {
componentData: DecryptedTransferPayload<ComponentContent>,
error: unknown,
) {
const component = this.application.items.findItem(componentData.uuid) const component = this.application.items.findItem(componentData.uuid)
if (!component) { if (!component) {
return return

View File

@@ -129,14 +129,10 @@ export class IOService {
// For a modifier like ctrlKey, must check both event.ctrlKey and event.key. // For a modifier like ctrlKey, must check both event.ctrlKey and event.key.
// That's because on keyup, event.ctrlKey would be false, but event.key == Control would be true. // That's because on keyup, event.ctrlKey would be false, but event.key == Control would be true.
const matches = const matches =
((event.ctrlKey || event.key === KeyboardModifier.Ctrl) && ((event.ctrlKey || event.key === KeyboardModifier.Ctrl) && modifier === KeyboardModifier.Ctrl) ||
modifier === KeyboardModifier.Ctrl) || ((event.metaKey || event.key === KeyboardModifier.Meta) && modifier === KeyboardModifier.Meta) ||
((event.metaKey || event.key === KeyboardModifier.Meta) && ((event.altKey || event.key === KeyboardModifier.Alt) && modifier === KeyboardModifier.Alt) ||
modifier === KeyboardModifier.Meta) || ((event.shiftKey || event.key === KeyboardModifier.Shift) && modifier === KeyboardModifier.Shift)
((event.altKey || event.key === KeyboardModifier.Alt) &&
modifier === KeyboardModifier.Alt) ||
((event.shiftKey || event.key === KeyboardModifier.Shift) &&
modifier === KeyboardModifier.Shift)
return matches return matches
}) })
@@ -190,10 +186,7 @@ export class IOService {
continue continue
} }
if ( if (observer.key && this.eventMatchesKeyAndModifiers(event, observer.key, observer.modifiers)) {
observer.key &&
this.eventMatchesKeyAndModifiers(event, observer.key, observer.modifiers)
) {
const callback = keyEvent === KeyboardKeyEvent.Down ? observer.onKeyDown : observer.onKeyUp const callback = keyEvent === KeyboardKeyEvent.Down ? observer.onKeyDown : observer.onKeyUp
if (callback) { if (callback) {
callback(event) callback(event)

View File

@@ -72,7 +72,7 @@
"@standardnotes/components": "1.7.15", "@standardnotes/components": "1.7.15",
"@standardnotes/filepicker": "1.13.3", "@standardnotes/filepicker": "1.13.3",
"@standardnotes/sncrypto-web": "1.8.4", "@standardnotes/sncrypto-web": "1.8.4",
"@standardnotes/snjs": "2.102.0", "@standardnotes/snjs": "2.103.0",
"@standardnotes/stylekit": "5.23.0", "@standardnotes/stylekit": "5.23.0",
"@zip.js/zip.js": "^2.4.10", "@zip.js/zip.js": "^2.4.10",
"mobx": "^6.5.0", "mobx": "^6.5.0",

View File

@@ -2458,14 +2458,14 @@
"@standardnotes/auth" "^3.18.11" "@standardnotes/auth" "^3.18.11"
"@standardnotes/features" "^1.38.1" "@standardnotes/features" "^1.38.1"
"@standardnotes/encryption@^1.4.12": "@standardnotes/encryption@^1.4.13":
version "1.4.12" version "1.4.13"
resolved "https://registry.yarnpkg.com/@standardnotes/encryption/-/encryption-1.4.12.tgz#098c9320a7b19aba44e0c7baa1fcd243120c2fef" resolved "https://registry.yarnpkg.com/@standardnotes/encryption/-/encryption-1.4.13.tgz#056880bd82f2dcb5ca6bb2e38650b1f6004db35c"
integrity sha512-DTW/CAlDDOimXwE8XN+V2R3sPXXQYzYnWZHs6WCD3NaLN41MAoG1j8cVuTKHHMP0hhaS2/refOllgt8Kf97mKQ== integrity sha512-0AXjs15UKKjTEIyZTzTqny5yd/5lVGxZOtxAkO8/z8Qx1lK/J3KTUlWz2h0JBsRyA4PaTyLSNVKoF51mE8Bd1w==
dependencies: dependencies:
"@standardnotes/models" "^1.5.1" "@standardnotes/models" "^1.6.0"
"@standardnotes/responses" "^1.6.12" "@standardnotes/responses" "^1.6.12"
"@standardnotes/services" "^1.9.13" "@standardnotes/services" "^1.9.14"
"@standardnotes/features@^1.38.1": "@standardnotes/features@^1.38.1":
version "1.38.1" version "1.38.1"
@@ -2483,10 +2483,10 @@
"@standardnotes/common" "^1.19.6" "@standardnotes/common" "^1.19.6"
"@standardnotes/utils" "^1.6.2" "@standardnotes/utils" "^1.6.2"
"@standardnotes/models@^1.5.1": "@standardnotes/models@^1.6.0":
version "1.5.1" version "1.6.0"
resolved "https://registry.yarnpkg.com/@standardnotes/models/-/models-1.5.1.tgz#a522c715c74c63e58fc4182e69baad46548dbfba" resolved "https://registry.yarnpkg.com/@standardnotes/models/-/models-1.6.0.tgz#63cab950b2e533bbe3feab1fad8deddc51c66ae9"
integrity sha512-dOVnT5HCAjU3i4KqTeu05h5d+LDp8nteam6xb9V75XbA/UT9TMC3zwE+yEYpvWC4iKSbdPQvIuuvp8hXFyOnbA== integrity sha512-tO7YpRQXHsJkF06BNxOwI89Rhk5G3thkcfv6/dKaxG274F91XYBzoFGaRvs3EczEKDfqkOyb1H7wM02T8LXIvw==
dependencies: dependencies:
"@standardnotes/features" "^1.38.1" "@standardnotes/features" "^1.38.1"
"@standardnotes/responses" "^1.6.12" "@standardnotes/responses" "^1.6.12"
@@ -2501,13 +2501,13 @@
"@standardnotes/common" "^1.19.6" "@standardnotes/common" "^1.19.6"
"@standardnotes/features" "^1.38.1" "@standardnotes/features" "^1.38.1"
"@standardnotes/services@^1.9.13": "@standardnotes/services@^1.9.14":
version "1.9.13" version "1.9.14"
resolved "https://registry.yarnpkg.com/@standardnotes/services/-/services-1.9.13.tgz#4af36863626cd70be976785f85dc76cb3fd8f3d8" resolved "https://registry.yarnpkg.com/@standardnotes/services/-/services-1.9.14.tgz#6bc692ce58c2db3573474c7efd44b3586a59d52e"
integrity sha512-UWrg8ThBUl3JvLRFc3tEPXstJFQtnLAVHOfRppUL8MZZ+U6sYmKRpQp9+pX0Wdx0SQwQuuRyFKtSw9JFlLvrnA== integrity sha512-9Z62AP+zcOpmQfRiOFYUZnYIsHgTVsV6x3DcvE800xvBkQkHbkx5VeeDzV9r06iJzIl4f2BGvss3rjj3PC/R3Q==
dependencies: dependencies:
"@standardnotes/common" "^1.19.6" "@standardnotes/common" "^1.19.6"
"@standardnotes/models" "^1.5.1" "@standardnotes/models" "^1.6.0"
"@standardnotes/responses" "^1.6.12" "@standardnotes/responses" "^1.6.12"
"@standardnotes/utils" "^1.6.2" "@standardnotes/utils" "^1.6.2"
@@ -2530,20 +2530,20 @@
buffer "^6.0.3" buffer "^6.0.3"
libsodium-wrappers "^0.7.9" libsodium-wrappers "^0.7.9"
"@standardnotes/snjs@2.102.0": "@standardnotes/snjs@2.103.0":
version "2.102.0" version "2.103.0"
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.102.0.tgz#756ad160395c87d791399d0d2784ae9b2853d07e" resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.103.0.tgz#708d39780b685b9e27478cb70900d71e89d6ec57"
integrity sha512-+cPyYW6MUex1D8MeX0hrDzKywnuGZj8le7varDbhs3zT++f7UWt6pmu7SEXx71A75rP5u5oDtdaOxqSyBNHOlg== integrity sha512-ak89W+ShM2kNxlW+eMA86AgjGGMUkyy+4zOa5G0KWdQJEHcevFnLVyn4ZPhvywxJWAnNZi0gGEQFuLd5IunyLQ==
dependencies: dependencies:
"@standardnotes/auth" "^3.18.11" "@standardnotes/auth" "^3.18.11"
"@standardnotes/common" "^1.19.6" "@standardnotes/common" "^1.19.6"
"@standardnotes/domain-events" "^2.27.12" "@standardnotes/domain-events" "^2.27.12"
"@standardnotes/encryption" "^1.4.12" "@standardnotes/encryption" "^1.4.13"
"@standardnotes/features" "^1.38.1" "@standardnotes/features" "^1.38.1"
"@standardnotes/filepicker" "^1.13.3" "@standardnotes/filepicker" "^1.13.3"
"@standardnotes/models" "^1.5.1" "@standardnotes/models" "^1.6.0"
"@standardnotes/responses" "^1.6.12" "@standardnotes/responses" "^1.6.12"
"@standardnotes/services" "^1.9.13" "@standardnotes/services" "^1.9.14"
"@standardnotes/settings" "^1.14.1" "@standardnotes/settings" "^1.14.1"
"@standardnotes/sncrypto-common" "^1.7.7" "@standardnotes/sncrypto-common" "^1.7.7"
"@standardnotes/utils" "^1.6.2" "@standardnotes/utils" "^1.6.2"