chore: prettier

This commit is contained in:
Mo
2022-05-02 09:59:55 -05:00
parent 4689b07dfd
commit 8aa92bb367
44 changed files with 279 additions and 794 deletions

View File

@@ -41,9 +41,7 @@ export type AppStackNavigationProp<T extends keyof AppStackNavigatorParamList> =
const AppStack = createStackNavigator<AppStackNavigatorParamList>()
export const AppStackComponent = (
props: ModalStackNavigationProp<'AppStack'> & { env: TEnvironment }
) => {
export const AppStackComponent = (props: ModalStackNavigationProp<'AppStack'> & { env: TEnvironment }) => {
// Context
const application = useContext(ApplicationContext)
const theme = useContext(ThemeContext)
@@ -52,9 +50,7 @@ export const AppStackComponent = (
// State
const [dimensions, setDimensions] = useState(() => Dimensions.get('window'))
const [isInTabletMode, setIsInTabletMode] = useState(
() => application?.getAppState().isInTabletMode
)
const [isInTabletMode, setIsInTabletMode] = useState(() => application?.getAppState().isInTabletMode)
const [notesStatus, setNotesStatus] = useState<ScreenStatus>()
const [composeStatus, setComposeStatus] = useState<ScreenStatus>()
const [noteDrawerOpen, setNoteDrawerOpen] = useState(false)
@@ -96,18 +92,16 @@ export const AppStackComponent = (
}, [])
useEffect(() => {
const remoteTabletModeSubscription = application
?.getAppState()
.addStateEventObserver((event, data) => {
if (event === AppStateEventType.TabletModeChange) {
const eventData = data as TabletModeChangeData
if (eventData.new_isInTabletMode && !eventData.old_isInTabletMode) {
setIsInTabletMode(true)
} else if (!eventData.new_isInTabletMode && eventData.old_isInTabletMode) {
setIsInTabletMode(false)
}
const remoteTabletModeSubscription = application?.getAppState().addStateEventObserver((event, data) => {
if (event === AppStateEventType.TabletModeChange) {
const eventData = data as TabletModeChangeData
if (eventData.new_isInTabletMode && !eventData.old_isInTabletMode) {
setIsInTabletMode(true)
} else if (!eventData.new_isInTabletMode && eventData.old_isInTabletMode) {
setIsInTabletMode(false)
}
})
}
})
return remoteTabletModeSubscription
}, [application])
@@ -141,13 +135,7 @@ export const AppStackComponent = (
drawerType="slide"
drawerLockMode={hasEditor ? 'unlocked' : 'locked-closed'}
renderNavigationView={() =>
hasEditor && (
<NoteSideMenu
drawerOpen={noteDrawerOpen}
drawerRef={noteDrawerRef.current}
env={props.env}
/>
)
hasEditor && <NoteSideMenu drawerOpen={noteDrawerOpen} drawerRef={noteDrawerRef.current} env={props.env} />
}
>
<AppStack.Navigator
@@ -170,17 +158,9 @@ export const AppStackComponent = (
const screenStatus = isInTabletMode ? composeStatus || notesStatus : notesStatus
const title = route.params?.title ?? (children || '')
const subtitle = [screenStatus?.status, route.params?.subTitle]
.filter(x => !!x)
.join(' • ')
const subtitle = [screenStatus?.status, route.params?.subTitle].filter(x => !!x).join(' • ')
return (
<HeaderTitleView
title={title}
subtitle={subtitle}
subtitleColor={screenStatus?.color}
/>
)
return <HeaderTitleView title={title} subtitle={subtitle} subtitleColor={screenStatus?.color} />
},
headerLeft: () => (
<HeaderButtons HeaderButtonComponent={IoniconsHeaderButton}>

View File

@@ -35,10 +35,7 @@ const ButtonLabel = styled.Text<ButtonLabelProps>`
text-align: ${props => (props.leftAligned ? 'left' : 'center')};
text-align-vertical: center;
color: ${props => {
let color =
Platform.OS === 'android'
? props.theme.stylekitForegroundColor
: props.theme.stylekitInfoColor
let color = Platform.OS === 'android' ? props.theme.stylekitForegroundColor : props.theme.stylekitInfoColor
if (props.disabled) {
color = 'gray'
} else if (props.important) {

View File

@@ -26,9 +26,7 @@ const TitleContainer = styled.View``
const Title = styled.Text<Pick<Props, 'tinted'>>`
background-color: ${props => props.theme.stylekitBackgroundColor};
font-size: ${props => {
return Platform.OS === 'android'
? props.theme.mainTextFontSize - 2
: props.theme.mainTextFontSize - 4
return Platform.OS === 'android' ? props.theme.mainTextFontSize - 2 : props.theme.mainTextFontSize - 4
}}px;
padding-left: ${props => props.theme.paddingLeft}px;
color: ${props => {
@@ -36,9 +34,7 @@ const Title = styled.Text<Pick<Props, 'tinted'>>`
return props.theme.stylekitInfoColor
}
return Platform.OS === 'android'
? props.theme.stylekitInfoColor
: props.theme.stylekitNeutralColor
return Platform.OS === 'android' ? props.theme.stylekitInfoColor : props.theme.stylekitNeutralColor
}};
font-weight: ${Platform.OS === 'android' ? 'bold' : 'normal'};
`

View File

@@ -88,11 +88,7 @@ export const SectionedAccessoryTableCell: React.FC<Props> = props => {
}
const checkmarkName = Platform.OS === 'android' ? 'md-checkbox' : 'ios-checkmark-circle'
const iconName = props.iconName
? props.iconName
: props.selected && props.selected()
? checkmarkName
: null
const iconName = props.iconName ? props.iconName : props.selected && props.selected() ? checkmarkName : null
const left = props.leftAlignIcon
let iconSize = left ? 25 : 30
@@ -129,15 +125,8 @@ export const SectionedAccessoryTableCell: React.FC<Props> = props => {
)
return (
<TouchableContainer
first={props.first}
last={props.last}
onPress={onPress}
onLongPress={onLongPress}
>
<ContentContainer>
{props.leftAlignIcon ? [icon, textWrapper] : [textWrapper, icon]}
</ContentContainer>
<TouchableContainer first={props.first} last={props.last} onPress={onPress} onLongPress={onLongPress}>
<ContentContainer>{props.leftAlignIcon ? [icon, textWrapper] : [textWrapper, icon]}</ContentContainer>
</TouchableContainer>
)
}

View File

@@ -15,9 +15,7 @@ import { ThemeContext } from 'styled-components'
import { HeaderTitleParams } from './App'
type HistoryStackNavigatorParamList = {
[SCREEN_NOTE_HISTORY]:
| (HeaderTitleParams & { noteUuid: string })
| (undefined & { noteUuid: string })
[SCREEN_NOTE_HISTORY]: (HeaderTitleParams & { noteUuid: string }) | (undefined & { noteUuid: string })
[SCREEN_NOTE_HISTORY_PREVIEW]: HeaderTitleParams & {
revision: NoteHistoryEntry
originalNoteUuid: string
@@ -54,9 +52,7 @@ export const HistoryStack = () => {
testID="headerButton"
disabled={disabled}
title={Platform.OS === 'ios' ? 'Done' : ''}
iconName={
Platform.OS === 'ios' ? undefined : ThemeService.nameForIcon(ICON_CHECKMARK)
}
iconName={Platform.OS === 'ios' ? undefined : ThemeService.nameForIcon(ICON_CHECKMARK)}
onPress={onPress}
/>
</HeaderButtons>

View File

@@ -4,10 +4,7 @@ import { Alert, AlertButton } from 'react-native'
import { goBack, navigate } from './NavigationService'
export class AlertService implements SNAlertService {
blockingDialog(
text: string,
title?: string
): DismissBlockingDialog | Promise<DismissBlockingDialog> {
blockingDialog(text: string, title?: string): DismissBlockingDialog | Promise<DismissBlockingDialog> {
navigate(MODAL_BLOCKING_ALERT, { text, title })
return goBack

View File

@@ -21,14 +21,8 @@ export class ApplicationGroup extends SNApplicationGroup {
})
}
private createApplication = (
descriptor: ApplicationDescriptor,
deviceInterface: DeviceInterface
) => {
const application = new MobileApplication(
deviceInterface as MobileDeviceInterface,
descriptor.identifier
)
private createApplication = (descriptor: ApplicationDescriptor, deviceInterface: DeviceInterface) => {
const application = new MobileApplication(deviceInterface as MobileDeviceInterface, descriptor.identifier)
const internalEventBus = new InternalEventBus()
const applicationState = new ApplicationState(application)
const reviewService = new ReviewService(application, internalEventBus)

View File

@@ -80,10 +80,7 @@ export enum MobileStorageKey {
PasscodeKeyboardTypeKey = 'passcodeKeyboardType',
}
type EventObserverCallback = (
event: AppStateEventType,
data?: TabletModeChangeData
) => void | Promise<void>
type EventObserverCallback = (event: AppStateEventType, data?: TabletModeChangeData) => void | Promise<void>
type ObserverCallback = (event: AppStateType, data?: any) => void | Promise<void>
type LockStateObserverCallback = (event: LockStateType) => void | Promise<void>
@@ -147,10 +144,7 @@ export class ApplicationState extends ApplicationService {
if (this.selectedTagRestored) {
return
}
const savedTagUuid: string | undefined = this.prefService.getValue(
PrefKey.SelectedTagUuid,
undefined
)
const savedTagUuid: string | undefined = this.prefService.getValue(PrefKey.SelectedTagUuid, undefined)
if (isNullOrUndefined(savedTagUuid)) {
this.selectedTagRestored = true
@@ -275,11 +269,7 @@ export class ApplicationState extends ApplicationService {
const defaultEditor = this.application.componentManager.getDefaultEditor()
if (defaultEditor) {
await associateComponentWithNote(
this.application,
defaultEditor,
this.getActiveNoteController().note!
)
await associateComponentWithNote(this.application, defaultEditor, this.getActiveNoteController().note!)
}
}
@@ -356,10 +346,7 @@ export class ApplicationState extends ApplicationService {
this.removeItemChangesListener = this.application.streamItems<SNNote | SNTag>(
[ContentType.Note, ContentType.Tag],
async ({ changed, inserted, removed, source }) => {
if (
source === PayloadEmitSource.PreSyncSave ||
source === PayloadEmitSource.RemoteRetrieved
) {
if (source === PayloadEmitSource.PreSyncSave || source === PayloadEmitSource.RemoteRetrieved) {
const removedNotes = removed.filter(i => i.content_type === ContentType.Note)
for (const removedNote of removedNotes) {
const editor = this.editorForNote(removedNote.uuid)
@@ -368,17 +355,13 @@ export class ApplicationState extends ApplicationService {
}
}
const notes = [...changed, ...inserted].filter(
candidate => candidate.content_type === ContentType.Note
)
const notes = [...changed, ...inserted].filter(candidate => candidate.content_type === ContentType.Note)
const isBrowswingTrashedNotes =
this.selectedTag instanceof SmartView &&
this.selectedTag.uuid === SystemViewId.TrashedNotes
this.selectedTag instanceof SmartView && this.selectedTag.uuid === SystemViewId.TrashedNotes
const isBrowsingArchivedNotes =
this.selectedTag instanceof SmartView &&
this.selectedTag.uuid === SystemViewId.ArchivedNotes
this.selectedTag instanceof SmartView && this.selectedTag.uuid === SystemViewId.ArchivedNotes
for (const note of notes) {
const editor = this.editorForNote(note.uuid)
@@ -395,9 +378,7 @@ export class ApplicationState extends ApplicationService {
}
if (this.selectedTag) {
const matchingTag = [...changed, ...inserted].find(
candidate => candidate.uuid === this.selectedTag!.uuid
)
const matchingTag = [...changed, ...inserted].find(candidate => candidate.uuid === this.selectedTag!.uuid)
if (matchingTag) {
this.selectedTag = matchingTag as SNTag
}
@@ -441,9 +422,7 @@ export class ApplicationState extends ApplicationService {
this.selectedTag = tag
if (saveSelection) {
void this.application
.getLocalPreferences()
.setUserPrefValue(PrefKey.SelectedTagUuid, tag.uuid)
void this.application.getLocalPreferences().setUserPrefValue(PrefKey.SelectedTagUuid, tag.uuid)
}
this.notifyOfStateChange(AppStateType.TagChanged, {
@@ -538,11 +517,7 @@ export class ApplicationState extends ApplicationService {
const hasPasscode = this.application.hasPasscode()
if (hasPasscode && this.passcodeTiming === UnlockTiming.Immediately) {
await this.application.lock()
} else if (
hasBiometrics &&
this.biometricsTiming === UnlockTiming.Immediately &&
!this.locked
) {
} else if (hasBiometrics && this.biometricsTiming === UnlockTiming.Immediately && !this.locked) {
const challenge = new Challenge(
[new ChallengePrompt(ChallengeValidation.Biometric)],
ChallengeReason.ApplicationUnlock,
@@ -574,8 +549,7 @@ export class ApplicationState extends ApplicationService {
// from inactive to active, which doesn't really happen unless you, say, swipe
// notification center in iOS down then back up. We don't want to lock on this state change.
const isResuming = nextAppState === 'active'
const isResumingFromBackground =
isResuming && this.mostRecentState === AppStateType.EnteringBackground
const isResumingFromBackground = isResuming && this.mostRecentState === AppStateType.EnteringBackground
const isEnteringBackground = nextAppState === 'background'
const isLosingFocus = nextAppState === 'inactive'
@@ -624,51 +598,36 @@ export class ApplicationState extends ApplicationService {
}
private async getScreenshotPrivacyEnabled(): Promise<boolean | undefined> {
return this.application.getValue(
StorageKey.MobileScreenshotPrivacyEnabled,
StorageValueModes.Default
) as Promise<boolean | undefined>
return this.application.getValue(StorageKey.MobileScreenshotPrivacyEnabled, StorageValueModes.Default) as Promise<
boolean | undefined
>
}
private async getPasscodeTiming(): Promise<UnlockTiming | undefined> {
return this.application.getValue(
StorageKey.MobilePasscodeTiming,
StorageValueModes.Nonwrapped
) as Promise<UnlockTiming | undefined>
return this.application.getValue(StorageKey.MobilePasscodeTiming, StorageValueModes.Nonwrapped) as Promise<
UnlockTiming | undefined
>
}
private async getBiometricsTiming(): Promise<UnlockTiming | undefined> {
return this.application.getValue(
StorageKey.MobileBiometricsTiming,
StorageValueModes.Nonwrapped
) as Promise<UnlockTiming | undefined>
return this.application.getValue(StorageKey.MobileBiometricsTiming, StorageValueModes.Nonwrapped) as Promise<
UnlockTiming | undefined
>
}
public async setScreenshotPrivacyEnabled(enabled: boolean) {
await this.application.setValue(
StorageKey.MobileScreenshotPrivacyEnabled,
enabled,
StorageValueModes.Default
)
await this.application.setValue(StorageKey.MobileScreenshotPrivacyEnabled, enabled, StorageValueModes.Default)
this.screenshotPrivacyEnabled = enabled
void this.setAndroidScreenshotPrivacy(enabled)
}
public async setPasscodeTiming(timing: UnlockTiming) {
await this.application.setValue(
StorageKey.MobilePasscodeTiming,
timing,
StorageValueModes.Nonwrapped
)
await this.application.setValue(StorageKey.MobilePasscodeTiming, timing, StorageValueModes.Nonwrapped)
this.passcodeTiming = timing
}
public async setBiometricsTiming(timing: UnlockTiming) {
await this.application.setValue(
StorageKey.MobileBiometricsTiming,
timing,
StorageValueModes.Nonwrapped
)
await this.application.setValue(StorageKey.MobileBiometricsTiming, timing, StorageValueModes.Nonwrapped)
this.biometricsTiming = timing
}
@@ -680,11 +639,7 @@ export class ApplicationState extends ApplicationService {
}
public async setPasscodeKeyboardType(type: PasscodeKeyboardType) {
await this.application.setValue(
MobileStorageKey.PasscodeKeyboardTypeKey,
type,
StorageValueModes.Nonwrapped
)
await this.application.setValue(MobileStorageKey.PasscodeKeyboardTypeKey, type, StorageValueModes.Nonwrapped)
}
public onDrawerOpen() {
@@ -695,10 +650,7 @@ export class ApplicationState extends ApplicationService {
Allows other parts of the code to perform external actions without triggering state change notifications.
This is useful on Android when you present a share sheet and dont want immediate authentication to appear.
*/
async performActionWithoutStateChangeImpact(
block: () => void | Promise<void>,
notAwaited?: boolean
) {
async performActionWithoutStateChangeImpact(block: () => void | Promise<void>, notAwaited?: boolean) {
this.ignoreStateChanges = true
if (notAwaited) {
void block()

View File

@@ -62,20 +62,18 @@ export class BackupsService extends ApplicationService {
private async exportIOS(filename: string, data: string) {
return new Promise<boolean>(resolve => {
void (this.application! as MobileApplication)
.getAppState()
.performActionWithoutStateChangeImpact(async () => {
Share.share({
title: filename,
message: data,
})
.then(result => {
resolve(result.action !== Share.dismissedAction)
})
.catch(() => {
resolve(false)
})
void (this.application! as MobileApplication).getAppState().performActionWithoutStateChangeImpact(async () => {
Share.share({
title: filename,
message: data,
})
.then(result => {
resolve(result.action !== Share.dismissedAction)
})
.catch(() => {
resolve(false)
})
})
})
}
@@ -152,9 +150,7 @@ export class BackupsService extends ApplicationService {
}
private async requestStoragePermissionsAndroid() {
const writeStorageGranted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
)
const writeStorageGranted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE)
return writeStorageGranted === PermissionsAndroid.RESULTS.GRANTED
}

View File

@@ -108,15 +108,12 @@ export class ComponentManager extends SNComponentManager {
this.log('Existing package version', existingVersion)
this.log('Latest package version', version)
const shouldDownload =
!existingPackageJson || isRightVersionGreaterThanLeft(existingVersion, version!)
const shouldDownload = !existingPackageJson || isRightVersionGreaterThanLeft(existingVersion, version!)
return shouldDownload
}
public async downloadComponentOffline(
component: SNComponent
): Promise<ComponentLoadingError | undefined> {
public async downloadComponentOffline(component: SNComponent): Promise<ComponentLoadingError | undefined> {
const identifier = component.identifier
const nativeFeature = this.nativeFeatureForIdentifier(identifier)
const downloadUrl = nativeFeature?.download_url || component.package_info?.download_url
@@ -170,9 +167,7 @@ export class ComponentManager extends SNComponentManager {
return false
}
if (checksum !== desiredChecksum) {
this.log(
`Checksums don't match for ${featureIdentifier}; ${checksum} != ${desiredChecksum}; aborting install`
)
this.log(`Checksums don't match for ${featureIdentifier}; ${checksum} != ${desiredChecksum}; aborting install`)
return false
}
this.log(`Checksum ${checksum} matches ${desiredChecksum} for ${featureIdentifier}`)
@@ -191,14 +186,7 @@ export class ComponentManager extends SNComponentManager {
await RNFS.unlink(tmpLocation)
}
this.log(
'Downloading component',
identifier,
'from url',
downloadUrl,
'to location',
tmpLocation
)
this.log('Downloading component', identifier, 'from url', downloadUrl, 'to location', tmpLocation)
const result = await RNFS.downloadFile({
fromUrl: downloadUrl,
@@ -338,11 +326,7 @@ export class ComponentManager extends SNComponentManager {
}
}
export async function associateComponentWithNote(
application: SNApplication,
component: SNComponent,
note: SNNote
) {
export async function associateComponentWithNote(application: SNApplication, component: SNComponent, note: SNNote) {
return application.mutator.changeItem<ComponentMutator>(component, mutator => {
mutator.removeDisassociatedItemId(note.uuid)
mutator.associateWithItem(note.uuid)

View File

@@ -4,14 +4,9 @@ import { ModalStackNavigatorParamList } from '@Root/ModalStack'
import * as React from 'react'
export const navigationRef =
React.createRef<
NavigationContainerRef<AppStackNavigatorParamList & ModalStackNavigatorParamList>
>()
React.createRef<NavigationContainerRef<AppStackNavigatorParamList & ModalStackNavigatorParamList>>()
export function navigate(
name: keyof AppStackNavigatorParamList | keyof ModalStackNavigatorParamList,
params?: any
) {
export function navigate(name: keyof AppStackNavigatorParamList | keyof ModalStackNavigatorParamList, params?: any) {
navigationRef.current?.navigate(name, params)
}

View File

@@ -24,12 +24,7 @@ export class SNReactNativeCrypto implements SNPureCrypto {
return
}
pbkdf2(
password: Utf8String,
salt: Utf8String,
iterations: number,
length: number
): Promise<string | null> {
pbkdf2(password: Utf8String, salt: Utf8String, iterations: number, length: number): Promise<string | null> {
return Aes.pbkdf2(password, salt, iterations, length)
}
@@ -43,11 +38,7 @@ export class SNReactNativeCrypto implements SNPureCrypto {
return Aes.encrypt(plaintext, key, iv)
}
async aes256CbcDecrypt(
ciphertext: Base64String,
iv: HexString,
key: HexString
): Promise<Utf8String | null> {
async aes256CbcDecrypt(ciphertext: Base64String, iv: HexString, key: HexString): Promise<Utf8String | null> {
try {
return Aes.decrypt(ciphertext, key, iv)
} catch (e) {
@@ -71,29 +62,11 @@ export class SNReactNativeCrypto implements SNPureCrypto {
return Aes.sha1(text)
}
public argon2(
password: Utf8String,
salt: HexString,
iterations: number,
bytes: number,
length: number
): HexString {
return Sodium.crypto_pwhash(
length,
password,
salt,
iterations,
bytes,
Sodium.constants.crypto_pwhash_ALG_DEFAULT
)
public argon2(password: Utf8String, salt: HexString, iterations: number, bytes: number, length: number): HexString {
return Sodium.crypto_pwhash(length, password, salt, iterations, bytes, Sodium.constants.crypto_pwhash_ALG_DEFAULT)
}
xchacha20Encrypt(
plaintext: Utf8String,
nonce: HexString,
key: HexString,
assocData: Utf8String
): Base64String {
xchacha20Encrypt(plaintext: Utf8String, nonce: HexString, key: HexString, assocData: Utf8String): Base64String {
return Sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(plaintext, nonce, key, assocData)
}
@@ -104,12 +77,7 @@ export class SNReactNativeCrypto implements SNPureCrypto {
assocData: Utf8String
): string | null {
try {
const result = Sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
ciphertext,
nonce,
key,
assocData
)
const result = Sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(ciphertext, nonce, key, assocData)
return result
} catch (e) {
return null
@@ -136,10 +104,7 @@ export class SNReactNativeCrypto implements SNPureCrypto {
return new Uint8Array(encryptedBuffer)
}
public xchacha20StreamInitDecryptor(
header: Base64String,
key: HexString
): Sodium.MobileStreamDecryptor {
public xchacha20StreamInitDecryptor(header: Base64String, key: HexString): Sodium.MobileStreamDecryptor {
const decryptor = Sodium.crypto_secretstream_xchacha20poly1305_init_pull(header, key)
return decryptor
}
@@ -153,11 +118,7 @@ export class SNReactNativeCrypto implements SNPureCrypto {
throw new Error('Invalid ciphertext size')
}
const result = Sodium.crypto_secretstream_xchacha20poly1305_pull(
decryptor,
encryptedBuffer.buffer,
assocData
)
const result = Sodium.crypto_secretstream_xchacha20poly1305_pull(decryptor, encryptedBuffer.buffer, assocData)
if (!result) {
return false

View File

@@ -93,9 +93,7 @@ export const useIsLocked = () => {
const application = React.useContext(ApplicationContext)
// State
const [isLocked, setIsLocked] = React.useState<boolean>(() =>
Boolean(application?.getAppState().locked)
)
const [isLocked, setIsLocked] = React.useState<boolean>(() => Boolean(application?.getAppState().locked))
useEffect(() => {
let isMounted = true
@@ -127,11 +125,9 @@ export const useHasEditor = () => {
const [hasEditor, setHasEditor] = React.useState<boolean>(false)
useEffect(() => {
const removeEditorObserver = application?.editorGroup.addActiveControllerChangeObserver(
newEditor => {
setHasEditor(Boolean(newEditor))
}
)
const removeEditorObserver = application?.editorGroup.addActiveControllerChangeObserver(newEditor => {
setHasEditor(Boolean(newEditor))
})
return removeEditorObserver
}, [application])
@@ -208,10 +204,7 @@ export const useSyncStatus = () => {
const unsubscribeAppEvents = application?.addEventObserver(async eventName => {
if (eventName === ApplicationEvent.LocalDataIncrementalLoad) {
updateLocalDataStatus()
} else if (
eventName === ApplicationEvent.SyncStatusChanged ||
eventName === ApplicationEvent.FailedSync
) {
} else if (eventName === ApplicationEvent.SyncStatusChanged || eventName === ApplicationEvent.FailedSync) {
updateSyncStatus()
} else if (eventName === ApplicationEvent.LocalDataLoaded) {
setDecrypting(false)
@@ -226,13 +219,9 @@ export const useSyncStatus = () => {
setLoading(false)
updateSyncStatus()
} else if (eventName === ApplicationEvent.LocalDatabaseReadError) {
void application!.alertService!.alert(
'Unable to load local storage. Please restart the app and try again.'
)
void application!.alertService!.alert('Unable to load local storage. Please restart the app and try again.')
} else if (eventName === ApplicationEvent.LocalDatabaseWriteError) {
void application!.alertService!.alert(
'Unable to write to local storage. Please restart the app and try again.'
)
void application!.alertService!.alert('Unable to write to local storage. Please restart the app and try again.')
} else if (eventName === ApplicationEvent.SignedIn) {
setLoading(true)
}
@@ -245,12 +234,7 @@ export const useSyncStatus = () => {
setRefreshing(true)
}
return [loading, decrypting, refreshing, startRefreshing] as [
boolean,
boolean,
boolean,
() => void
]
return [loading, decrypting, refreshing, startRefreshing] as [boolean, boolean, boolean, () => void]
}
export const useDeleteNoteWithPrivileges = (
@@ -266,12 +250,7 @@ export const useDeleteNoteWithPrivileges = (
const title = 'Move to Trash'
const message = 'Are you sure you want to move this note to the trash?'
const confirmed = await application?.alertService?.confirm(
message,
title,
'Confirm',
ButtonType.Danger
)
const confirmed = await application?.alertService?.confirm(message, title, 'Confirm', ButtonType.Danger)
if (confirmed) {
onTrashCallback()
}
@@ -286,13 +265,7 @@ export const useDeleteNoteWithPrivileges = (
)
return
}
const confirmed = await application?.alertService?.confirm(
message,
title,
'Delete',
ButtonType.Danger,
'Cancel'
)
const confirmed = await application?.alertService?.confirm(message, title, 'Delete', ButtonType.Danger, 'Cancel')
if (confirmed) {
onDeleteCallback()
}
@@ -358,18 +331,11 @@ export const useProtectionSessionExpiry = () => {
}, [application])
// State
const [protectionsDisabledUntil, setProtectionsDisabledUntil] = React.useState(
getProtectionsDisabledUntil()
)
const [protectionsDisabledUntil, setProtectionsDisabledUntil] = React.useState(getProtectionsDisabledUntil())
useEffect(() => {
const removeProtectionLengthSubscriber = application?.addEventObserver(async event => {
if (
[
ApplicationEvent.UnprotectedSessionBegan,
ApplicationEvent.UnprotectedSessionExpired,
].includes(event)
) {
if ([ApplicationEvent.UnprotectedSessionBegan, ApplicationEvent.UnprotectedSessionExpired].includes(event)) {
setProtectionsDisabledUntil(getProtectionsDisabledUntil())
}
})
@@ -381,10 +347,7 @@ export const useProtectionSessionExpiry = () => {
return [protectionsDisabledUntil]
}
export const useChangeNoteChecks = (
note: SNNote | undefined,
editor: NoteViewController | undefined = undefined
) => {
export const useChangeNoteChecks = (note: SNNote | undefined, editor: NoteViewController | undefined = undefined) => {
// Context
const application = useSafeApplicationContext()
@@ -410,10 +373,7 @@ export const useChangeNoteChecks = (
return [canChangeNote]
}
export const useChangeNote = (
note: SNNote | undefined,
editor: NoteViewController | undefined = undefined
) => {
export const useChangeNote = (note: SNNote | undefined, editor: NoteViewController | undefined = undefined) => {
const application = React.useContext(ApplicationContext)
const [canChangeNote] = useChangeNoteChecks(note, editor)

View File

@@ -1,8 +1,7 @@
import { ChallengePrompt, ChallengeValidation, ChallengeValue } from '@standardnotes/snjs'
export const isInActiveState = (state: AuthenticationValueStateType) =>
state !== AuthenticationValueStateType.WaitingInput &&
state !== AuthenticationValueStateType.Success
state !== AuthenticationValueStateType.WaitingInput && state !== AuthenticationValueStateType.Success
export enum AuthenticationValueStateType {
WaitingTurn = 0,
@@ -29,10 +28,7 @@ type SetChallengeValue = {
}
type Action = SetChallengeValueState | SetChallengeValue
export const authenticationReducer = (
state: ChallengeValueState,
action: Action
): ChallengeValueState => {
export const authenticationReducer = (state: ChallengeValueState, action: Action): ChallengeValueState => {
switch (action.type) {
case 'setState': {
return {
@@ -68,10 +64,7 @@ export const findIndexInObject = (
return Object.keys(map).indexOf(id)
}
export const getChallengePromptTitle = (
prompt: ChallengePrompt,
state: AuthenticationValueStateType
) => {
export const getChallengePromptTitle = (prompt: ChallengePrompt, state: AuthenticationValueStateType) => {
const title = prompt.title
switch (state) {
case AuthenticationValueStateType.WaitingTurn:
@@ -83,10 +76,7 @@ export const getChallengePromptTitle = (
}
}
export const getLabelForStateAndType = (
validation: ChallengeValidation,
state: AuthenticationValueStateType
) => {
export const getLabelForStateAndType = (validation: ChallengeValidation, state: AuthenticationValueStateType) => {
switch (validation) {
case ChallengeValidation.Biometric: {
switch (state) {

View File

@@ -126,9 +126,7 @@ export const ComponentView = ({
)
if (confirmed) {
void application
?.getLocalPreferences()
.setUserPrefValue(PrefKey.DoNotShowAgainUnsupportedEditors, true)
void application?.getLocalPreferences().setUserPrefValue(PrefKey.DoNotShowAgainUnsupportedEditors, true)
}
}
}
@@ -275,8 +273,8 @@ export const ComponentView = ({
<LockedContainer>
<StyledIcon />
<LockedText>
Subscription expired. Editors are in a read-only state. To edit immediately, please
switch to the Plain Editor.
Subscription expired. Editors are in a read-only state. To edit immediately, please switch to the Plain
Editor.
</LockedText>
</LockedContainer>
)}
@@ -308,9 +306,7 @@ export const ComponentView = ({
setSupportMultipleWindows={false}
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
cacheEnabled={true}
autoManageStatusBarEnabled={
false /* To prevent StatusBar from changing colors when focusing */
}
autoManageStatusBarEnabled={false /* To prevent StatusBar from changing colors when focusing */}
injectedJavaScript={defaultInjectedJavaScript()}
onContentProcessDidTerminate={() => onLoadErrorHandler()}
/>

View File

@@ -53,8 +53,7 @@ type State = {
componentViewer?: ComponentViewer
}
const EditingIsDisabledText =
'This note has editing disabled. Please enable editing on this note to make changes.'
const EditingIsDisabledText = 'This note has editing disabled. Please enable editing on this note to make changes.'
export class Compose extends React.Component<Record<string, unknown>, State> {
static override contextType = ApplicationContext
@@ -71,10 +70,7 @@ export class Compose extends React.Component<Record<string, unknown>, State> {
removeAppEventObserver?: () => void
removeComponentHandler?: () => void
constructor(
props: Record<string, unknown>,
context: React.ContextType<typeof ApplicationContext>
) {
constructor(props: Record<string, unknown>, context: React.ContextType<typeof ApplicationContext>) {
super(props)
this.context = context
const initialEditor = context?.editorGroup.activeNoteViewController
@@ -90,52 +86,46 @@ export class Compose extends React.Component<Record<string, unknown>, State> {
}
override componentDidMount() {
this.removeNoteInnerValueObserver = this.editor?.addNoteInnerValueChangeObserver(
(note, source) => {
if (isPayloadSourceRetrieved(source!)) {
this.setState({
title: note.title,
text: note.text,
})
}
this.removeNoteInnerValueObserver = this.editor?.addNoteInnerValueChangeObserver((note, source) => {
if (isPayloadSourceRetrieved(source!)) {
this.setState({
title: note.title,
text: note.text,
})
}
const isTemplateNoteInsertedToBeInteractableWithEditor =
source === PayloadEmitSource.LocalInserted && note.dirty
if (isTemplateNoteInsertedToBeInteractableWithEditor) {
return
}
const isTemplateNoteInsertedToBeInteractableWithEditor = source === PayloadEmitSource.LocalInserted && note.dirty
if (isTemplateNoteInsertedToBeInteractableWithEditor) {
return
}
if (note.lastSyncBegan || note.dirty) {
if (note.lastSyncEnd) {
if (note.dirty || note.lastSyncBegan!.getTime() > note.lastSyncEnd.getTime()) {
this.showSavingStatus()
} else if (
this.context?.getStatusManager().hasMessage(SCREEN_COMPOSE) &&
note.lastSyncEnd.getTime() > note.lastSyncBegan!.getTime()
) {
this.showAllChangesSavedStatus()
}
} else {
if (note.lastSyncBegan || note.dirty) {
if (note.lastSyncEnd) {
if (note.dirty || note.lastSyncBegan!.getTime() > note.lastSyncEnd.getTime()) {
this.showSavingStatus()
} else if (
this.context?.getStatusManager().hasMessage(SCREEN_COMPOSE) &&
note.lastSyncEnd.getTime() > note.lastSyncBegan!.getTime()
) {
this.showAllChangesSavedStatus()
}
} else {
this.showSavingStatus()
}
}
)
})
this.removeStreamComponents = this.context?.streamItems(
ContentType.Component,
async ({ source }) => {
if (isPayloadSourceInternalChange(source)) {
return
}
if (!this.note) {
return
}
void this.reloadComponentEditorState()
this.removeStreamComponents = this.context?.streamItems(ContentType.Component, async ({ source }) => {
if (isPayloadSourceInternalChange(source)) {
return
}
)
if (!this.note) {
return
}
void this.reloadComponentEditorState()
})
this.removeAppEventObserver = this.context?.addEventObserver(async eventName => {
if (eventName === ApplicationEvent.CompletedFullSync) {
@@ -349,9 +339,7 @@ export class Compose extends React.Component<Record<string, unknown>, State> {
}
if (!this.context?.items.findItem(note!.uuid)) {
void this.context?.alertService!.alert(
'Attempting to save this note has failed. The note cannot be found.'
)
void this.context?.alertService!.alert('Attempting to save this note has failed. The note cannot be found.')
return
}
@@ -479,10 +467,7 @@ export class Compose extends React.Component<Record<string, unknown>, State> {
override render() {
const shouldDisplayEditor =
this.state.componentViewer &&
Boolean(this.note) &&
!this.note?.prefersPlainEditor &&
!this.state.webViewError
this.state.componentViewer && Boolean(this.note) && !this.note?.prefersPlainEditor && !this.state.webViewError
return (
<Container>
@@ -491,24 +476,15 @@ export class Compose extends React.Component<Record<string, unknown>, State> {
<>
{this.noteLocked && (
<LockedContainer>
<Icon
name={ThemeService.nameForIcon(ICON_LOCK)}
size={16}
color={theme.stylekitBackgroundColor}
/>
<Icon name={ThemeService.nameForIcon(ICON_LOCK)} size={16} color={theme.stylekitBackgroundColor} />
<LockedText>Note Editing Disabled</LockedText>
</LockedContainer>
)}
{this.state.webViewError && (
<LockedContainer>
<Icon
name={ThemeService.nameForIcon(ICON_ALERT)}
size={16}
color={theme.stylekitBackgroundColor}
/>
<Icon name={ThemeService.nameForIcon(ICON_ALERT)} size={16} color={theme.stylekitBackgroundColor} />
<LockedText>
Unable to load {this.state.componentViewer?.component.name} {' '}
{this.getErrorText()}
Unable to load {this.state.componentViewer?.component.name} {this.getErrorText()}
</LockedText>
<WebViewReloadButton
onPress={() => {
@@ -535,8 +511,7 @@ export class Compose extends React.Component<Record<string, unknown>, State> {
autoCapitalize={'sentences'}
/>
{(this.state.downloadingEditor ||
(this.state.loadingWebview &&
themeService?.isLikelyUsingDarkColorTheme())) && (
(this.state.loadingWebview && themeService?.isLikelyUsingDarkColorTheme())) && (
<LoadingWebViewContainer locked={this.noteLocked}>
<LoadingText>
{'Loading '}
@@ -557,22 +532,20 @@ export class Compose extends React.Component<Record<string, unknown>, State> {
/>
)}
{!shouldDisplayEditor &&
!isNullOrUndefined(this.note) &&
Platform.OS === 'android' && (
<TextContainer>
<StyledTextView
testID="noteContentField"
ref={this.editorViewRef}
autoFocus={false}
value={this.state.text}
selectionColor={lighten(theme.stylekitInfoColor, 0.35)}
handlesColor={theme.stylekitInfoColor}
onChangeText={this.onContentChange}
errorState={false}
/>
</TextContainer>
)}
{!shouldDisplayEditor && !isNullOrUndefined(this.note) && Platform.OS === 'android' && (
<TextContainer>
<StyledTextView
testID="noteContentField"
ref={this.editorViewRef}
autoFocus={false}
value={this.state.text}
selectionColor={lighten(theme.stylekitInfoColor, 0.35)}
handlesColor={theme.stylekitInfoColor}
onChangeText={this.onContentChange}
errorState={false}
/>
</TextContainer>
)}
{/* Empty wrapping view fixes native textview crashing */}
{!shouldDisplayEditor && Platform.OS === 'ios' && (
<View key={this.note?.uuid}>

View File

@@ -54,13 +54,7 @@ export const FileInputModal: FC<Props> = props => {
/>
</SectionedTableCell>
<ButtonCell
maxHeight={45}
disabled={fileName.length === 0}
title={'Save'}
bold
onPress={onSubmit}
/>
<ButtonCell maxHeight={45} disabled={fileName.length === 0} title={'Save'} bold onPress={onSubmit} />
</TableSection>
</Container>
)

View File

@@ -85,13 +85,7 @@ export const TagInputModal = (props: Props) => {
/>
</SectionedTableCell>
<ButtonCell
maxHeight={45}
disabled={text.length === 0}
title={'Save'}
bold
onPress={onSubmit}
/>
<ButtonCell maxHeight={45} disabled={text.length === 0} title={'Save'} bold onPress={onSubmit} />
</TableSection>
</Container>
)

View File

@@ -78,8 +78,7 @@ export const ManageSessions: React.FC = () => {
const theme = useContext(ThemeContext)
const insets = useSafeAreaInsets()
const [sessions, getSessions, refreshSessions, refreshing, revokeSession, errorMessage] =
useSessions()
const [sessions, getSessions, refreshSessions, refreshing, revokeSession, errorMessage] = useSessions()
const onItemPress = (item: RemoteSession) => {
showActionSheet({

View File

@@ -1,7 +1,4 @@
import {
Props as TableCellProps,
SectionedTableCellTouchableHighlight,
} from '@Root/Components/SectionedTableCell'
import { Props as TableCellProps, SectionedTableCellTouchableHighlight } from '@Root/Components/SectionedTableCell'
import React from 'react'
import styled, { css } from 'styled-components/native'

View File

@@ -22,9 +22,7 @@ export const NoteHistory = (props: Props) => {
const themeService = useContext(ThemeServiceContext)
// State
const [note] = useState<SNNote>(
() => application?.items.findItem(props.route.params.noteUuid) as SNNote
)
const [note] = useState<SNNote>(() => application?.items.findItem(props.route.params.noteUuid) as SNNote)
const [routes] = React.useState([
{ key: 'session', title: 'Session' },
{ key: 'remote', title: 'Remote' },

View File

@@ -1,7 +1,4 @@
import {
Props as TableCellProps,
SectionedTableCellTouchableHighlight,
} from '@Root/Components/SectionedTableCell'
import { Props as TableCellProps, SectionedTableCellTouchableHighlight } from '@Root/Components/SectionedTableCell'
import React from 'react'
import styled, { css } from 'styled-components/native'

View File

@@ -9,13 +9,7 @@ import { ThemeService } from '@Style/ThemeService'
import React, { useCallback, useContext, useLayoutEffect } from 'react'
import { LogBox } from 'react-native'
import { HeaderButtons, Item } from 'react-navigation-header-buttons'
import {
Container,
StyledTextView,
TextContainer,
Title,
TitleContainer,
} from './NoteHistoryPreview.styled'
import { Container, StyledTextView, TextContainer, Title, TitleContainer } from './NoteHistoryPreview.styled'
LogBox.ignoreLogs(['Non-serializable values were found in the navigation state'])
@@ -40,9 +34,7 @@ export const NoteHistoryPreview = ({
if (asCopy) {
await application?.mutator.duplicateItem(originalNote!, {
...revision.payload.content,
title: revision.payload.content.title
? revision.payload.content.title + ' (copy)'
: undefined,
title: revision.payload.content.title ? revision.payload.content.title + ' (copy)' : undefined,
})
// eslint-disable-next-line @typescript-eslint/ban-ts-comment

View File

@@ -43,11 +43,7 @@ export const RemoteHistory: React.FC<Props> = ({ note, onPress }) => {
async (item: RevisionListEntry) => {
const remoteRevision = await application?.historyManager!.fetchRemoteRevision(note, item)
if (remoteRevision) {
onPress(
item.uuid,
remoteRevision as NoteHistoryEntry,
new Date(item.updated_at).toLocaleString()
)
onPress(item.uuid, remoteRevision as NoteHistoryEntry, new Date(item.updated_at).toLocaleString())
} else {
void application?.alertService!.alert(
'The remote revision could not be loaded. Please try again later.',
@@ -60,19 +56,10 @@ export const RemoteHistory: React.FC<Props> = ({ note, onPress }) => {
)
const renderItem: ListRenderItem<RevisionListEntry> | null | undefined = ({ item }) => {
return (
<NoteHistoryCell
onPress={() => onItemPress(item)}
title={new Date(item.updated_at).toLocaleString()}
/>
)
return <NoteHistoryCell onPress={() => onItemPress(item)} title={new Date(item.updated_at).toLocaleString()} />
}
if (
fetchingRemoteHistory ||
!remoteHistoryList ||
(remoteHistoryList && remoteHistoryList.length === 0)
) {
if (fetchingRemoteHistory || !remoteHistoryList || (remoteHistoryList && remoteHistoryList.length === 0)) {
const placeholderText = fetchingRemoteHistory ? 'Loading entries...' : 'No entries.'
return (
<LoadingContainer>

View File

@@ -1,18 +1,8 @@
import {
useChangeNote,
useDeleteNoteWithPrivileges,
useProtectOrUnprotectNote,
} from '@Lib/SnjsHelperHooks'
import { useChangeNote, useDeleteNoteWithPrivileges, useProtectOrUnprotectNote } from '@Lib/SnjsHelperHooks'
import { ApplicationContext } from '@Root/ApplicationContext'
import { SnIcon } from '@Root/Components/SnIcon'
import { NoteCellIconFlags } from '@Root/Screens/Notes/NoteCellIconFlags'
import {
CollectionSort,
CollectionSortProperty,
IconType,
isNullOrUndefined,
SNNote,
} from '@standardnotes/snjs'
import { CollectionSort, CollectionSortProperty, IconType, isNullOrUndefined, SNNote } from '@standardnotes/snjs'
import { CustomActionSheetOption, useCustomActionSheet } from '@Style/CustomActionSheet'
import { getTintColorForEditor } from '@Style/Utils'
import React, { useContext, useRef, useState } from 'react'
@@ -194,9 +184,10 @@ export const NoteCell = ({
const showDetails = !hideDates || note.protected
const editorForNote = application?.componentManager.editorForNote(note)
const [icon, tint] = application?.iconsController.getIconAndTintForEditor(
editorForNote?.identifier
) as [IconType, number]
const [icon, tint] = application?.iconsController.getIconAndTintForEditor(editorForNote?.identifier) as [
IconType,
number
]
return (
<TouchableContainer
@@ -207,19 +198,13 @@ export const NoteCell = ({
delayPressIn={150}
>
<Container ref={elementRef as any} selected={highlight} distance={padding}>
{!hideEditorIcon && (
<SnIcon type={icon} fill={getTintColorForEditor(theme, tint)} style={styles.editorIcon} />
)}
{!hideEditorIcon && <SnIcon type={icon} fill={getTintColorForEditor(theme, tint)} style={styles.editorIcon} />}
<NoteDataContainer distance={padding}>
<NoteCellFlags note={note} highlight={highlight} />
<FlexContainer>
<NoteContentsContainer>
{note.title.length > 0 ? (
<TitleText selected={highlight}>{note.title}</TitleText>
) : (
<View />
)}
{note.title.length > 0 ? <TitleText selected={highlight}>{note.title}</TitleText> : <View />}
{hasPlainPreview && showPreview && (
<NoteText selected={highlight} numberOfLines={2}>
{note.preview_plain}
@@ -245,9 +230,7 @@ export const NoteCell = ({
)}
{!hideDates && (
<Text>
{sortType === CollectionSort.UpdatedAt
? 'Modified ' + note.updatedAtString
: note.createdAtString}
{sortType === CollectionSort.UpdatedAt ? 'Modified ' + note.updatedAtString : note.createdAtString}
</Text>
)}
</DetailsText>

View File

@@ -7,15 +7,7 @@ import { Chip } from '@Root/Components/Chip'
import { SearchBar } from '@Root/Components/SearchBar'
import { SCREEN_NOTES } from '@Root/Screens/screens'
import { CollectionSortProperty, SNNote } from '@standardnotes/snjs'
import React, {
Dispatch,
SetStateAction,
useCallback,
useContext,
useEffect,
useRef,
useState,
} from 'react'
import React, { Dispatch, SetStateAction, useCallback, useContext, useEffect, useRef, useState } from 'react'
import { Animated, FlatList, ListRenderItem, RefreshControl } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import IosSearchBar from 'react-native-search-bar'
@@ -90,13 +82,11 @@ export const NoteList = (props: Props) => {
})
useEffect(() => {
const unsubscribeStateEventObserver = application
?.getAppState()
.addStateEventObserver(state => {
if (state === AppStateEventType.DrawerOpen) {
dismissKeyboard()
}
})
const unsubscribeStateEventObserver = application?.getAppState().addStateEventObserver(state => {
if (state === AppStateEventType.DrawerOpen) {
dismissKeyboard()
}
})
return unsubscribeStateEventObserver
}, [application])
@@ -109,13 +99,11 @@ export const NoteList = (props: Props) => {
}, [noteListScrolled, props.notes])
useEffect(() => {
const unsubscribeTagChangedEventObserver = application
?.getAppState()
.addStateChangeObserver(event => {
if (event === AppStateType.TagChanged) {
scrollListToTop()
}
})
const unsubscribeTagChangedEventObserver = application?.getAppState().addStateChangeObserver(event => {
if (event === AppStateType.TagChanged) {
scrollListToTop()
}
})
return unsubscribeTagChangedEventObserver
}, [application, scrollListToTop])
@@ -232,10 +220,7 @@ export const NoteList = (props: Props) => {
ref={noteListRef}
style={styles.list}
keyExtractor={item => item.uuid}
contentContainerStyle={[
{ paddingBottom: insets.bottom },
props.notes.length > 0 ? {} : { height: '100%' },
]}
contentContainerStyle={[{ paddingBottom: insets.bottom }, props.notes.length > 0 ? {} : { height: '100%' }]}
initialNumToRender={6}
windowSize={6}
maxToRenderPerBatch={6}
@@ -260,9 +245,7 @@ export const NoteList = (props: Props) => {
data={props.notes}
renderItem={renderItem}
extraData={signedIn}
ListHeaderComponent={() => (
<HeaderContainer>{!signedIn && <OfflineBanner />}</HeaderContainer>
)}
ListHeaderComponent={() => <HeaderContainer>{!signedIn && <OfflineBanner />}</HeaderContainer>}
onScroll={onScroll}
/>
</Container>

View File

@@ -77,9 +77,7 @@ export const Notes = React.memo(
const [shouldFocusSearch, setShouldFocusSearch] = useState<boolean>(false)
const haveDisplayOptions = useRef(false)
const protectionsEnabled = useRef(
application.hasProtectionSources() && !application.hasUnprotectedAccessSession()
)
const protectionsEnabled = useRef(application.hasProtectionSources() && !application.hasUnprotectedAccessSession())
const reloadTitle = useCallback(
(newNotes?: SNNote[], newFilter?: string) => {
@@ -90,8 +88,7 @@ export const Notes = React.memo(
if (newNotes && (newFilter ?? searchText).length > 0) {
const resultCount = newNotes.length
title =
resultCount === 1 ? `${resultCount} search result` : `${resultCount} search results`
title = resultCount === 1 ? `${resultCount} search result` : `${resultCount} search results`
} else if (selectedTag) {
title = selectedTag.title
if (selectedTag instanceof SNTag && selectedTag.parentId) {
@@ -164,13 +161,11 @@ export const Notes = React.memo(
useEffect(() => {
let mounted = true
const removeEditorObserver = application.editorGroup.addActiveControllerChangeObserver(
activeEditor => {
if (mounted) {
setSelectedNoteId(activeEditor?.note?.uuid)
}
const removeEditorObserver = application.editorGroup.addActiveControllerChangeObserver(activeEditor => {
if (mounted) {
setSelectedNoteId(activeEditor?.note?.uuid)
}
)
})
return () => {
mounted = false
@@ -264,8 +259,7 @@ export const Notes = React.memo(
}, [includeTrashedNotes, reloadNotesDisplayOptions])
const reloadSearchOptions = useCallback(() => {
const protections =
application.hasProtectionSources() && !application.hasUnprotectedAccessSession()
const protections = application.hasProtectionSources() && !application.hasUnprotectedAccessSession()
if (protections !== protectionsEnabled.current) {
protectionsEnabled.current = !!protections
@@ -281,10 +275,8 @@ export const Notes = React.memo(
},
]
const isArchiveView =
selectedTag instanceof SmartView && selectedTag.uuid === SystemViewId.ArchivedNotes
const isTrashView =
selectedTag instanceof SmartView && selectedTag.uuid === SystemViewId.TrashedNotes
const isArchiveView = selectedTag instanceof SmartView && selectedTag.uuid === SystemViewId.ArchivedNotes
const isTrashView = selectedTag instanceof SmartView && selectedTag.uuid === SystemViewId.TrashedNotes
if (!isArchiveView && !isTrashView) {
setSearchOptions([
...options,
@@ -312,10 +304,7 @@ export const Notes = React.memo(
toggleIncludeTrashed,
])
const getFirstSelectableNote = useCallback(
(newNotes: SNNote[]) => newNotes.find(note => !note.protected),
[]
)
const getFirstSelectableNote = useCallback((newNotes: SNNote[]) => newNotes.find(note => !note.protected), [])
const selectFirstNote = useCallback(
(newNotes: SNNote[]) => {
@@ -383,20 +372,11 @@ export const Notes = React.memo(
}
}
},
[
application,
reloadNotesDisplayOptions,
reloadSearchOptions,
reloadTitle,
selectFirstNote,
selectNextOrCreateNew,
]
[application, reloadNotesDisplayOptions, reloadSearchOptions, reloadTitle, selectFirstNote, selectNextOrCreateNew]
)
const onNoteCreate = useCallback(async () => {
const title = application.getAppState().isTabletDevice
? `Note ${notes.length + 1}`
: undefined
const title = application.getAppState().isTabletDevice ? `Note ${notes.length + 1}` : undefined
await application.getAppState().createEditor(title)
openCompose(true)
reloadNotes(true)
@@ -422,21 +402,13 @@ export const Notes = React.memo(
}, [application, reloadNotes, reloadNotesDisplayOptions])
const reloadPreferences = useCallback(async () => {
const newSortBy = application
.getLocalPreferences()
.getValue(PrefKey.SortNotesBy, CollectionSort.CreatedAt)
const newSortBy = application.getLocalPreferences().getValue(PrefKey.SortNotesBy, CollectionSort.CreatedAt)
let displayOptionsChanged = false
const newSortReverse = application
.getLocalPreferences()
.getValue(PrefKey.SortNotesReverse, false)
const newHidePreview = application
.getLocalPreferences()
.getValue(PrefKey.NotesHideNotePreview, false)
const newSortReverse = application.getLocalPreferences().getValue(PrefKey.SortNotesReverse, false)
const newHidePreview = application.getLocalPreferences().getValue(PrefKey.NotesHideNotePreview, false)
const newHideDate = application.getLocalPreferences().getValue(PrefKey.NotesHideDate, false)
const newHideEditorIcon = application
.getLocalPreferences()
.getValue(PrefKey.NotesHideEditorIcon, false)
const newHideEditorIcon = application.getLocalPreferences().getValue(PrefKey.NotesHideEditorIcon, false)
if (sortBy !== newSortBy) {
setSortBy(newSortBy)
@@ -494,30 +466,22 @@ export const Notes = React.memo(
useFocusEffect(
useCallback(() => {
void reloadPreferences()
const removeAppStateChangeHandler = application
.getAppState()
.addStateChangeObserver(state => {
if (state === AppStateType.TagChanged) {
reloadNotesDisplayOptions()
reloadNotes(true, true)
}
if (state === AppStateType.PreferencesChanged) {
void reloadPreferences()
}
})
const removeAppStateChangeHandler = application.getAppState().addStateChangeObserver(state => {
if (state === AppStateType.TagChanged) {
reloadNotesDisplayOptions()
reloadNotes(true, true)
}
if (state === AppStateType.PreferencesChanged) {
void reloadPreferences()
}
})
const removeStreams = streamNotesAndTags()
return () => {
removeAppStateChangeHandler()
removeStreams()
}
}, [
application,
reloadNotes,
reloadNotesDisplayOptions,
reloadPreferences,
streamNotesAndTags,
])
}, [application, reloadNotes, reloadNotesDisplayOptions, reloadPreferences, streamNotesAndTags])
)
return (
@@ -551,9 +515,7 @@ export const Notes = React.memo(
onClickAction={onNoteCreate}
visible={true}
size={30}
iconTextComponent={
<StyledIcon testID="newNoteButton" name={ThemeService.nameForIcon(ICON_ADD)} />
}
iconTextComponent={<StyledIcon testID="newNoteButton" name={ThemeService.nameForIcon(ICON_ADD)} />}
/>
</>
)

View File

@@ -38,13 +38,4 @@ const SubText = styled.Text`
color: ${props => props.theme.stylekitNeutralColor};
`
export {
Touchable,
Container,
CenterContainer,
UserIcon,
ForwardIcon,
TextContainer,
BoldText,
SubText,
}
export { Touchable, Container, CenterContainer, UserIcon, ForwardIcon, TextContainer, BoldText, SubText }

View File

@@ -10,13 +10,7 @@ import Icon from 'react-native-vector-icons/Ionicons'
import { ThemeContext } from 'styled-components'
import { Compose } from './Compose/Compose'
import { Notes } from './Notes/Notes'
import {
ComposeContainer,
Container,
ExpandTouchable,
iconNames,
NotesContainer,
} from './Root.styled'
import { ComposeContainer, Container, ExpandTouchable, iconNames, NotesContainer } from './Root.styled'
export const Root = () => {
// Context
@@ -62,11 +56,9 @@ export const Root = () => {
}
}
})
const removeNoteObserver = application?.editorGroup.addActiveControllerChangeObserver(
activeController => {
setActiveNoteId(activeController?.note.uuid)
}
)
const removeNoteObserver = application?.editorGroup.addActiveControllerChangeObserver(activeController => {
setActiveNoteId(activeController?.note.uuid)
})
return () => {
if (removeApplicationStateEventHandler) {
removeApplicationStateEventHandler()
@@ -112,8 +104,7 @@ export const Root = () => {
setNoteListCollapsed(value => !value)
}
const collapseIconBottomPosition =
(keyboardHeight ?? 0) > (height ?? 0) / 2 ? (keyboardHeight ?? 0) + 40 : '50%'
const collapseIconBottomPosition = (keyboardHeight ?? 0) > (height ?? 0) / 2 ? (keyboardHeight ?? 0) + 40 : '50%'
if (isLocked) {
return null
@@ -128,11 +119,7 @@ export const Root = () => {
<ComposeContainer>
<Compose key={activeNoteId} />
<ExpandTouchable style={{ bottom: collapseIconBottomPosition }} onPress={toggleNoteList}>
<Icon
name={collapseIconName}
size={24}
color={hexToRGBA(theme.stylekitInfoColor, 0.85)}
/>
<Icon name={collapseIconName} size={24} color={hexToRGBA(theme.stylekitInfoColor, 0.85)} />
</ExpandTouchable>
</ComposeContainer>
)}

View File

@@ -56,11 +56,7 @@ export const AuthSection = (props: Props) => {
const validate = () => {
if (!email) {
void application?.alertService?.alert(
'Please enter a valid email address.',
'Missing Email',
'OK'
)
void application?.alertService?.alert('Please enter a valid email address.', 'Missing Email', 'OK')
return false
}
@@ -125,8 +121,8 @@ export const AuthSection = (props: Props) => {
<SectionHeader title={'Confirm Password'} />
<RegistrationDescription>
Due to the nature of our encryption, Standard Notes cannot offer password reset
functionality. If you forget your password, you will permanently lose access to your data.
Due to the nature of our encryption, Standard Notes cannot offer password reset functionality. If you forget
your password, you will permanently lose access to your data.
</RegistrationDescription>
<SectionedTableCell first textInputCell>
@@ -241,11 +237,7 @@ export const AuthSection = (props: Props) => {
/>
{!showAdvanced && (
<ButtonCell
testID="advancedOptionsButton"
title="Advanced Options"
onPress={() => setShowAdvanced(true)}
/>
<ButtonCell testID="advancedOptionsButton" title="Advanced Options" onPress={() => setShowAdvanced(true)} />
)}
</TableSection>
)

View File

@@ -8,9 +8,9 @@ import { Platform, Share } from 'react-native'
import { ContentContainer, Label } from './CompanySection.styled'
const URLS = {
feedback: `mailto:help@standardnotes.com?subject=${
Platform.OS === 'android' ? 'Android' : 'iOS'
} app feedback (v${ApplicationState.version})`,
feedback: `mailto:help@standardnotes.com?subject=${Platform.OS === 'android' ? 'Android' : 'iOS'} app feedback (v${
ApplicationState.version
})`,
learn_more: 'https://standardnotes.com',
privacy: 'https://standardnotes.com/privacy',
help: 'https://standardnotes.com/help',
@@ -47,8 +47,7 @@ export const CompanySection = (props: Props) => {
const shareWithFriend = () => {
const title = 'Standard Notes'
let message =
'Check out Standard Notes, a free, open-source, and completely encrypted notes app.'
let message = 'Check out Standard Notes, a free, open-source, and completely encrypted notes app.'
const url = 'https://standardnotes.com'
// Android ignores url. iOS ignores title.
if (Platform.OS === 'android') {
@@ -80,19 +79,11 @@ export const CompanySection = (props: Props) => {
<Label>Share Standard Notes with a friend.</Label>
</ButtonCell>
<ButtonCell
leftAligned={true}
title="Learn About Standard Notes"
onPress={() => openUrl('learn_more')}
>
<ButtonCell leftAligned={true} title="Learn About Standard Notes" onPress={() => openUrl('learn_more')}>
<Label>https://standardnotes.com</Label>
</ButtonCell>
<ButtonCell
leftAligned={true}
title="Our Privacy Manifesto"
onPress={() => openUrl('privacy')}
>
<ButtonCell leftAligned={true} title="Our Privacy Manifesto" onPress={() => openUrl('privacy')}>
<Label>https://standardnotes.com/privacy</Label>
</ButtonCell>

View File

@@ -106,9 +106,7 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
return RNFS.readFile(fileUri)
.then(result => JSON.parse(result))
.catch(() => {
void application!.alertService!.alert(
'Unable to open file. Ensure it is a proper JSON file and try again.'
)
void application!.alertService!.alert('Unable to open file. Ensure it is a proper JSON file and try again.')
})
}
@@ -134,8 +132,7 @@ export const OptionsSection = ({ title, encryptionAvailable }: Props) => {
type: [DocumentPicker.types.plainText],
})
const selectedFile = selectedFiles[0]
const selectedFileURI =
Platform.OS === 'ios' ? decodeURIComponent(selectedFile.uri) : selectedFile.uri
const selectedFileURI = Platform.OS === 'ios' ? decodeURIComponent(selectedFile.uri) : selectedFile.uri
const data = await readImportFile(selectedFileURI)
if (!data) {
return

View File

@@ -45,9 +45,7 @@ export const PreferencesSection = () => {
setSortBy(key)
}
const toggleNotesPreviewHidden = () => {
void application
?.getLocalPreferences()
.setUserPrefValue(PrefKey.NotesHideNotePreview, !hidePreviews)
void application?.getLocalPreferences().setUserPrefValue(PrefKey.NotesHideNotePreview, !hidePreviews)
setHidePreviews(value => !value)
}
const toggleNotesDateHidden = () => {
@@ -55,9 +53,7 @@ export const PreferencesSection = () => {
setHideDates(value => !value)
}
const toggleNotesEditorIconHidden = () => {
void application
?.getLocalPreferences()
.setUserPrefValue(PrefKey.NotesHideEditorIcon, !hideEditorIcon)
void application?.getLocalPreferences().setUserPrefValue(PrefKey.NotesHideEditorIcon, !hideEditorIcon)
setHideEditorIcon(value => !value)
}

View File

@@ -4,13 +4,7 @@ import { SectionHeader } from '@Root/Components/SectionHeader'
import { TableSection } from '@Root/Components/TableSection'
import { useSafeApplicationContext } from '@Root/Hooks/useSafeApplicationContext'
import React from 'react'
import {
BaseView,
StyledSectionedTableCell,
SubText,
Subtitle,
Title,
} from './ProtectionsSection.styled'
import { BaseView, StyledSectionedTableCell, SubText, Subtitle, Title } from './ProtectionsSection.styled'
type Props = {
title: string
@@ -23,9 +17,7 @@ export const ProtectionsSection = (props: Props) => {
// State
const [protectionsDisabledUntil] = useProtectionSessionExpiry()
const protectionsEnabledSubtitle = protectionsDisabledUntil
? `Disabled until ${protectionsDisabledUntil}`
: 'Enabled'
const protectionsEnabledSubtitle = protectionsDisabledUntil ? `Disabled until ${protectionsDisabledUntil}` : 'Enabled'
const protectionsEnabledSubtext =
'Actions like viewing protected notes, exporting decrypted backups, or revoking an active session, require additional authentication like entering your account password or application passcode.'
@@ -40,9 +32,7 @@ export const ProtectionsSection = (props: Props) => {
<StyledSectionedTableCell first>
<BaseView>
<Title>Status</Title>
<Subtitle>
{props.protectionsAvailable ? protectionsEnabledSubtitle : 'Disabled'}
</Subtitle>
<Subtitle>{props.protectionsAvailable ? protectionsEnabledSubtitle : 'Disabled'}</Subtitle>
</BaseView>
</StyledSectionedTableCell>
{props.protectionsAvailable && protectionsDisabledUntil && (

View File

@@ -26,9 +26,7 @@ export const SecuritySection = (props: Props) => {
const application = useContext(ApplicationContext)
// State
const [encryptionPolicy, setEncryptionPolicy] = useState(() =>
application?.getStorageEncryptionPolicy()
)
const [encryptionPolicy, setEncryptionPolicy] = useState(() => application?.getStorageEncryptionPolicy())
const [encryptionPolictChangeInProgress, setEncryptionPolictChangeInProgress] = useState(false)
const [hasScreenshotPrivacy, setHasScreenshotPrivacy] = useState<boolean | undefined>(false)
const [hasBiometrics, setHasBiometrics] = useState(false)
@@ -178,8 +176,7 @@ export const SecuritySection = (props: Props) => {
message =
'Are you sure you want to disable your local passcode? This will not affect your encryption status, as your data is currently being encrypted through your sync account keys.'
} else {
message =
'Are you sure you want to disable your local passcode? This will disable encryption on your data.'
message = 'Are you sure you want to disable your local passcode? This will disable encryption on your data.'
}
const confirmed = await application?.alertService?.confirm(

View File

@@ -20,12 +20,8 @@ export const Settings = (props: Props) => {
// State
const [hasPasscode, setHasPasscode] = useState(() => Boolean(application?.hasPasscode()))
const [protectionsAvailable, setProtectionsAvailable] = useState(
application?.hasProtectionSources()
)
const [encryptionAvailable, setEncryptionAvailable] = useState(() =>
application?.isEncryptionAvailable()
)
const [protectionsAvailable, setProtectionsAvailable] = useState(application?.hasProtectionSources())
const [encryptionAvailable, setEncryptionAvailable] = useState(() => application?.isEncryptionAvailable())
const updateProtectionsAvailable = useCallback(() => {
setProtectionsAvailable(application?.hasProtectionSources())

View File

@@ -1,11 +1,6 @@
import { SnIcon } from '@Root/Components/SnIcon'
import { useSafeApplicationContext } from '@Root/Hooks/useSafeApplicationContext'
import {
CantLoadActionsText,
CreateBlogContainer,
ListedItemRow,
styles,
} from '@Root/Screens/SideMenu/Listed.styled'
import { CantLoadActionsText, CreateBlogContainer, ListedItemRow, styles } from '@Root/Screens/SideMenu/Listed.styled'
import { SideMenuCell } from '@Root/Screens/SideMenu/SideMenuCell'
import { SideMenuOptionIconDescriptionType } from '@Root/Screens/SideMenu/SideMenuSection'
import { Action, ButtonType, ListedAccount, ListedAccountInfo, SNNote } from '@standardnotes/snjs'
@@ -28,9 +23,7 @@ export const Listed: FC<TProps> = ({ note }) => {
const [listedAccounts, setListedAccounts] = useState<ListedAccount[]>([])
const [listedAccountDetails, setListedAccountDetails] = useState<TListedAccountItem[]>([])
const [authorUrlWithInProgressAction, setAuthorUrlWithInProgressAction] = useState<string | null>(
null
)
const [authorUrlWithInProgressAction, setAuthorUrlWithInProgressAction] = useState<string | null>(null)
const { showActionSheet } = useCustomActionSheet()
@@ -41,9 +34,7 @@ export const Listed: FC<TProps> = ({ note }) => {
for (const listedAccountItem of accounts) {
const listedItemInfo = await application.getListedAccountInfo(listedAccountItem, note?.uuid)
listedAccountsArray.push(
listedItemInfo ? listedItemInfo : { display_name: listedAccountItem.authorId }
)
listedAccountsArray.push(listedItemInfo ? listedItemInfo : { display_name: listedAccountItem.authorId })
}
return listedAccountsArray
},
@@ -124,9 +115,7 @@ export const Listed: FC<TProps> = ({ note }) => {
setAuthorUrlWithInProgressAction(null)
return
}
const listedDetails = (await getListedAccountsDetails(
listedAccounts
)) as TListedAccountItem[]
const listedDetails = (await getListedAccountsDetails(listedAccounts)) as TListedAccountItem[]
setListedAccountDetails(listedDetails)
showActionsMenu(listedDetails[index], index)
@@ -159,10 +148,9 @@ export const Listed: FC<TProps> = ({ note }) => {
value: <SnIcon type={'notes'} style={styles.blogItemIcon} />,
}}
/>
{isActionInProgress &&
(item as ListedAccountInfo).author_url === authorUrlWithInProgressAction && (
<ActivityIndicator style={styles.blogActionInProgressIndicator} />
)}
{isActionInProgress && (item as ListedAccountInfo).author_url === authorUrlWithInProgressAction && (
<ActivityIndicator style={styles.blogActionInProgressIndicator} />
)}
</ListedItemRow>
{!isLoading && !doesListedItemHaveActions(item) && (
<CantLoadActionsText>Unable to load actions</CantLoadActionsText>
@@ -183,9 +171,7 @@ export const Listed: FC<TProps> = ({ note }) => {
value: <SnIcon type={'user-add'} style={styles.blogItemIcon} />,
}}
/>
{isRequestingAccount && (
<ActivityIndicator style={styles.blogActionInProgressIndicator} />
)}
{isRequestingAccount && <ActivityIndicator style={styles.blogActionInProgressIndicator} />}
</ListedItemRow>
<ListedItemRow>
<SideMenuCell

View File

@@ -16,11 +16,7 @@ import Icon from 'react-native-vector-icons/Ionicons'
import { ThemeContext } from 'styled-components'
import { FirstSafeAreaView, MainSafeAreaView, useStyles } from './MainSideMenu.styled'
import { SideMenuHero } from './SideMenuHero'
import {
SideMenuOption,
SideMenuOptionIconDescriptionType,
SideMenuSection,
} from './SideMenuSection'
import { SideMenuOption, SideMenuOptionIconDescriptionType, SideMenuSection } from './SideMenuSection'
import { TagSelectionList } from './TagSelectionList'
type Props = {
@@ -252,11 +248,7 @@ export const MainSideMenu = React.memo(({ drawerRef }: Props) => {
<Fragment>
<FirstSafeAreaView />
<MainSafeAreaView>
<SideMenuHero
testID="settingsButton"
onPress={openSettings}
onOutOfSyncPress={outOfSyncPressed}
/>
<SideMenuHero testID="settingsButton" onPress={openSettings} onOutOfSyncPress={outOfSyncPressed} />
<FlatList
style={styles.sections}
data={['themes-section', 'views-section', 'tags-section'].map(key => ({

View File

@@ -1,9 +1,5 @@
import { associateComponentWithNote } from '@Lib/ComponentManager'
import {
useChangeNote,
useDeleteNoteWithPrivileges,
useProtectOrUnprotectNote,
} from '@Lib/SnjsHelperHooks'
import { useChangeNote, useDeleteNoteWithPrivileges, useProtectOrUnprotectNote } from '@Lib/SnjsHelperHooks'
import { isUnfinishedFeaturesEnabled } from '@Lib/Utils'
import { useFocusEffect, useNavigation } from '@react-navigation/native'
import { TEnvironment } from '@Root/App'
@@ -50,11 +46,7 @@ import DrawerLayout from 'react-native-gesture-handler/DrawerLayout'
import Icon from 'react-native-vector-icons/Ionicons'
import { ThemeContext } from 'styled-components'
import { SafeAreaContainer, useStyles } from './NoteSideMenu.styled'
import {
SideMenuOption,
SideMenuOptionIconDescriptionType,
SideMenuSection,
} from './SideMenuSection'
import { SideMenuOption, SideMenuOptionIconDescriptionType, SideMenuSection } from './SideMenuSection'
import { TagSelectionList } from './TagSelectionList'
function sortAlphabetically(array: SNComponent[]): SNComponent[] {
@@ -74,9 +66,7 @@ function useEditorComponents(): SNComponent[] {
const [components, setComponents] = useState<SNComponent[]>([])
useEffect(() => {
const removeComponentsObserver = application.streamItems(ContentType.Component, () => {
const displayComponents = sortAlphabetically(
application.componentManager.componentsForArea(ComponentArea.Editor)
)
const displayComponents = sortAlphabetically(application.componentManager.componentsForArea(ComponentArea.Editor))
setComponents(displayComponents)
})
return () => {
@@ -108,12 +98,9 @@ export const NoteSideMenu = React.memo((props: Props) => {
)
useEffect(() => {
const removeEventObserver = application.addSingleEventObserver(
ApplicationEvent.PreferencesChanged,
async () => {
setShouldAddTagHierachy(application.getPreference(PrefKey.NoteAddToParentFolders, true))
}
)
const removeEventObserver = application.addSingleEventObserver(ApplicationEvent.PreferencesChanged, async () => {
setShouldAddTagHierachy(application.getPreference(PrefKey.NoteAddToParentFolders, true))
})
return () => {
removeEventObserver()
@@ -276,10 +263,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
false
)
}
if (
activeEditorComponent?.isExplicitlyEnabledForItem(note!.uuid) ||
activeEditorComponent?.isMobileDefault
) {
if (activeEditorComponent?.isExplicitlyEnabledForItem(note!.uuid) || activeEditorComponent?.isMobileDefault) {
await disassociateComponentWithCurrentNote(activeEditorComponent)
}
} else if (selectedComponent.area === ComponentArea.Editor) {
@@ -632,19 +616,15 @@ export const NoteSideMenu = React.memo((props: Props) => {
selectedTags,
}))}
renderItem={({ item }) => {
const { OptionsSection, EditorsSection, ListedSection, TagsSection, FilesSection } =
MenuSections
const { OptionsSection, EditorsSection, ListedSection, TagsSection, FilesSection } = MenuSections
if (
item.key === FilesSection &&
(isEntitledToFiles || isUnfinishedFeaturesEnabled(props.env))
) {
if (item.key === FilesSection && (isEntitledToFiles || isUnfinishedFeaturesEnabled(props.env))) {
return (
<SideMenuSection
title={'Files'}
customCollapsedLabel={`${
attachedFilesLength ? `${attachedFilesLength}` : 'No'
} attached file${attachedFilesLength === 1 ? '' : 's'}`}
customCollapsedLabel={`${attachedFilesLength ? `${attachedFilesLength}` : 'No'} attached file${
attachedFilesLength === 1 ? '' : 's'
}`}
collapsed={false}
>
<Files note={note} />
@@ -655,9 +635,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
return <SideMenuSection title="Options" options={item.noteOptions} />
}
if (item.key === EditorsSection) {
return (
<SideMenuSection title="Editors" options={item.editorComponents} collapsed={true} />
)
return <SideMenuSection title="Editors" options={item.editorComponents} collapsed={true} />
}
if (item.key === ListedSection) {
return (
@@ -674,9 +652,7 @@ export const NoteSideMenu = React.memo((props: Props) => {
contentType={ContentType.Tag}
onTagSelect={tag => item.onTagSelect(tag, shouldAddTagHierarchy)}
selectedTags={item.selectedTags}
emptyPlaceholder={
'Create a new tag using the tag button in the bottom right corner.'
}
emptyPlaceholder={'Create a new tag using the tag button in the bottom right corner.'}
/>
</SideMenuSection>
)

View File

@@ -71,9 +71,7 @@ export const SideMenuCell: React.FC<SideMenuOption> = props => {
>
<CellContent iconSide={iconSide} style={props.cellContentStyle || {}}>
{iconSide === 'left' && (
<IconContainerLeft>
{renderIcon(props.iconDesc, theme.stylekitInfoColor)}
</IconContainerLeft>
<IconContainerLeft>{renderIcon(props.iconDesc, theme.stylekitInfoColor)}</IconContainerLeft>
)}
<TextContainer selected={props.selected} isSubtext={Boolean(props.subtext)}>
@@ -88,9 +86,7 @@ export const SideMenuCell: React.FC<SideMenuOption> = props => {
{props.children}
{iconSide === 'right' && (
<IconContainerRight>
{renderIcon(props.iconDesc, theme.stylekitInfoColor)}
</IconContainerRight>
<IconContainerRight>{renderIcon(props.iconDesc, theme.stylekitInfoColor)}</IconContainerRight>
)}
</CellContent>
</Touchable>

View File

@@ -5,15 +5,7 @@ import { ContentType } from '@standardnotes/snjs'
import React, { useContext, useEffect, useMemo, useState } from 'react'
import { ViewProps } from 'react-native'
import { ThemeContext } from 'styled-components'
import {
Cell,
IconCircle,
OutOfSyncContainer,
OutOfSyncLabel,
SubTitle,
Title,
Touchable,
} from './SideMenuHero.styled'
import { Cell, IconCircle, OutOfSyncContainer, OutOfSyncLabel, SubTitle, Title, Touchable } from './SideMenuHero.styled'
type Props = {
onPress: () => void
@@ -78,11 +70,7 @@ export const SideMenuHero: React.FC<Props> = props => {
{isOutOfSync && (
<OutOfSyncContainer onPress={props.onOutOfSyncPress}>
<IconCircle>
<Circle
size={10}
backgroundColor={theme.stylekitWarningColor}
borderColor={theme.stylekitWarningColor}
/>
<Circle size={10} backgroundColor={theme.stylekitWarningColor} borderColor={theme.stylekitWarningColor} />
</IconCircle>
<OutOfSyncLabel>Potentially Out of Sync</OutOfSyncLabel>
</OutOfSyncContainer>

View File

@@ -3,14 +3,7 @@ import { AppStackNavigationProp } from '@Root/AppStack'
import { useSafeApplicationContext } from '@Root/Hooks/useSafeApplicationContext'
import { SCREEN_COMPOSE, SCREEN_INPUT_MODAL_TAG } from '@Root/Screens/screens'
import { SideMenuOptionIconDescriptionType } from '@Root/Screens/SideMenu/SideMenuSection'
import {
ButtonType,
CollectionSort,
ContentType,
FindItem,
SmartView,
SNTag,
} from '@standardnotes/snjs'
import { ButtonType, CollectionSort, ContentType, FindItem, SmartView, SNTag } from '@standardnotes/snjs'
import { useCustomActionSheet } from '@Style/CustomActionSheet'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { FlatList, ListRenderItem } from 'react-native'
@@ -117,9 +110,7 @@ export const TagSelectionList = React.memo(
children = (tags as SNTag[]).filter((tag: SNTag) => rawChildren.includes(tag.uuid))
}
const isSelected = selectedTags.some(
(selectedTag: SNTag | SmartView) => selectedTag.uuid === item.uuid
)
const isSelected = selectedTags.some((selectedTag: SNTag | SmartView) => selectedTag.uuid === item.uuid)
return (
<>

View File

@@ -32,16 +32,8 @@ export const ViewProtectedNote = ({
return (
<Container>
<Title>This note is protected</Title>
<Text>
Add a passcode or biometrics lock, or create an account, to require authentication to view
this note.
</Text>
<Button
label="Go to Settings"
primary={true}
fullWidth={true}
onPress={onPressGoToSettings}
/>
<Text>Add a passcode or biometrics lock, or create an account, to require authentication to view this note.</Text>
<Button label="Go to Settings" primary={true} fullWidth={true} onPress={onPressGoToSettings} />
<Button label="View" fullWidth={true} last={true} onPress={onPressView} />
</Container>
)

View File

@@ -19,13 +19,7 @@ import THEME_DARK_JSON from './Themes/blue-dark.json'
import THEME_BLUE_JSON from './Themes/blue.json'
import THEME_RED_JSON from './Themes/red.json'
import { MobileThemeVariables } from './Themes/styled-components'
import {
DARK_CONTENT,
getColorLuminosity,
keyboardColorForTheme,
LIGHT_CONTENT,
statusBarColorForTheme,
} from './Utils'
import { DARK_CONTENT, getColorLuminosity, keyboardColorForTheme, LIGHT_CONTENT, statusBarColorForTheme } from './Utils'
const LIGHT_THEME_KEY = 'lightThemeKey'
const DARK_THEME_KEY = 'darkThemeKey'
@@ -243,10 +237,7 @@ export class ThemeService {
}
public async getThemeForMode(mode: 'light' | 'dark') {
return this.application?.getValue(
mode === 'dark' ? DARK_THEME_KEY : LIGHT_THEME_KEY,
StorageValueModes.Nonwrapped
)
return this.application?.getValue(mode === 'dark' ? DARK_THEME_KEY : LIGHT_THEME_KEY, StorageValueModes.Nonwrapped)
}
/**
@@ -260,8 +251,7 @@ export class ThemeService {
}
private setDefaultTheme() {
const defaultThemeId =
this.getColorScheme() === 'dark' ? SystemThemeTint.Dark : SystemThemeTint.Blue
const defaultThemeId = this.getColorScheme() === 'dark' ? SystemThemeTint.Dark : SystemThemeTint.Blue
this.setActiveTheme(defaultThemeId)
}
@@ -321,9 +311,7 @@ export class ThemeService {
...theme.mobileContent.variables,
...baseVariables,
}
const luminosity =
theme.mobileContent.luminosity ||
getColorLuminosity(variables.stylekitContrastBackgroundColor)
const luminosity = theme.mobileContent.luminosity || getColorLuminosity(variables.stylekitContrastBackgroundColor)
return new MobileTheme(
theme.payload.copy({
content: {
@@ -372,9 +360,7 @@ export class ThemeService {
if (Platform.Version <= 22) {
StatusBar.setBackgroundColor('#000000')
} else {
StatusBar.setBackgroundColor(
theme.mobileContent.variables.stylekitContrastBackgroundColor
)
StatusBar.setBackgroundColor(theme.mobileContent.variables.stylekitContrastBackgroundColor)
}
}
},
@@ -476,8 +462,7 @@ export class ThemeService {
}
private async loadCachedThemes() {
const rawValue =
(await this.application!.getValue(CACHED_THEMES_KEY, StorageValueModes.Nonwrapped)) || []
const rawValue = (await this.application!.getValue(CACHED_THEMES_KEY, StorageValueModes.Nonwrapped)) || []
const themes = (rawValue as DecryptedTransferPayload<ComponentContent>[]).map(rawPayload => {
const payload = new DecryptedPayload<ComponentContent>(rawPayload)