diff --git a/src/App.tsx b/src/App.tsx
index f8d2d422..71b942bf 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -145,15 +145,16 @@ export const App = (props: { env: TEnvironment }) => {
return removeAppChangeObserver;
}, [applicationGroupRef.current.primaryApplication]);
+ if (!application) {
+ return null;
+ }
return (
- {application && (
-
- )}
+
);
};
diff --git a/src/hooks/useFiles.ts b/src/hooks/useFiles.ts
index e0a4c7b4..03bf03fa 100644
--- a/src/hooks/useFiles.ts
+++ b/src/hooks/useFiles.ts
@@ -1,6 +1,6 @@
import { ToastType } from '@Lib/types';
import { useNavigation } from '@react-navigation/native';
-import { ApplicationContext } from '@Root/ApplicationContext';
+import { useSafeApplicationContext } from '@Root/hooks/useSafeApplicationContext';
import { SCREEN_INPUT_MODAL_FILE_NAME } from '@Screens/screens';
import { TAppStackNavigationProp } from '@Screens/UploadedFilesList/UploadedFileItem';
import {
@@ -15,7 +15,7 @@ import {
SNNote,
} from '@standardnotes/snjs';
import { useCustomActionSheet } from '@Style/custom_action_sheet';
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import { Platform } from 'react-native';
import FileViewer from 'react-native-file-viewer';
import RNFS, { exists } from 'react-native-fs';
@@ -41,7 +41,7 @@ export const isFileTypePreviewable = (fileType: string) => {
};
export const useFiles = ({ note }: Props) => {
- const application = useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const { showActionSheet } = useCustomActionSheet();
const navigation = useNavigation();
@@ -53,9 +53,6 @@ export const useFiles = ({ note }: Props) => {
const { Success, Info, Error } = ToastType;
const reloadAttachedFiles = useCallback(() => {
- if (!application || !note) {
- return [];
- }
setAttachedFiles(
application.items
.getFilesForNote(note)
@@ -64,9 +61,6 @@ export const useFiles = ({ note }: Props) => {
}, [application, note]);
const reloadAllFiles = useCallback(() => {
- if (!application) {
- return [];
- }
setAllFiles(
application.items
.getItems(ContentType.File)
@@ -87,7 +81,7 @@ export const useFiles = ({ note }: Props) => {
file,
saveInTempLocation = false,
}: TDownloadFileAndReturnLocalPathParams): Promise => {
- if (isDownloading || !application) {
+ if (isDownloading) {
return;
}
const filesService = application.getFilesService();
@@ -148,9 +142,6 @@ export const useFiles = ({ note }: Props) => {
const shareFile = useCallback(
async (file: SNFile) => {
- if (!application) {
- return;
- }
const downloadedFilePath = await downloadFileAndReturnLocalPath({
file,
saveInTempLocation: true,
@@ -201,9 +192,6 @@ export const useFiles = ({ note }: Props) => {
const attachFileToNote = useCallback(
async (file: SNFile) => {
- if (!application || !note) {
- return;
- }
await application.items.associateFileWithNote(file, note);
Toast.show({
type: Success,
@@ -216,9 +204,6 @@ export const useFiles = ({ note }: Props) => {
const detachFileFromNote = useCallback(
async (file: SNFile) => {
- if (!application || !note) {
- return;
- }
await application.items.disassociateFileWithNote(file, note);
Toast.show({
type: Success,
@@ -232,9 +217,6 @@ export const useFiles = ({ note }: Props) => {
const toggleFileProtection = useCallback(
async (file: SNFile) => {
try {
- if (!application) {
- return file.protected;
- }
let result: SNFile | undefined;
if (file.protected) {
result = await application.mutator.unprotectFile(file);
@@ -253,9 +235,6 @@ export const useFiles = ({ note }: Props) => {
const authorizeProtectedActionForFile = useCallback(
async (file: SNFile, challengeReason: ChallengeReason) => {
- if (!application) {
- return false;
- }
const authorizedFiles =
await application.protections.authorizeProtectedActionForFiles(
[file],
@@ -268,9 +247,6 @@ export const useFiles = ({ note }: Props) => {
const renameFile = useCallback(
async (file: SNFile, fileName: string) => {
- if (!application) {
- return;
- }
await application.items.renameFile(file, fileName);
},
[application]
@@ -278,10 +254,6 @@ export const useFiles = ({ note }: Props) => {
const previewFile = useCallback(
async (file: SNFile) => {
- if (!application) {
- return;
- }
-
let downloadedFilePath: string | undefined = '';
try {
const isPreviewable = isFileTypePreviewable(file.mimeType);
@@ -327,10 +299,6 @@ export const useFiles = ({ note }: Props) => {
);
const handleFileAction = useCallback(
async (action: UploadedFileItemAction) => {
- if (!application) {
- return false;
- }
-
const file =
action.type !== UploadedFileItemActionType.RenameFile
? action.payload
@@ -395,9 +363,6 @@ export const useFiles = ({ note }: Props) => {
);
useEffect(() => {
- if (!application) {
- return;
- }
const unregisterFileStream = application.streamItems(
ContentType.File,
() => {
diff --git a/src/hooks/useSafeApplicationContext.ts b/src/hooks/useSafeApplicationContext.ts
new file mode 100644
index 00000000..bd1c3c8a
--- /dev/null
+++ b/src/hooks/useSafeApplicationContext.ts
@@ -0,0 +1,8 @@
+import { MobileApplication } from '@Lib/application';
+import { ApplicationContext } from '@Root/ApplicationContext';
+import { useContext } from 'react';
+
+export const useSafeApplicationContext = () => {
+ const application = useContext(ApplicationContext) as MobileApplication;
+ return application;
+};
diff --git a/src/lib/snjs_helper_hooks.ts b/src/lib/snjs_helper_hooks.ts
index 0e260a6d..5f4f637c 100644
--- a/src/lib/snjs_helper_hooks.ts
+++ b/src/lib/snjs_helper_hooks.ts
@@ -1,4 +1,5 @@
import { ApplicationContext } from '@Root/ApplicationContext';
+import { useSafeApplicationContext } from '@Root/hooks/useSafeApplicationContext';
import { SCREEN_NOTES } from '@Screens/screens';
import {
ApplicationEvent,
@@ -17,7 +18,7 @@ export const useSignedIn = (
signedOutCallback?: () => void
) => {
// Context
- const application = React.useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const [isLocked] = useIsLocked();
@@ -28,24 +29,22 @@ export const useSignedIn = (
let mounted = true;
const getSignedIn = async () => {
if (mounted && !isLocked) {
- setSignedIn(!application?.noAccount());
+ setSignedIn(!application.noAccount());
}
};
getSignedIn();
- const removeSignedInObserver = application?.addEventObserver(
- async event => {
- if (event === ApplicationEvent.Launched) {
- getSignedIn();
- }
- if (event === ApplicationEvent.SignedIn) {
- setSignedIn(true);
- signedInCallback && signedInCallback();
- } else if (event === ApplicationEvent.SignedOut) {
- setSignedIn(false);
- signedOutCallback && signedOutCallback();
- }
+ const removeSignedInObserver = application.addEventObserver(async event => {
+ if (event === ApplicationEvent.Launched) {
+ getSignedIn();
}
- );
+ if (event === ApplicationEvent.SignedIn) {
+ setSignedIn(true);
+ signedInCallback && signedInCallback();
+ } else if (event === ApplicationEvent.SignedOut) {
+ setSignedIn(false);
+ signedOutCallback && signedOutCallback();
+ }
+ });
return () => {
mounted = false;
@@ -58,7 +57,7 @@ export const useSignedIn = (
export const useOutOfSync = () => {
// Context
- const application = React.useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
// State
const [outOfSync, setOutOfSync] = React.useState(false);
@@ -66,7 +65,7 @@ export const useOutOfSync = () => {
React.useEffect(() => {
let isMounted = true;
const getOutOfSync = async () => {
- const outOfSyncInitial = await application?.sync.isOutOfSync();
+ const outOfSyncInitial = await application.sync.isOutOfSync();
if (isMounted) {
setOutOfSync(Boolean(outOfSyncInitial));
}
@@ -78,15 +77,13 @@ export const useOutOfSync = () => {
}, [application]);
React.useEffect(() => {
- const removeSignedInObserver = application?.addEventObserver(
- async event => {
- if (event === ApplicationEvent.EnteredOutOfSync) {
- setOutOfSync(true);
- } else if (event === ApplicationEvent.ExitedOutOfSync) {
- setOutOfSync(false);
- }
+ const removeSignedInObserver = application.addEventObserver(async event => {
+ if (event === ApplicationEvent.EnteredOutOfSync) {
+ setOutOfSync(true);
+ } else if (event === ApplicationEvent.ExitedOutOfSync) {
+ setOutOfSync(false);
}
- );
+ });
return removeSignedInObserver;
}, [application]);
@@ -412,7 +409,7 @@ export const useChangeNoteChecks = (
editor: NoteViewController | undefined = undefined
) => {
// Context
- const application = React.useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const canChangeNote = useCallback(async () => {
if (!note) {
@@ -420,7 +417,7 @@ export const useChangeNoteChecks = (
}
if (note.deleted) {
- application?.alertService?.alert(
+ application.alertService?.alert(
'The note you are attempting to edit has been deleted, and is awaiting sync. Changes you make will be disregarded.'
);
return false;
@@ -430,8 +427,8 @@ export const useChangeNoteChecks = (
await editor.insertTemplatedNote();
}
- if (!application?.items.findItem(note.uuid)) {
- application?.alertService!.alert(
+ if (!application.items.findItem(note.uuid)) {
+ application.alertService!.alert(
"The note you are attempting to save can not be found or has been deleted. Changes you make will not be synced. Please copy this note's text and start a new note."
);
return false;
diff --git a/src/screens/InputModal/FileInputModal.tsx b/src/screens/InputModal/FileInputModal.tsx
index ddb8878a..97e50f86 100644
--- a/src/screens/InputModal/FileInputModal.tsx
+++ b/src/screens/InputModal/FileInputModal.tsx
@@ -1,7 +1,7 @@
import { ButtonCell } from '@Components/ButtonCell';
import { SectionedTableCell } from '@Components/SectionedTableCell';
import { TableSection } from '@Components/TableSection';
-import { ApplicationContext } from '@Root/ApplicationContext';
+import { useSafeApplicationContext } from '@Root/hooks/useSafeApplicationContext';
import { ModalStackNavigationProp } from '@Root/ModalStack';
import { SCREEN_INPUT_MODAL_FILE_NAME } from '@Screens/screens';
import { UploadedFileItemActionType } from '@Screens/UploadedFilesList/UploadedFileItemAction';
@@ -15,16 +15,13 @@ type Props = ModalStackNavigationProp;
export const FileInputModal: FC = props => {
const { file, handleFileAction } = props.route.params;
const themeService = useContext(ThemeServiceContext);
- const application = useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const fileNameInputRef = useRef(null);
const [fileName, setFileName] = useState(file.name);
const onSubmit = async () => {
- if (!application) {
- return;
- }
const trimmedFileName = fileName.trim();
if (trimmedFileName === '') {
setFileName(file.name);
diff --git a/src/screens/Notes/Notes.tsx b/src/screens/Notes/Notes.tsx
index 07eb385e..9885b2f8 100644
--- a/src/screens/Notes/Notes.tsx
+++ b/src/screens/Notes/Notes.tsx
@@ -2,8 +2,8 @@ import { AppStateType } from '@Lib/application_state';
import { PrefKey } from '@Lib/preferences_manager';
import { useSignedIn, useSyncStatus } from '@Lib/snjs_helper_hooks';
import { useFocusEffect, useNavigation } from '@react-navigation/native';
-import { ApplicationContext } from '@Root/ApplicationContext';
import { AppStackNavigationProp } from '@Root/AppStack';
+import { useSafeApplicationContext } from '@Root/hooks/useSafeApplicationContext';
import {
SCREEN_COMPOSE,
SCREEN_NOTES,
@@ -47,7 +47,7 @@ export const Notes = React.memo(
keyboardHeight: number | undefined;
}) => {
// Context
- const application = useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const theme = useContext(ThemeContext);
const navigation =
useNavigation<
@@ -62,25 +62,25 @@ export const Notes = React.memo(
// State
const [sortBy, setSortBy] = useState(() =>
- application!
+ application
.getLocalPreferences()
.getValue(PrefKey.SortNotesBy, CollectionSort.CreatedAt)
);
const [sortReverse, setSortReverse] = useState(() =>
- application!
+ application
.getLocalPreferences()
.getValue(PrefKey.SortNotesReverse, false)
);
const [hideDates, setHideDates] = useState(() =>
- application!.getLocalPreferences().getValue(PrefKey.NotesHideDate, false)
+ application.getLocalPreferences().getValue(PrefKey.NotesHideDate, false)
);
const [hidePreviews, setHidePreviews] = useState(() =>
- application!
+ application
.getLocalPreferences()
.getValue(PrefKey.NotesHideNotePreview, false)
);
const [hideEditorIcon, setHideEditorIcon] = useState(() =>
- application!
+ application
.getLocalPreferences()
.getValue(PrefKey.NotesHideEditorIcon, false)
);
@@ -92,8 +92,8 @@ export const Notes = React.memo(
useState(
() =>
!(
- application!.hasProtectionSources() &&
- !application!.hasUnprotectedAccessSession()
+ application.hasProtectionSources() &&
+ !application.hasUnprotectedAccessSession()
)
);
const [includeArchivedNotes, setIncludeArchivedNotes] =
@@ -106,8 +106,8 @@ export const Notes = React.memo(
const haveDisplayOptions = useRef(false);
const protectionsEnabled = useRef(
- application!.hasProtectionSources() &&
- !application!.hasUnprotectedAccessSession()
+ application.hasProtectionSources() &&
+ !application.hasUnprotectedAccessSession()
);
const reloadTitle = useCallback(
@@ -115,7 +115,7 @@ export const Notes = React.memo(
let title = '';
let subTitle: string | undefined;
- const selectedTag = application?.getAppState().selectedTag;
+ const selectedTag = application.getAppState().selectedTag;
if (newNotes && (newFilter ?? searchText).length > 0) {
const resultCount = newNotes.length;
@@ -126,7 +126,7 @@ export const Notes = React.memo(
} else if (selectedTag) {
title = selectedTag.title;
if (selectedTag instanceof SNTag && selectedTag.parentId) {
- const parents = application!.items.getTagParentChain(
+ const parents = application.items.getTagParentChain(
selectedTag.uuid
);
const hierarchy = parents.map(tag => tag.title).join(' ⫽ ');
@@ -161,7 +161,7 @@ export const Notes = React.memo(
const openNote = useCallback(
async (noteUuid: SNNote['uuid'], replaceScreen: boolean = false) => {
- await application!.getAppState().openEditor(noteUuid);
+ await application.getAppState().openEditor(noteUuid);
openCompose(false, replaceScreen);
},
[application, openCompose]
@@ -169,25 +169,25 @@ export const Notes = React.memo(
const onNoteSelect = useCallback(
async (noteUuid: SNNote['uuid']) => {
- const note = application?.items.findItem(noteUuid) as SNNote;
+ const note = application.items.findItem(noteUuid) as SNNote;
if (note) {
if (note.errorDecrypting) {
if (note.waitingForKey) {
- return application?.presentKeyRecoveryWizard();
+ return application.presentKeyRecoveryWizard();
} else {
- return application?.alertService.alert(
+ return application.alertService.alert(
'Standard Notes was unable to decrypt this item. Please sign out of your account and back in to attempt to resolve this issue.',
'Unable to Decrypt'
);
}
}
- if (note.protected && !application?.hasProtectionSources()) {
+ if (note.protected && !application.hasProtectionSources()) {
return navigation.navigate(SCREEN_VIEW_PROTECTED_NOTE, {
onPressView: () => openNote(noteUuid, true),
});
}
- if (await application?.authorizeNoteAccess(note)) {
+ if (await application.authorizeNoteAccess(note)) {
openNote(noteUuid);
}
}
@@ -209,7 +209,7 @@ export const Notes = React.memo(
useEffect(() => {
let mounted = true;
const removeEditorObserver =
- application?.editorGroup.addActiveControllerChangeObserver(
+ application.editorGroup.addActiveControllerChangeObserver(
activeEditor => {
if (mounted) {
setSelectedNoteId(activeEditor?.note?.uuid);
@@ -241,7 +241,7 @@ export const Notes = React.memo(
includeArchived?: boolean,
includeTrashed?: boolean
) => {
- const tag = application!.getAppState().selectedTag;
+ const tag = application.getAppState().selectedTag;
const searchQuery =
searchText || searchFilter
? {
@@ -270,7 +270,7 @@ export const Notes = React.memo(
includeTrashed:
applyFilters && (includeTrashed ?? includeTrashedNotes),
});
- application!.items.setNotesDisplayCriteria(criteria);
+ application.items.setNotesDisplayCriteria(criteria);
},
[
application,
@@ -290,7 +290,7 @@ export const Notes = React.memo(
if (includeProtected) {
setIncludeProtectedStarted(true);
allowToggling =
- await application?.authorizeSearchingProtectedNotesText();
+ await application.authorizeSearchingProtectedNotesText();
}
setIncludeProtectedStarted(false);
@@ -326,15 +326,15 @@ export const Notes = React.memo(
const reloadSearchOptions = useCallback(() => {
const protections =
- application?.hasProtectionSources() &&
- !application!.hasUnprotectedAccessSession();
+ application.hasProtectionSources() &&
+ !application.hasUnprotectedAccessSession();
if (protections !== protectionsEnabled.current) {
protectionsEnabled.current = !!protections;
setIncludeProtectedNoteText(!protections);
}
- const selectedTag = application?.getAppState().selectedTag;
+ const selectedTag = application.getAppState().selectedTag;
const options = [
{
label: 'Include Protected Contents',
@@ -398,7 +398,7 @@ export const Notes = React.memo(
if (note) {
onNoteSelect(note.uuid);
} else {
- application?.getAppState().closeActiveEditor();
+ application.getAppState().closeActiveEditor();
}
},
[application, getFirstSelectableNote, onNoteSelect]
@@ -406,7 +406,7 @@ export const Notes = React.memo(
const reloadNotes = useCallback(
(reselectNote?: boolean, tagChanged?: boolean, searchFilter?: string) => {
- const tag = application!.getAppState().selectedTag;
+ const tag = application.getAppState().selectedTag;
if (!tag) {
return;
}
@@ -419,7 +419,7 @@ export const Notes = React.memo(
reloadNotesDisplayOptions();
}
- const newNotes = application!.items.getDisplayableItems(
+ const newNotes = application.items.getDisplayableItems(
ContentType.Note
) as SNNote[];
let renderedNotes: SNNote[] = newNotes;
@@ -427,22 +427,22 @@ export const Notes = React.memo(
setNotes(renderedNotes);
reloadTitle(renderedNotes, searchFilter);
- if (reselectNote && application?.getAppState().isTabletDevice) {
+ if (reselectNote && application.getAppState().isTabletDevice) {
if (tagChanged) {
if (renderedNotes.length > 0) {
selectFirstNote(renderedNotes);
} else {
- application?.getAppState().closeActiveEditor();
+ application.getAppState().closeActiveEditor();
}
} else {
const activeNote = application
- ?.getAppState()
+ .getAppState()
.getActiveNoteController()?.note;
if (activeNote) {
const discarded = activeNote.deleted || activeNote.trashed;
const isTrashView =
- application?.getAppState().selectedTag instanceof SmartView &&
- application?.getAppState().selectedTag.uuid ===
+ application.getAppState().selectedTag instanceof SmartView &&
+ application.getAppState().selectedTag.uuid ===
SystemViewId.TrashedNotes;
if (discarded && !isTrashView) {
selectNextOrCreateNew(renderedNotes);
@@ -464,16 +464,16 @@ export const Notes = React.memo(
);
const onNoteCreate = useCallback(async () => {
- let title = application!.getAppState().isTabletDevice
+ let title = application.getAppState().isTabletDevice
? `Note ${notes.length + 1}`
: undefined;
- await application!.getAppState().createEditor(title);
+ await application.getAppState().createEditor(title);
openCompose(true);
reloadNotes(true);
}, [application, notes.length, openCompose, reloadNotes]);
const streamNotesAndTags = useCallback(() => {
- const removeStreamNotes = application!.streamItems(
+ const removeStreamNotes = application.streamItems(
[ContentType.Note],
async () => {
/** If a note changes, it will be queried against the existing filter;
@@ -482,7 +482,7 @@ export const Notes = React.memo(
}
);
- const removeStreamTags = application!.streamItems(
+ const removeStreamTags = application.streamItems(
[ContentType.Tag],
async () => {
/** A tag could have changed its relationships, so we need to reload the filter */
@@ -499,20 +499,20 @@ export const Notes = React.memo(
const reloadPreferences = useCallback(async () => {
const newSortBy = application
- ?.getLocalPreferences()
+ .getLocalPreferences()
.getValue(PrefKey.SortNotesBy, CollectionSort.CreatedAt);
let displayOptionsChanged = false;
const newSortReverse = application
- ?.getLocalPreferences()
+ .getLocalPreferences()
.getValue(PrefKey.SortNotesReverse, false);
- const newHidePreview = application!
+ const newHidePreview = application
.getLocalPreferences()
.getValue(PrefKey.NotesHideNotePreview, false);
- const newHideDate = application!
+ const newHideDate = application
.getLocalPreferences()
.getValue(PrefKey.NotesHideDate, false);
- const newHideEditorIcon = application!
+ const newHideEditorIcon = application
.getLocalPreferences()
.getValue(PrefKey.NotesHideEditorIcon, false);
@@ -557,7 +557,7 @@ export const Notes = React.memo(
const onRefresh = useCallback(() => {
startRefreshing();
- application?.sync.sync();
+ application.sync.sync();
}, [application, startRefreshing]);
const onSearchChange = useCallback(
@@ -572,7 +572,7 @@ export const Notes = React.memo(
useFocusEffect(
useCallback(() => {
reloadPreferences();
- const removeAppStateChangeHandler = application!
+ const removeAppStateChangeHandler = application
.getAppState()
.addStateChangeObserver(state => {
if (state === AppStateType.TagChanged) {
@@ -616,7 +616,7 @@ export const Notes = React.memo(
hideDates={hideDates}
hideEditorIcon={hideEditorIcon}
selectedNoteId={
- application?.getAppState().isInTabletMode
+ application.getAppState().isInTabletMode
? selectedNoteId
: undefined
}
@@ -627,7 +627,7 @@ export const Notes = React.memo(
= ({ note }) => {
- const application = useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const navigation =
useNavigation<
@@ -30,10 +30,6 @@ export const Files: FC = ({ note }) => {
>();
const { showActionsMenu, attachedFiles } = useFiles({ note });
- if (!application) {
- return null;
- }
-
const openFilesScreen = () => {
navigation.navigate(SCREEN_UPLOADED_FILES_LIST, { note });
};
diff --git a/src/screens/SideMenu/Listed.tsx b/src/screens/SideMenu/Listed.tsx
index c07f8d58..96c3bbd0 100644
--- a/src/screens/SideMenu/Listed.tsx
+++ b/src/screens/SideMenu/Listed.tsx
@@ -1,5 +1,5 @@
import { SnIcon } from '@Components/SnIcon';
-import { ApplicationContext } from '@Root/ApplicationContext';
+import { useSafeApplicationContext } from '@Root/hooks/useSafeApplicationContext';
import {
CantLoadActionsText,
CreateBlogContainer,
@@ -15,7 +15,7 @@ import {
SNNote,
} from '@standardnotes/snjs';
import { useCustomActionSheet } from '@Style/custom_action_sheet';
-import React, { FC, useCallback, useContext, useEffect, useState } from 'react';
+import React, { FC, useCallback, useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, View } from 'react-native';
type TProps = {
@@ -27,7 +27,7 @@ type TListedAccountItem =
| Pick;
export const Listed: FC = ({ note }) => {
- const application = useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const [isLoading, setIsLoading] = useState(false);
const [isActionInProgress, setIsActionInProgress] = useState(false);
@@ -44,9 +44,6 @@ export const Listed: FC = ({ note }) => {
const getListedAccountsDetails = useCallback(
async (accounts: ListedAccount[]) => {
- if (!application) {
- return;
- }
const listedAccountsArray: TListedAccountItem[] = [];
for (const listedAccountItem of accounts) {
@@ -67,9 +64,6 @@ export const Listed: FC = ({ note }) => {
);
const reloadListedAccounts = useCallback(async () => {
- if (!application) {
- return [];
- }
setIsLoading(true);
const accounts = await application.getListedAccounts();
setListedAccounts(accounts);
@@ -79,7 +73,7 @@ export const Listed: FC = ({ note }) => {
}, [application, getListedAccountsDetails]);
const registerNewAccount = useCallback(() => {
- if (!application || isRequestingAccount) {
+ if (isRequestingAccount) {
return;
}
@@ -125,9 +119,6 @@ export const Listed: FC = ({ note }) => {
};
const showActionsMenu = (item: TListedAccountItem, index: number) => {
- if (!application) {
- return;
- }
if (!doesListedItemHaveActions(item)) {
application.alertService.alert('Unable to load actions.');
return;
@@ -163,9 +154,6 @@ export const Listed: FC = ({ note }) => {
);
};
- if (!application) {
- return null;
- }
return (
{isLoading && }
diff --git a/src/screens/SideMenu/NoteSideMenu.tsx b/src/screens/SideMenu/NoteSideMenu.tsx
index 0dc55439..e68e3617 100644
--- a/src/screens/SideMenu/NoteSideMenu.tsx
+++ b/src/screens/SideMenu/NoteSideMenu.tsx
@@ -7,8 +7,8 @@ import {
import { isUnfinishedFeaturesEnabled } from '@Lib/utils';
import { useFocusEffect, useNavigation } from '@react-navigation/native';
import { TEnvironment } from '@Root/App';
-import { ApplicationContext } from '@Root/ApplicationContext';
import { AppStackNavigationProp } from '@Root/AppStack';
+import { useSafeApplicationContext } from '@Root/hooks/useSafeApplicationContext';
import {
SCREEN_COMPOSE,
SCREEN_INPUT_MODAL_TAG,
@@ -80,12 +80,9 @@ type Props = {
};
function useEditorComponents(): SNComponent[] {
- const application = useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const [components, setComponents] = useState([]);
useEffect(() => {
- if (!application) {
- return;
- }
const removeComponentsObserver = application.streamItems(
ContentType.Component,
() => {
@@ -108,7 +105,7 @@ function useEditorComponents(): SNComponent[] {
export const NoteSideMenu = React.memo((props: Props) => {
// Context
const theme = useContext(ThemeContext);
- const application = useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const navigation =
useNavigation<
AppStackNavigationProp['navigation']
@@ -129,8 +126,6 @@ export const NoteSideMenu = React.memo((props: Props) => {
);
useEffect(() => {
- if (!application) return;
-
const removeEventObserver = application.addSingleEventObserver(
ApplicationEvent.PreferencesChanged,
async () => {
@@ -155,7 +150,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
async () => {
await application?.mutator.deleteItem(note!);
props.drawerRef?.closeDrawer();
- if (!application?.getAppState().isInTabletMode) {
+ if (!application.getAppState().isInTabletMode) {
navigation.popToTop();
}
},
@@ -164,7 +159,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
mutator.trashed = true;
}, false);
props.drawerRef?.closeDrawer();
- if (!application?.getAppState().isInTabletMode) {
+ if (!application.getAppState().isInTabletMode) {
navigation.popToTop();
}
},
@@ -172,7 +167,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
);
useEffect(() => {
- if (!application || !note) {
+ if (!note) {
setAttachedFilesLength(0);
return;
}
@@ -180,7 +175,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
}, [application, note]);
useEffect(() => {
- if (!application || !note) {
+ if (!note) {
return;
}
const removeFilesObserver = application.streamItems(
@@ -282,7 +277,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
const onEditorPress = useCallback(
async (selectedComponent?: SNComponent) => {
- if (!note || !application) {
+ if (!note) {
return;
}
if (note?.locked) {
@@ -413,7 +408,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
);
const editors = useMemo(() => {
- if (!note || !application) {
+ if (!note) {
return [];
}
const componentEditor = application.componentManager.editorForNote(note);
@@ -606,7 +601,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
if (confirmed) {
await application?.mutator.emptyTrash();
props.drawerRef?.closeDrawer();
- if (!application?.getAppState().isInTabletMode) {
+ if (!application.getAppState().isInTabletMode) {
navigation.popToTop();
}
application?.sync.sync();
diff --git a/src/screens/SideMenu/TagSelectionList.tsx b/src/screens/SideMenu/TagSelectionList.tsx
index e45db430..d4a7eb73 100644
--- a/src/screens/SideMenu/TagSelectionList.tsx
+++ b/src/screens/SideMenu/TagSelectionList.tsx
@@ -1,6 +1,6 @@
import { useNavigation } from '@react-navigation/native';
-import { ApplicationContext } from '@Root/ApplicationContext';
import { AppStackNavigationProp } from '@Root/AppStack';
+import { useSafeApplicationContext } from '@Root/hooks/useSafeApplicationContext';
import { SCREEN_COMPOSE, SCREEN_INPUT_MODAL_TAG } from '@Screens/screens';
import { SideMenuOptionIconDescriptionType } from '@Screens/SideMenu/SideMenuSection';
import {
@@ -11,13 +11,7 @@ import {
SNTag,
} from '@standardnotes/snjs';
import { useCustomActionSheet } from '@Style/custom_action_sheet';
-import React, {
- useCallback,
- useContext,
- useEffect,
- useRef,
- useState,
-} from 'react';
+import React, { useCallback, useEffect, useRef, useState } from 'react';
import { FlatList, ListRenderItem } from 'react-native';
import { SideMenuCell } from './SideMenuCell';
import { EmptyPlaceholder } from './TagSelectionList.styled';
@@ -39,7 +33,7 @@ export const TagSelectionList = React.memo(
hasBottomPadding,
}: Props) => {
// Context
- const application = useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const navigation =
useNavigation<
AppStackNavigationProp['navigation']
@@ -124,7 +118,7 @@ export const TagSelectionList = React.memo(
};
const isRootTag = (tag: SNTag | SmartView): boolean =>
- tag instanceof SmartView || !application?.items.getTagParent(tag.uuid);
+ tag instanceof SmartView || !application.items.getTagParent(tag.uuid);
const showFolders = contentType === ContentType.Tag;
const renderedTags = showFolders
@@ -132,10 +126,6 @@ export const TagSelectionList = React.memo(
: tags;
const renderItem: ListRenderItem = ({ item }) => {
- if (!application) {
- return null;
- }
-
let title = item.deleted ? 'Deleting...' : item.title;
if (item.errorDecrypting) {
title = 'Unable to Decrypt';
diff --git a/src/screens/UploadedFilesList/UploadedFileItem.tsx b/src/screens/UploadedFilesList/UploadedFileItem.tsx
index 8800ec53..8fb18be2 100644
--- a/src/screens/UploadedFilesList/UploadedFileItem.tsx
+++ b/src/screens/UploadedFilesList/UploadedFileItem.tsx
@@ -1,7 +1,7 @@
import { SnIcon } from '@Components/SnIcon';
-import { ApplicationContext } from '@Root/ApplicationContext';
import { AppStackNavigationProp } from '@Root/AppStack';
import { useFiles } from '@Root/hooks/useFiles';
+import { useSafeApplicationContext } from '@Root/hooks/useSafeApplicationContext';
import { SCREEN_COMPOSE } from '@Screens/screens';
import { formatSizeToReadableString } from '@standardnotes/filepicker';
import { SNFile, SNNote } from '@standardnotes/snjs';
@@ -29,7 +29,7 @@ export type TAppStackNavigationProp = AppStackNavigationProp<
>['navigation'];
export const UploadedFileItem: FC = ({ file, note }) => {
- const application = useContext(ApplicationContext);
+ const application = useSafeApplicationContext();
const theme = useContext(ThemeContext);
const { showActionsMenu } = useFiles({ note });
@@ -40,10 +40,6 @@ export const UploadedFileItem: FC = ({ file, note }) => {
setFileName(file.name);
}, [file.name]);
- if (!application) {
- return null;
- }
-
const iconType = application.iconsController.getIconForFileType(
file.mimeType
);
diff --git a/src/screens/UploadedFilesList/UploadedFilesList.tsx b/src/screens/UploadedFilesList/UploadedFilesList.tsx
index 67e8a3df..4bb0c234 100644
--- a/src/screens/UploadedFilesList/UploadedFilesList.tsx
+++ b/src/screens/UploadedFilesList/UploadedFilesList.tsx
@@ -1,7 +1,6 @@
import { SearchBar } from '@Components/SearchBar';
import { SnIcon } from '@Components/SnIcon';
import { useNavigation } from '@react-navigation/native';
-import { ApplicationContext } from '@Root/ApplicationContext';
import { useFiles } from '@Root/hooks/useFiles';
import { ModalStackNavigationProp } from '@Root/ModalStack';
import { SCREEN_UPLOADED_FILES_LIST } from '@Screens/screens';
@@ -16,7 +15,6 @@ import { SNFile } from '@standardnotes/snjs';
import React, {
FC,
useCallback,
- useContext,
useEffect,
useMemo,
useRef,
@@ -34,7 +32,6 @@ enum Tabs {
type Props = ModalStackNavigationProp;
export const UploadedFilesList: FC = props => {
- const application = useContext(ApplicationContext);
const styles = useUploadedFilesListStyles();
const navigation = useNavigation();
@@ -54,16 +51,12 @@ export const UploadedFilesList: FC = props => {
currentTab === Tabs.AttachedFiles ? attachedFiles : allFiles;
const filteredList = useMemo(() => {
- if (!application) {
- return [];
- }
-
return searchString
? filesList.filter(file =>
file.name.toLowerCase().includes(searchString.toLowerCase())
)
: filesList;
- }, [application, filesList, searchString]);
+ }, [filesList, searchString]);
useEffect(() => {
let screenTitle = 'Files';
@@ -91,10 +84,6 @@ export const UploadedFilesList: FC = props => {
[scrollListToTop]
);
- if (!application) {
- return null;
- }
-
const { AttachedFiles, AllFiles } = Tabs;
const {
centeredView,