1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-10-31 00:07:48 +02:00

Chore: Refactor folder related functions to TypeScript

This commit is contained in:
Laurent Cozic
2024-01-06 17:21:51 +00:00
parent 68e04f944f
commit 763716397b
12 changed files with 116 additions and 104 deletions

View File

@@ -674,6 +674,7 @@ packages/lib/file-api-driver-memory.js
packages/lib/file-api-driver.test.js
packages/lib/file-api.test.js
packages/lib/file-api.js
packages/lib/folders-screen-utils.js
packages/lib/fs-driver-base.js
packages/lib/fs-driver-node.js
packages/lib/fsDriver.test.js

1
.gitignore vendored
View File

@@ -654,6 +654,7 @@ packages/lib/file-api-driver-memory.js
packages/lib/file-api-driver.test.js
packages/lib/file-api.test.js
packages/lib/file-api.js
packages/lib/folders-screen-utils.js
packages/lib/fs-driver-base.js
packages/lib/fs-driver-node.js
packages/lib/fsDriver.test.js

View File

@@ -1,5 +1,5 @@
const BaseApplication = require('@joplin/lib/BaseApplication').default;
const { FoldersScreenUtils } = require('@joplin/lib/folders-screen-utils.js');
const { refreshFolders } = require('@joplin/lib/folders-screen-utils.js');
const ResourceService = require('@joplin/lib/services/ResourceService').default;
const BaseModel = require('@joplin/lib/BaseModel').default;
const Folder = require('@joplin/lib/models/Folder').default;
@@ -435,7 +435,7 @@ class Application extends BaseApplication {
// initialised. So we manually call dispatchUpdateAll() to force an update.
Setting.dispatchUpdateAll();
await FoldersScreenUtils.refreshFolders();
await refreshFolders((action) => { this.store().dispatch(action); });
const tags = await Tag.allWithNotes();

View File

@@ -22,7 +22,6 @@ import stateToWhenClauseContext from './services/commands/stateToWhenClauseConte
import ResourceService from '@joplin/lib/services/ResourceService';
import ExternalEditWatcher from '@joplin/lib/services/ExternalEditWatcher';
import appReducer, { createAppDefaultState } from './app.reducer';
const { FoldersScreenUtils } = require('@joplin/lib/folders-screen-utils.js');
import Folder from '@joplin/lib/models/Folder';
import Tag from '@joplin/lib/models/Tag';
import { reg } from '@joplin/lib/registry';
@@ -72,6 +71,7 @@ import OcrService from '@joplin/lib/services/ocr/OcrService';
import OcrDriverTesseract from '@joplin/lib/services/ocr/drivers/OcrDriverTesseract';
import SearchEngine from '@joplin/lib/services/search/SearchEngine';
import { PackageInfo } from '@joplin/lib/versionInfo';
import { refreshFolders } from '@joplin/lib/folders-screen-utils';
const pluginClasses = [
require('./plugins/GotoAnything').default,
@@ -482,7 +482,7 @@ class Application extends BaseApplication {
// manually call dispatchUpdateAll() to force an update.
Setting.dispatchUpdateAll();
await FoldersScreenUtils.refreshFolders();
await refreshFolders((action: any) => this.dispatch(action));
const tags = await Tag.allWithNotes();

View File

@@ -122,6 +122,7 @@ import { ReactNode } from 'react';
import { parseShareCache } from '@joplin/lib/services/share/reducer';
import autodetectTheme, { onSystemColorSchemeChange } from './utils/autodetectTheme';
import runOnDeviceFsDriverTests from './utils/fs-driver/runOnDeviceTests';
import { refreshFolders } from '@joplin/lib/folders-screen-utils';
type SideMenuPosition = 'left' | 'right';
@@ -637,7 +638,7 @@ async function initialize(dispatch: Function) {
reg.logger().info('Loading folders...');
await FoldersScreenUtils.refreshFolders();
await refreshFolders((action: any) => dispatch(action));
const tags = await Tag.allWithNotes();
@@ -999,7 +1000,7 @@ class AppComponent extends React.Component {
public UNSAFE_componentWillReceiveProps(newProps: any) {
if (newProps.syncStarted !== this.lastSyncStarted_) {
if (!newProps.syncStarted) FoldersScreenUtils.refreshFolders();
if (!newProps.syncStarted) void refreshFolders((action: any) => this.props.dispatch(action));
this.lastSyncStarted_ = newProps.syncStarted;
}
}

View File

@@ -13,7 +13,7 @@ import SyncTargetOneDrive from './SyncTargetOneDrive';
import { createStore, applyMiddleware, Store } from 'redux';
const { defaultState, stateUtils } = require('./reducer');
import JoplinDatabase from './JoplinDatabase';
const { FoldersScreenUtils } = require('./folders-screen-utils.js');
import { cancelTimers as folderScreenUtilsCancelTimers, refreshFolders, scheduleRefreshFolders } from './folders-screen-utils';
const { DatabaseDriverNode } = require('./database-driver-node.js');
import BaseModel from './BaseModel';
import Folder from './models/Folder';
@@ -107,7 +107,7 @@ export default class BaseApplication {
await ResourceFetcher.instance().destroy();
await SearchEngine.instance().destroy();
await DecryptionWorker.instance().destroy();
await FoldersScreenUtils.cancelTimers();
await folderScreenUtilsCancelTimers();
await BaseItem.revisionService_.cancelTimers();
await ResourceService.instance().cancelTimers();
await reg.cancelTimers();
@@ -418,8 +418,7 @@ export default class BaseApplication {
const result = next(action);
let refreshNotes = false;
let refreshFolders: boolean | string = false;
// let refreshTags = false;
let doRefreshFolders: boolean | string = false;
let refreshNotesUseSelectedNoteId = false;
let refreshNotesHash = '';
@@ -434,7 +433,7 @@ export default class BaseApplication {
// Don't add FOLDER_UPDATE_ALL as refreshFolders() is calling it too, which
// would cause the sidebar to refresh all the time.
if (this.hasGui() && ['FOLDER_UPDATE_ONE'].indexOf(action.type) >= 0) {
refreshFolders = true;
doRefreshFolders = true;
}
if (action.type === 'HISTORY_BACKWARD' || action.type === 'HISTORY_FORWARD') {
@@ -510,23 +509,23 @@ export default class BaseApplication {
action.changedFields.includes('encryption_applied') ||
action.changedFields.includes('is_conflict')
) {
refreshFolders = true;
doRefreshFolders = true;
}
}
if (action.type === 'NOTE_DELETE') {
refreshFolders = true;
doRefreshFolders = true;
}
if (this.hasGui() && action.type === 'SETTING_UPDATE_ALL') {
refreshFolders = 'now';
doRefreshFolders = 'now';
}
if (this.hasGui() && action.type === 'SETTING_UPDATE_ONE' && (
action.key.indexOf('folders.sortOrder') === 0 ||
action.key === 'showNoteCounts' ||
action.key === 'showCompletedTodos')) {
refreshFolders = 'now';
doRefreshFolders = 'now';
}
if (this.hasGui() && action.type === 'SYNC_GOT_ENCRYPTED_ITEM') {
@@ -543,11 +542,11 @@ export default class BaseApplication {
await this.applySettingsSideEffects();
}
if (refreshFolders) {
if (refreshFolders === 'now') {
await FoldersScreenUtils.refreshFolders();
if (doRefreshFolders) {
if (doRefreshFolders === 'now') {
await refreshFolders((action: any) => this.dispatch(action));
} else {
await FoldersScreenUtils.scheduleRefreshFolders();
await scheduleRefreshFolders((action: any) => this.dispatch(action));
}
}
return result;
@@ -571,8 +570,6 @@ export default class BaseApplication {
});
BaseModel.dispatch = this.store().dispatch;
FoldersScreenUtils.dispatch = this.store().dispatch;
// reg.dispatch = this.store().dispatch;
BaseSyncTarget.dispatch = this.store().dispatch;
DecryptionWorker.instance().dispatch = this.store().dispatch;
ResourceFetcher.instance().dispatch = this.store().dispatch;
@@ -582,8 +579,6 @@ export default class BaseApplication {
public deinitRedux() {
this.store_ = null;
BaseModel.dispatch = function() {};
FoldersScreenUtils.dispatch = function() {};
// reg.dispatch = function() {};
BaseSyncTarget.dispatch = function() {};
DecryptionWorker.instance().dispatch = function() {};
ResourceFetcher.instance().dispatch = function() {};

View File

@@ -1,5 +1,4 @@
import paginationToSql from './models/utils/paginationToSql';
import Database from './database';
import uuid from './uuid';
import time from './time';
@@ -271,11 +270,15 @@ class BaseModel {
return this.modelSelectAll(`SELECT * FROM \`${this.tableName()}\` WHERE \`id\` LIKE ?`, [`${partialId}%`]);
}
public static applySqlOptions(options: any, sql: string, params: any[] = null) {
public static applySqlOptions(options: LoadOptions, sql: string, params: any[] = null) {
if (!options) options = {};
if (options.order && options.order.length) {
sql += ` ORDER BY ${paginationToSql(options)}`;
sql += ` ORDER BY ${paginationToSql({
limit: options.limit,
order: options.order as any,
page: 1,
})}`;
}
if (options.limit) sql += ` LIMIT ${options.limit}`;
@@ -289,7 +292,7 @@ class BaseModel {
return rows.map((r: any) => r.id);
}
public static async all(options: any = null) {
public static async all(options: LoadOptions = null) {
if (!options) options = {};
if (!options.fields) options.fields = '*';

View File

@@ -1,75 +0,0 @@
const Folder = require('./models/Folder').default;
const Setting = require('./models/Setting').default;
const shim = require('./shim').default;
class FoldersScreenUtils {
static async allForDisplay(options = {}) {
const orderDir = Setting.value('folders.sortOrder.reverse') ? 'DESC' : 'ASC';
const folderOptions = {
caseInsensitive: true,
order: [
{
by: 'title',
dir: orderDir,
},
],
...options,
};
let folders = await Folder.all(folderOptions);
if (Setting.value('folders.sortOrder.field') === 'last_note_user_updated_time') {
folders = await Folder.orderByLastModified(folders, orderDir);
}
if (Setting.value('showNoteCounts')) {
await Folder.addNoteCounts(folders,
Setting.value('showCompletedTodos'));
}
return folders;
}
static async refreshFolders() {
FoldersScreenUtils.refreshCalls_.push(true);
try {
const folders = await this.allForDisplay({ includeConflictFolder: true });
this.dispatch({
type: 'FOLDER_UPDATE_ALL',
items: folders,
});
} finally {
FoldersScreenUtils.refreshCalls_.pop();
}
}
static scheduleRefreshFolders() {
if (this.scheduleRefreshFoldersIID_) shim.clearTimeout(this.scheduleRefreshFoldersIID_);
this.scheduleRefreshFoldersIID_ = shim.setTimeout(() => {
this.scheduleRefreshFoldersIID_ = null;
this.refreshFolders();
}, 1000);
}
static async cancelTimers() {
if (this.scheduleRefreshFoldersIID_) {
shim.clearTimeout(this.scheduleRefreshFoldersIID_);
this.scheduleRefreshFoldersIID_ = null;
}
return new Promise((resolve) => {
const iid = shim.setInterval(() => {
if (!FoldersScreenUtils.refreshCalls_.length) {
shim.clearInterval(iid);
resolve();
}
}, 100);
});
}
}
FoldersScreenUtils.refreshCalls_ = [];
module.exports = { FoldersScreenUtils };

View File

@@ -0,0 +1,73 @@
import { Dispatch } from 'redux';
import Folder from './models/Folder';
import Setting from './models/Setting';
import shim from './shim';
import { FolderLoadOptions } from './models/utils/types';
const refreshCalls_: boolean[] = [];
let scheduleRefreshFoldersIID_: any = null;
export const allForDisplay = async (options: FolderLoadOptions = {}) => {
const orderDir = Setting.value('folders.sortOrder.reverse') ? 'DESC' : 'ASC';
const folderOptions: FolderLoadOptions = {
caseInsensitive: true,
order: [
{
by: 'title',
dir: orderDir,
},
],
...options,
};
let folders = await Folder.all(folderOptions);
if (Setting.value('folders.sortOrder.field') === 'last_note_user_updated_time') {
folders = await Folder.orderByLastModified(folders, orderDir);
}
if (Setting.value('showNoteCounts')) {
await Folder.addNoteCounts(folders,
Setting.value('showCompletedTodos'));
}
return folders;
};
export const refreshFolders = async (dispatch: Dispatch) => {
refreshCalls_.push(true);
try {
const folders = await allForDisplay({ includeConflictFolder: true });
dispatch({
type: 'FOLDER_UPDATE_ALL',
items: folders,
});
} finally {
refreshCalls_.pop();
}
};
export const scheduleRefreshFolders = async (dispatch: Dispatch) => {
if (scheduleRefreshFoldersIID_) shim.clearTimeout(scheduleRefreshFoldersIID_);
scheduleRefreshFoldersIID_ = shim.setTimeout(() => {
scheduleRefreshFoldersIID_ = null;
void refreshFolders(dispatch);
}, 1000);
};
export const cancelTimers = async () => {
if (scheduleRefreshFoldersIID_) {
shim.clearTimeout(scheduleRefreshFoldersIID_);
scheduleRefreshFoldersIID_ = null;
}
return new Promise((resolve) => {
const iid = shim.setInterval(() => {
if (!refreshCalls_.length) {
shim.clearInterval(iid);
resolve(null);
}
}, 100);
});
};

View File

@@ -1,5 +1,6 @@
import { defaultFolderIcon, FolderEntity, FolderIcon, NoteEntity, ResourceEntity } from '../services/database/types';
import BaseModel, { DeleteOptions } from '../BaseModel';
import { FolderLoadOptions } from './utils/types';
import time from '../time';
import { _ } from '../locale';
import Note from './Note';
@@ -249,7 +250,7 @@ export default class Folder extends BaseItem {
return output;
}
public static async all(options: any = null) {
public static async all(options: FolderLoadOptions = null) {
const output = await super.all(options);
if (options && options.includeConflictFolder) {
const conflictCount = await Note.conflictedCount();

View File

@@ -21,6 +21,18 @@ export interface Pagination {
export interface LoadOptions {
caseInsensitive?: boolean;
fields?: string | string[];
where?: string;
whereParams?: any[];
order?: {
by: string;
dir: string;
caseInsensitive?: boolean;
}[];
limit?: number;
}
export interface FolderLoadOptions extends LoadOptions {
includeConflictFolder?: boolean;
}
export interface SaveOptions {

View File

@@ -296,7 +296,7 @@ export default class ReportService {
section = { title: _('Folders'), body: [] };
const folders = await Folder.all({
order: { by: 'title', dir: 'ASC' },
order: [{ by: 'title', dir: 'ASC' }],
caseInsensitive: true,
});