feat: files related improvements
This commit is contained in:
@@ -72,7 +72,7 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
||||
}, [application, note])
|
||||
|
||||
const toggleAttachedFilesMenu = useCallback(async () => {
|
||||
if (!appState.features.isEntitledToFiles) {
|
||||
if (!appState.features.hasFiles) {
|
||||
premiumModal.activate('Files')
|
||||
return
|
||||
}
|
||||
@@ -99,7 +99,7 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
||||
|
||||
setOpen(newOpenState)
|
||||
}
|
||||
}, [appState.features.isEntitledToFiles, onClickPreprocessing, open, premiumModal])
|
||||
}, [appState.features.hasFiles, onClickPreprocessing, open, premiumModal])
|
||||
|
||||
const deleteFile = async (file: SNFile) => {
|
||||
const shouldDelete = await confirmDialog({
|
||||
@@ -294,6 +294,10 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
||||
|
||||
setIsDraggingFiles(false)
|
||||
|
||||
if (!appState.features.hasFiles) {
|
||||
return
|
||||
}
|
||||
|
||||
if (event.dataTransfer?.items.length) {
|
||||
Array.from(event.dataTransfer.items).forEach(async (item) => {
|
||||
const fileOrHandle = StreamingFileReader.available()
|
||||
@@ -321,7 +325,7 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
||||
dragCounter.current = 0
|
||||
}
|
||||
},
|
||||
[appState.files, attachFileToNote, currentTab],
|
||||
[appState.files, appState.features.hasFiles, attachFileToNote, currentTab],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -18,7 +18,10 @@ export const FilePreviewInfoPanel: FunctionComponent<Props> = ({ file }) => {
|
||||
<span className="font-semibold">Type:</span> {file.mimeType}
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<span className="font-semibold">Size:</span> {formatSizeToReadableString(file.decryptedSize)}
|
||||
<span className="font-semibold">Decrypted Size:</span> {formatSizeToReadableString(file.decryptedSize)}
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<span className="font-semibold">Encrypted Size:</span> {formatSizeToReadableString(file.encryptedSize)}
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<span className="font-semibold">Created:</span> {file.created_at.toLocaleString()}
|
||||
|
||||
@@ -947,15 +947,13 @@ export class NoteView extends PureComponent<Props, State> {
|
||||
{this.state.noteStatus?.desc && <div className="desc">{this.state.noteStatus.desc}</div>}
|
||||
</div>
|
||||
</div>
|
||||
{this.appState.features.isFilesEnabled && (
|
||||
<div className="mr-3">
|
||||
<AttachedFilesButton
|
||||
application={this.application}
|
||||
appState={this.appState}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="mr-3">
|
||||
<AttachedFilesButton
|
||||
application={this.application}
|
||||
appState={this.appState}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="mr-3">
|
||||
<ChangeEditorButton
|
||||
application={this.application}
|
||||
|
||||
@@ -49,6 +49,7 @@ export const NotesListItem: FunctionComponent<Props> = ({
|
||||
tags,
|
||||
}) => {
|
||||
const flags = flagsForNote(note)
|
||||
const hasFiles = application.items.getFilesForNote(note).length > 0
|
||||
const showModifiedDate = sortedBy === CollectionSort.UpdatedAt
|
||||
const editorForNote = application.componentManager.editorForNote(note)
|
||||
const editorName = editorForNote?.name ?? PLAIN_EDITOR_NAME
|
||||
@@ -132,6 +133,11 @@ export const NotesListItem: FunctionComponent<Props> = ({
|
||||
<Icon ariaLabel="Pinned" type="pin-filled" className="sn-icon--small color-info" />
|
||||
</span>
|
||||
)}
|
||||
{hasFiles && (
|
||||
<span title="Files">
|
||||
<Icon ariaLabel="Files" type="attachment-file" className="sn-icon--small color-info" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ export const AccountPreferences = observer(({ application, appState }: Props) =>
|
||||
</>
|
||||
)}
|
||||
<Subscription application={application} appState={appState} />
|
||||
{application.hasAccount() && appState.features.isEntitledToFiles && <FilesSection application={application} />}
|
||||
{application.hasAccount() && appState.features.hasFiles && <FilesSection application={application} />}
|
||||
<SignOutWrapper application={application} appState={appState} />
|
||||
</PreferencesPane>
|
||||
))
|
||||
|
||||
@@ -48,10 +48,10 @@ export const PremiumFeaturesModal: FunctionalComponent<Props> = ({
|
||||
<div className="flex items-center justify-center p-1" aria-hidden={true}>
|
||||
<PremiumIllustration className="mb-2" />
|
||||
</div>
|
||||
<div className="text-lg text-center font-bold mb-1">Enable Premium Features</div>
|
||||
<div className="text-lg text-center font-bold mb-1">Enable Advanced Features</div>
|
||||
</AlertDialogLabel>
|
||||
<AlertDialogDescription className="text-sm text-center color-grey-1 px-4.5 mb-2">
|
||||
In order to use <span className="font-semibold">{featureName}</span> and other premium features, please
|
||||
In order to use <span className="font-semibold">{featureName}</span> and other advanced features, please
|
||||
purchase a subscription or upgrade your current plan.
|
||||
</AlertDialogDescription>
|
||||
<div className="p-4">
|
||||
|
||||
@@ -1,27 +1,23 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { isDev } from '@/Utils'
|
||||
import { ApplicationEvent, FeatureIdentifier, FeatureStatus } from '@standardnotes/snjs'
|
||||
import { action, computed, makeObservable, observable, runInAction, when } from 'mobx'
|
||||
import { action, makeObservable, observable, runInAction, when } from 'mobx'
|
||||
|
||||
export class FeaturesState {
|
||||
hasFolders: boolean
|
||||
hasSmartViews: boolean
|
||||
hasFilesBeta: boolean
|
||||
hasFiles: boolean
|
||||
premiumAlertFeatureName: string | undefined
|
||||
|
||||
constructor(private application: WebApplication, appObservers: (() => void)[]) {
|
||||
this.hasFolders = this.hasNativeFolders()
|
||||
this.hasSmartViews = this.hasNativeSmartViews()
|
||||
this.hasFilesBeta = this.isEntitledToFilesBeta()
|
||||
this.hasFolders = this.isEntitledToFolders()
|
||||
this.hasSmartViews = this.isEntitledToSmartViews()
|
||||
this.hasFiles = this.isEntitledToFiles()
|
||||
this.premiumAlertFeatureName = undefined
|
||||
|
||||
makeObservable(this, {
|
||||
hasFolders: observable,
|
||||
hasSmartViews: observable,
|
||||
|
||||
hasFilesBeta: observable,
|
||||
isFilesEnabled: computed,
|
||||
isEntitledToFiles: computed,
|
||||
hasFiles: observable,
|
||||
|
||||
premiumAlertFeatureName: observable,
|
||||
showPremiumAlert: action,
|
||||
@@ -37,9 +33,9 @@ export class FeaturesState {
|
||||
case ApplicationEvent.FeaturesUpdated:
|
||||
case ApplicationEvent.Launched:
|
||||
runInAction(() => {
|
||||
this.hasFolders = this.hasNativeFolders()
|
||||
this.hasSmartViews = this.hasNativeSmartViews()
|
||||
this.hasFilesBeta = this.isEntitledToFilesBeta()
|
||||
this.hasFolders = this.isEntitledToFolders()
|
||||
this.hasSmartViews = this.isEntitledToSmartViews()
|
||||
this.hasFiles = this.isEntitledToFiles()
|
||||
})
|
||||
}
|
||||
}),
|
||||
@@ -55,32 +51,21 @@ export class FeaturesState {
|
||||
this.premiumAlertFeatureName = undefined
|
||||
}
|
||||
|
||||
get isFilesEnabled(): boolean {
|
||||
return this.hasFilesBeta || window.enabledUnfinishedFeatures || isDev
|
||||
private isEntitledToFiles(): boolean {
|
||||
const status = this.application.features.getFeatureStatus(FeatureIdentifier.Files)
|
||||
|
||||
return status === FeatureStatus.Entitled
|
||||
}
|
||||
|
||||
get isEntitledToFiles(): boolean {
|
||||
return this.hasFilesBeta
|
||||
}
|
||||
|
||||
private hasNativeFolders(): boolean {
|
||||
private isEntitledToFolders(): boolean {
|
||||
const status = this.application.features.getFeatureStatus(FeatureIdentifier.TagNesting)
|
||||
|
||||
return status === FeatureStatus.Entitled
|
||||
}
|
||||
|
||||
private hasNativeSmartViews(): boolean {
|
||||
private isEntitledToSmartViews(): boolean {
|
||||
const status = this.application.features.getFeatureStatus(FeatureIdentifier.SmartFilters)
|
||||
|
||||
return status === FeatureStatus.Entitled
|
||||
}
|
||||
|
||||
private isEntitledToFilesBeta(): boolean {
|
||||
if (isDev && this.application.hasAccount()) {
|
||||
return true
|
||||
}
|
||||
|
||||
const status = this.application.features.getFeatureStatus(FeatureIdentifier.FilesBeta)
|
||||
return status === FeatureStatus.Entitled
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user