All files / src/libs/ContextMenus GetMetadata.ts

0% Statements 0/54
0% Branches 0/31
0% Functions 0/13
0% Lines 0/52

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169                                                                                                                                                                                                                                                                                                                                                 
import { Menu, TAbstractFile, TFile } from 'obsidian';
import { ImplementsStatic } from 'src/classes/decorators/ImplementsStatic';
import { Singleton } from 'src/classes/decorators/Singleton';
import type IMetadataCache from 'src/interfaces/IMetadataCache';
import { FileType } from 'src/libs/FileType/FileType';
import { DocumentModel } from 'src/models/DocumentModel';
import { ContextMenu } from './ContextMenu';
import { IContextMenu } from './interfaces/IContextMenu';
import { Inject } from '../DependencyInjection/decorators/Inject';
import type { IDIContainer } from '../DependencyInjection/interfaces/IDIContainer';
import type { IHelperObsidian } from '../Helper/interfaces/IHelperObsidian';
import { Lifecycle } from '../LifecycleManager/decorators/Lifecycle';
import { ILifecycleObject } from '../LifecycleManager/interfaces/ILifecycleObject';
import { FileMetadata } from '../MetadataCache';
import type ITranslationService from '../TranslationService/interfaces/ITranslationService';
 
/**
 * Represents a class for retrieving metadata for a file.
 * @see {@link Singleton}
 * @see {@link Lifecycle}
 */
@Lifecycle('Static')
@ImplementsStatic<ILifecycleObject>()
@Singleton
export class GetMetadata extends ContextMenu implements IContextMenu {
    protected _bindContextMenu = this.onContextMenu.bind(this);
    @Inject('ITranslationService')
    private readonly _ITranslationService: ITranslationService;
    @Inject('IMetadataCache')
    private readonly _IMetadataCache: IMetadataCache;
    @Inject('IHelperObsidian')
    private readonly _IHelperObsidian: IHelperObsidian;
    protected _hasEventsRegistered = false;
 
    /**
     * Initializes a instance of the GetMetadata class.
     * @param dependencies The dependencies for the context menu.
     */
    constructor(dependencies?: IDIContainer) {
        super();
    }
 
    /**
     * This method is called when the application is unloaded.
     */
    public static onLoad(): void {
        const instance = new GetMetadata();
        instance.isInitialized();
    }
 
    /**
     * This method is called when the application is unloaded.
     */
    public static onUnload(): void {
        const instance = new GetMetadata();
        instance.deconstructor();
    }
 
    /**
     * Initializes the context menu.
     */
    protected onConstruction(): void {
        this._IApp.workspace.on('file-menu', this._bindContextMenu);
 
        this._IPrj.addCommand({
            id: 'get-metadata-file',
            name: this._ITranslationService.get('Show Metadata File'),
            /**
             * Callback function for the 'get-metadata-file' command.
             */
            callback: () => {
                new GetMetadata().invoke();
            },
        });
    }
 
    /**
     * Cleans up the context menu.
     */
    protected onDeconstruction(): void {
        this._IApp.workspace.off('file-menu', this._bindContextMenu);
    }
 
    /**
     * Adds the 'GetMetadata' context menu item.
     * @param menu The context menu.
     * @param file The file to add the context menu item to.
     */
    protected onContextMenu(menu: Menu, file: TAbstractFile): void {
        // Allow only pdf files
        Iif (!(file instanceof TFile) || !file.path.endsWith('.pdf')) {
            return;
        }
        const metadataFile = this.getCorrespondingMetadataFile(file);
 
        Iif (!metadataFile) {
            return;
        }
        const document = new DocumentModel(metadataFile.file);
 
        Iif (metadataFile) {
            menu.addSeparator();
 
            menu.addItem((item) => {
                item.setTitle(
                    this._ITranslationService.get('Show Metadata File'),
                )
                    .setIcon(document.getCorospondingSymbol())
                    .onClick(async () => {
                        await this._IHelperObsidian.openFile(document.file);
                    });
            });
        }
    }
 
    /**
     * Returns the metadata file for the given document (e.g. pdf) file.
     * @param file The document file.
     * @returns The metadata file or undefined if not found.
     */
    private getCorrespondingMetadataFile(
        file: TFile,
    ): FileMetadata | undefined {
        return this._IMetadataCache.cache.find((metadata) => {
            const type = new FileType(metadata.metadata.frontmatter?.type);
 
            const fileLink = metadata.metadata.frontmatter?.file as
                | string
                | undefined
                | null;
 
            if (type.value && fileLink && type.equals('Metadata')) {
                return fileLink.contains(file.name);
            } else {
                return false;
            }
        });
    }
 
    /**
     * Opens the metadata file for the active (e.g. pdf) file.
     */
    public async invoke(): Promise<void> {
        const workspace = this._IApp.workspace;
        const activeFile = workspace.getActiveFile();
 
        Iif (
            !activeFile ||
            !(activeFile instanceof TFile) ||
            !activeFile.path.endsWith('.pdf')
        ) {
            this._logger?.warn('No active pdf file found.');
 
            return;
        }
        const metadataFile = this.getCorrespondingMetadataFile(activeFile);
 
        Iif (!metadataFile) {
            this._logger?.warn(
                'No metadata file to the active pdf file found.',
            );
 
            return;
        }
        const document = new DocumentModel(metadataFile.file);
        await this._IHelperObsidian.openFile(document.file);
    }
}
 
Zur TypeDoc-Dokumentation