fix: super note improvements (#1991)
* fix: super note previews * fix; checkmark size * fix: top padding * fix: prevent delete shortcut * fix: spellcheck control * fix: only embed file if uploaded to current note * fix: ability to create new tag from editor autocomplete * feat: protected file embed handling * fix: event payload
This commit is contained in:
@@ -12,8 +12,8 @@ export abstract class AbstractViewController<Event = void, EventData = void> {
|
||||
|
||||
constructor(public application: WebApplication, protected eventBus: InternalEventBus) {}
|
||||
|
||||
protected async publishEventSync(name: CrossControllerEvent): Promise<void> {
|
||||
await this.eventBus.publishSync({ type: name, payload: undefined }, InternalEventPublishStrategy.SEQUENCE)
|
||||
protected async publishCrossControllerEventSync(name: CrossControllerEvent, data?: unknown): Promise<void> {
|
||||
await this.eventBus.publishSync({ type: name, payload: data }, InternalEventPublishStrategy.SEQUENCE)
|
||||
}
|
||||
|
||||
deinit(): void {
|
||||
@@ -38,7 +38,7 @@ export abstract class AbstractViewController<Event = void, EventData = void> {
|
||||
}
|
||||
}
|
||||
|
||||
notifyEvent(event: Event, data: EventData): void {
|
||||
protected notifyEvent(event: Event, data: EventData): void {
|
||||
this.eventObservers.forEach((observer) => observer(event, data))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@ export enum CrossControllerEvent {
|
||||
ActiveEditorChanged = 'ActiveEditorChanged',
|
||||
HydrateFromPersistedValues = 'HydrateFromPersistedValues',
|
||||
RequestValuePersistence = 'RequestValuePersistence',
|
||||
DisplayPremiumModal = 'DisplayPremiumModal',
|
||||
}
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { destroyAllObjectProperties } from '@/Utils'
|
||||
import { ApplicationEvent, FeatureIdentifier, FeatureStatus, InternalEventBus } from '@standardnotes/snjs'
|
||||
import {
|
||||
ApplicationEvent,
|
||||
FeatureIdentifier,
|
||||
FeatureStatus,
|
||||
InternalEventBus,
|
||||
InternalEventInterface,
|
||||
} from '@standardnotes/snjs'
|
||||
import { action, makeObservable, observable, runInAction, when } from 'mobx'
|
||||
import { AbstractViewController } from './Abstract/AbstractViewController'
|
||||
import { CrossControllerEvent } from './CrossControllerEvent'
|
||||
|
||||
export class FeaturesController extends AbstractViewController {
|
||||
hasFolders: boolean
|
||||
@@ -30,6 +37,8 @@ export class FeaturesController extends AbstractViewController {
|
||||
this.hasFiles = this.isEntitledToFiles()
|
||||
this.premiumAlertFeatureName = undefined
|
||||
|
||||
eventBus.addEventHandler(this, CrossControllerEvent.DisplayPremiumModal)
|
||||
|
||||
makeObservable(this, {
|
||||
hasFolders: observable,
|
||||
hasSmartViews: observable,
|
||||
@@ -58,6 +67,13 @@ export class FeaturesController extends AbstractViewController {
|
||||
)
|
||||
}
|
||||
|
||||
async handleEvent(event: InternalEventInterface): Promise<void> {
|
||||
if (event.type === CrossControllerEvent.DisplayPremiumModal) {
|
||||
const payload = event.payload as { featureName: string }
|
||||
void this.showPremiumAlert(payload.featureName)
|
||||
}
|
||||
}
|
||||
|
||||
public async showPremiumAlert(featureName: string): Promise<void> {
|
||||
this.premiumAlertFeatureName = featureName
|
||||
return when(() => this.premiumAlertFeatureName === undefined)
|
||||
|
||||
@@ -139,7 +139,7 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
||||
}
|
||||
}
|
||||
|
||||
attachFileToNote = async (file: FileItem) => {
|
||||
attachFileToSelectedNote = async (file: FileItem) => {
|
||||
const note = this.notesController.firstSelectedNote
|
||||
if (!note) {
|
||||
addToast({
|
||||
@@ -207,7 +207,7 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
||||
|
||||
switch (action.type) {
|
||||
case PopoverFileItemActionType.AttachFileToNote:
|
||||
await this.attachFileToNote(file)
|
||||
await this.attachFileToSelectedNote(file)
|
||||
break
|
||||
case PopoverFileItemActionType.DetachFileToNote:
|
||||
await this.detachFileFromNote(file)
|
||||
@@ -398,10 +398,6 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
||||
type: ToastType.Success,
|
||||
message: `Uploaded file "${uploadedFile.name}"`,
|
||||
})
|
||||
|
||||
this.notifyEvent(FilesControllerEvent.FileUploadedToNote, {
|
||||
[FilesControllerEvent.FileUploadedToNote]: { uuid: uploadedFile.uuid },
|
||||
})
|
||||
}
|
||||
|
||||
return uploadedFiles
|
||||
@@ -420,6 +416,12 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
||||
return undefined
|
||||
}
|
||||
|
||||
notifyObserversOfUploadedFileLinkingToCurrentNote(fileUuid: string) {
|
||||
this.notifyEvent(FilesControllerEvent.FileUploadedToNote, {
|
||||
[FilesControllerEvent.FileUploadedToNote]: { uuid: fileUuid },
|
||||
})
|
||||
}
|
||||
|
||||
deleteFilesPermanently = async (files: FileItem[]) => {
|
||||
const title = Strings.trashItemsTitle
|
||||
const text = files.length === 1 ? StringUtils.deleteFile(files[0].name) : Strings.deleteMultipleFiles
|
||||
|
||||
@@ -259,7 +259,7 @@ export class ItemListController extends AbstractViewController implements Intern
|
||||
|
||||
this.linkingController.reloadAllLinks()
|
||||
|
||||
await this.publishEventSync(CrossControllerEvent.ActiveEditorChanged)
|
||||
await this.publishCrossControllerEventSync(CrossControllerEvent.ActiveEditorChanged)
|
||||
}
|
||||
|
||||
async openFile(fileUuid: string): Promise<void> {
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
} from '@standardnotes/snjs'
|
||||
import { action, computed, makeObservable, observable } from 'mobx'
|
||||
import { AbstractViewController } from './Abstract/AbstractViewController'
|
||||
import { CrossControllerEvent } from './CrossControllerEvent'
|
||||
import { FilesController } from './FilesController'
|
||||
import { ItemListController } from './ItemList/ItemListController'
|
||||
import { NavigationController } from './Navigation/NavigationController'
|
||||
@@ -262,24 +263,35 @@ export class LinkingController extends AbstractViewController {
|
||||
this.reloadAllLinks()
|
||||
}
|
||||
|
||||
linkItemToSelectedItem = async (itemToLink: LinkableItem) => {
|
||||
linkItemToSelectedItem = async (itemToLink: LinkableItem): Promise<boolean> => {
|
||||
const cannotLinkItem = !this.isEntitledToNoteLinking && itemToLink instanceof SNNote
|
||||
if (cannotLinkItem) {
|
||||
void this.publishCrossControllerEventSync(CrossControllerEvent.DisplayPremiumModal, {
|
||||
featureName: 'Note linking',
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
await this.ensureActiveItemIsInserted()
|
||||
const activeItem = this.activeItem
|
||||
|
||||
if (!activeItem) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
await this.linkItems(activeItem, itemToLink)
|
||||
return true
|
||||
}
|
||||
|
||||
createAndAddNewTag = async (title: string) => {
|
||||
createAndAddNewTag = async (title: string): Promise<SNTag> => {
|
||||
await this.ensureActiveItemIsInserted()
|
||||
const activeItem = this.activeItem
|
||||
const newTag = await this.application.mutator.findOrCreateTag(title)
|
||||
if (activeItem) {
|
||||
await this.addTagToItem(newTag, activeItem)
|
||||
}
|
||||
|
||||
return newTag
|
||||
}
|
||||
|
||||
addTagToItem = async (tag: SNTag, item: FileItem | SNNote) => {
|
||||
|
||||
Reference in New Issue
Block a user