文件
mynode/packages/app-desktop/services/plugins/PlatformImplementation.ts
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

126 行
3.5 KiB
TypeScript

import bridge from '../bridge';
import { VersionInfo } from '@joplin/lib/services/plugins/api/types';
import Setting from '@joplin/lib/models/Setting';
import { reg } from '@joplin/lib/registry';
import BasePlatformImplementation, { Joplin } from '@joplin/lib/services/plugins/BasePlatformImplementation';
import { CreateFromPdfOptions, Implementation as ImagingImplementation } from '@joplin/lib/services/plugins/api/JoplinImaging';
import shim from '@joplin/lib/shim';
import { join } from 'path';
import uuid, { uuidgen } from '@joplin/lib/uuid';
import { hasProtocol } from '@joplin/utils/url';
import { fileExtension } from '@joplin/utils/path';
import { clipboard, nativeImage } from 'electron';
const packageInfo = require('../../packageInfo');
interface Components {
[key: string]: unknown;
}
// PlatformImplementation provides access to platform specific dependencies,
// such as the clipboard, message dialog, etc. It allows having the same plugin
// API for all platforms, but with different implementations.
export default class PlatformImplementation extends BasePlatformImplementation {
private static instance_: PlatformImplementation;
private joplin_: Joplin;
private components_: Components;
public static instance(): PlatformImplementation {
if (!this.instance_) this.instance_ = new PlatformImplementation();
return this.instance_;
}
public get versionInfo(): VersionInfo {
return {
version: packageInfo.version,
syncVersion: Setting.value('syncVersion'),
profileVersion: reg.db().version(),
platform: 'desktop',
};
}
public get clipboard() {
return clipboard;
}
public get nativeImage() {
return nativeImage;
}
public constructor() {
super();
this.components_ = {};
this.joplin_ = {
views: {
dialogs: {
showMessageBox: async (message: string) => {
return bridge().showMessageBox(message);
},
showOpenDialog: async (options) => {
return bridge().showOpenDialog(options);
},
},
},
};
}
public registerComponent(name: string, component: unknown) {
this.components_[name] = component;
}
public unregisterComponent(name: string) {
delete this.components_[name];
}
public get joplin(): Joplin {
return this.joplin_;
}
public get imaging(): ImagingImplementation {
const createFromPdf = async (path: string, options: CreateFromPdfOptions) => {
const tempDir = join(Setting.value('tempDir'), uuid.createNano());
await shim.fsDriver().mkdir(tempDir);
try {
const paths = await shim.pdfToImages(path, tempDir, options);
return paths.map(path => nativeImage.createFromPath(path));
} finally {
await shim.fsDriver().remove(tempDir);
}
};
return {
createFromPath: async (path: string) => {
let pathToProcess = path;
let ext = fileExtension(path).toLowerCase();
if (hasProtocol(path, ['http', 'https', 'file'])) {
ext = fileExtension((new URL(path)).pathname);
const tempFilePath = `${Setting.value('tempDir')}/${uuidgen()}${ext ? `.${ext}` : ''}`;
await shim.fetchBlob(path, { path: tempFilePath });
pathToProcess = tempFilePath;
}
if (ext === 'pdf') {
const images = await createFromPdf(pathToProcess, { minPage: 1, maxPage: 1 });
if (images.length === 0) {
// Match the behavior or Electron's nativeImage when reading an invalid image.
return nativeImage.createEmpty();
}
return images[0];
} else {
return nativeImage.createFromPath(pathToProcess);
}
},
createFromPdf,
getPdfInfo(path: string) {
return shim.pdfInfo(path);
},
};
}
}