From 8ee6152c3c8ba2e594f27e381aab6baa444d50e8 Mon Sep 17 00:00:00 2001 From: ransome1 Date: Tue, 2 Apr 2024 20:11:49 +0200 Subject: [PATCH] Refactoring --- src/__tests__/__mock__/recurrence.txt | 28 +-- src/__tests__/__mock__/test.txt | 13 +- src/__tests__/main/Archive.tsx | 24 +- src/__tests__/main/CreateRecurringTodo.tsx | 90 +++---- src/__tests__/main/Dialog.tsx | 8 +- src/__tests__/main/Filters.tsx | 6 + src/__tests__/main/ProcessTodoObjects.tsx | 51 ++-- src/__tests__/main/Write.tsx | 235 +++++++++--------- src/main/config.tsx | 28 ++- src/main/main.tsx | 13 +- src/main/modules/File/Archive.tsx | 18 +- src/main/modules/File/Dialog.tsx | 25 +- src/main/modules/File/File.tsx | 14 +- src/main/modules/File/Watcher.tsx | 12 +- src/main/modules/File/Write.tsx | 25 +- src/main/modules/Filters/Filters.tsx | 14 +- src/main/modules/IpcMain.tsx | 135 +++++----- .../ChangeCompleteState.tsx | 2 +- .../ProcessDataRequest/CreateTodoObjects.tsx | 12 +- .../ProcessDataRequest/ProcessDataRequest.tsx | 32 ++- .../ProcessDataRequest/ProcessTodoObjects.tsx | 19 +- src/main/util.tsx | 8 +- src/renderer/SplashScreen.tsx | 2 +- src/types.tsx | 3 + yarn.lock | 99 ++++---- 25 files changed, 458 insertions(+), 458 deletions(-) diff --git a/src/__tests__/__mock__/recurrence.txt b/src/__tests__/__mock__/recurrence.txt index 72a81458..118f796e 100644 --- a/src/__tests__/__mock__/recurrence.txt +++ b/src/__tests__/__mock__/recurrence.txt @@ -1,15 +1,15 @@ -2024-04-01 Line 1 rec:1d due:2024-04-02 -2024-04-01 Line 1 rec:w due:2024-04-08 -2024-04-01 Line 1 rec:2m due:2024-06-01 -2024-04-01 Line 1 rec:+1d due:2024-04-03 -2024-04-01 Line 1 rec:7w due:2024-05-20 -2024-04-01 Line 1 due:2023-07-24 rec:+1b -2024-04-01 taxes are due in one year t:2022-03-30 due:2022-04-30 rec:+1y -2024-04-01 Water plants @home +quick due:2024-04-08 t:2024-03-29 rec:1w -2024-04-01 Line 1 rec:+1d t:2023-09-20 -2024-04-01 Line 1 rec:1d pri:A due:2024-04-02 -2024-04-01 (A) Do something rec:d t:2024-04-02 @SomeContext -2024-04-01 Do something rec:0d -2024-04-01 Do something rec:0d due:2024-04-01 -2024-04-01 Do something rec:0d due:2024-04-01 t:2024-04-01 \ No newline at end of file +2024-04-02 Line 1 rec:1d due:2024-04-03 +2024-04-02 Line 1 rec:w due:2024-04-09 +2024-04-02 Line 1 rec:2m due:2024-06-02 +2024-04-02 Line 1 rec:+1d due:2024-04-04 +2024-04-02 Line 1 rec:7w due:2024-05-21 +2024-04-02 Line 1 due:2023-07-24 rec:+1b +2024-04-02 taxes are due in one year t:2022-03-30 due:2022-04-30 rec:+1y +2024-04-02 Water plants @home +quick due:2024-04-09 t:2024-03-30 rec:1w +2024-04-02 Line 1 rec:+1d t:2023-09-20 +2024-04-02 Line 1 rec:1d pri:A due:2024-04-03 +2024-04-02 (A) Do something rec:d t:2024-04-03 @SomeContext +2024-04-02 Do something rec:0d +2024-04-02 Do something rec:0d due:2024-04-02 +2024-04-02 Do something rec:0d due:2024-04-02 t:2024-04-02 \ No newline at end of file diff --git a/src/__tests__/__mock__/test.txt b/src/__tests__/__mock__/test.txt index 80735e7e..40ceba3b 100644 --- a/src/__tests__/__mock__/test.txt +++ b/src/__tests__/__mock__/test.txt @@ -1,4 +1,11 @@ Line 1 -Line 2 -Line 3 -New line \ No newline at end of file +Edited line +Multi line 1Multi line 2Multi line 3 +Updated line +Append 1 +Append 2 +New line with relative threshold date t:June 3rd, 2005 +Line4 +Line5 +Line6 +Multi line 1Multi line 2Multi line 3 \ No newline at end of file diff --git a/src/__tests__/main/Archive.tsx b/src/__tests__/main/Archive.tsx index 7825e133..fddeb2d9 100644 --- a/src/__tests__/main/Archive.tsx +++ b/src/__tests__/main/Archive.tsx @@ -1,5 +1,5 @@ import { archiveTodos } from '../../main/modules/File/Archive'; -import fs from 'fs/promises'; +import fs from 'fs'; jest.mock('electron', () => ({ app: { @@ -33,22 +33,22 @@ jest.mock('../../main/modules/Menu', () => ({ })); describe('Archiving', () => { - beforeEach(async() => { + beforeEach(() => { jest.clearAllMocks(); - await fs.writeFile('./src/__tests__/__mock__/archiving.txt', `Unfinished todo 1\nx 2022-02-01 Finished todo 3\nUnfinished todo 2\nx 2022-02-08 Finished todo 1\nUnfinished todo 3\nx 2022-02-17 Finished todo 2`, 'utf8'); - await fs.writeFile('./src/__tests__/__mock__/done.txt', `x 2022-02-02 todo from done.txt 1\nx 2022-02-03 todo from done.txt 2\nx 2022-02-04 todo from done.txt 3\nx 2022-02-05 todo from done.txt 4`, 'utf8'); + fs.writeFileSync('./src/__tests__/__mock__/archiving.txt', `Unfinished todo 1\nx 2022-02-01 Finished todo 3\nUnfinished todo 2\nx 2022-02-08 Finished todo 1\nUnfinished todo 3\nx 2022-02-17 Finished todo 2`, 'utf8'); + fs.writeFileSync('./src/__tests__/__mock__/done.txt', `x 2022-02-02 todo from done.txt 1\nx 2022-02-03 todo from done.txt 2\nx 2022-02-04 todo from done.txt 3\nx 2022-02-05 todo from done.txt 4`, 'utf8'); }); - afterAll(async () => { - await fs.unlink('./src/__tests__/__mock__/archiving.txt'); - await fs.unlink('./src/__tests__/__mock__/done.txt'); + afterAll(() => { + fs.unlinkSync('./src/__tests__/__mock__/archiving.txt'); + fs.unlinkSync('./src/__tests__/__mock__/done.txt'); }); - test('Should collect data from todo and done file and merge it properly', async () => { - await archiveTodos(); - const fileContent = await fs.readFile('./src/__tests__/__mock__/done.txt', 'utf8'); + test('Should collect data from todo and done file and merge it properly', () => { + archiveTodos(); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/done.txt', 'utf8'); const expectedContent = `x 2022-02-02 todo from done.txt 1\nx 2022-02-03 todo from done.txt 2\nx 2022-02-04 todo from done.txt 3\nx 2022-02-05 todo from done.txt 4\nx 2022-02-01 Finished todo 3\nx 2022-02-08 Finished todo 1\nx 2022-02-17 Finished todo 2`; - await new Promise((resolve) => setTimeout(resolve, 1000)); - expect(fileContent).toEqual(expectedContent); + //await new Promise((resolve) => setTimeout(resolve, 1000)); + setTimeout(() => expect(fileContent).toEqual(expectedContent), 1000); }); }); \ No newline at end of file diff --git a/src/__tests__/main/CreateRecurringTodo.tsx b/src/__tests__/main/CreateRecurringTodo.tsx index edbcfb53..d8fbddb6 100644 --- a/src/__tests__/main/CreateRecurringTodo.tsx +++ b/src/__tests__/main/CreateRecurringTodo.tsx @@ -1,4 +1,4 @@ -import fs from 'fs/promises'; +import fs from 'fs'; import { createRecurringTodo } from '../../main/modules/ProcessDataRequest/CreateRecurringTodo'; import dayjs from 'dayjs'; @@ -32,92 +32,92 @@ const dateTodayInTwoMonths = dateToday.add(2, 'month').format('YYYY-MM-DD'); const dateTodayInSevenWeeks = dateToday.add(7, 'week').format('YYYY-MM-DD'); describe('Create recurring todos', () => { - beforeEach(async () => { + beforeEach(() => { jest.clearAllMocks(); - await fs.writeFile('./src/__tests__/__mock__/recurrence.txt', ''); + fs.writeFileSync('./src/__tests__/__mock__/recurrence.txt', ''); }); - test('Should add a new todo with due date set to tomorrow', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:1d`, '1d'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo with due date set to tomorrow', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:1d`, '1d'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(dateTodayString + ' Line 1 rec:1d due:' + dateTomorrowString); }); - test('Should add a new todo with due date set to next week', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:w`, 'w'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo with due date set to next week', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:w`, 'w'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(dateTodayString + ' Line 1 rec:w due:' + dateInOneWeekString); }); - test('Should add a new todo with due date set to today in 2 months', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:2m`, '2m'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo with due date set to today in 2 months', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:2m`, '2m'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(dateTodayString + ' Line 1 rec:2m due:' + dateTodayInTwoMonths); }); - test('Should add a new todo with due date set to day after tomorrow', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:+1d due:${dateTomorrowString}`, '+1d'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo with due date set to day after tomorrow', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:+1d due:${dateTomorrowString}`, '+1d'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(dateTodayString + ' Line 1 rec:+1d due:' + dateDayAfterTomorrowString); }); - test('Should add a new todo with due date set to today in 7 weeks', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:7w due:${dateTomorrowString}`, '7w'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo with due date set to today in 7 weeks', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:7w due:${dateTomorrowString}`, '7w'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(dateTodayString + ' Line 1 rec:7w due:' + dateTodayInSevenWeeks); }); - test('Should add a new todo with due date set to next possible business day, based off a todo which already contains a due date', async () => { - await createRecurringTodo(`x 2023-07-21 2023-07-21 Line 1 due:2023-07-21 rec:+1b`, '+1b'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo with due date set to next possible business day, based off a todo which already contains a due date', () => { + createRecurringTodo(`x 2023-07-21 2023-07-21 Line 1 due:2023-07-21 rec:+1b`, '+1b'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(`${dateTodayString} Line 1 due:2023-07-24 rec:+1b`); }); - test('Should add a new todo adding a strict recurrence of one year to due date and threshold date', async () => { - await createRecurringTodo(`x 2021-01-01 2021-01-01 taxes are due in one year t:2021-03-30 due:2021-04-30 rec:+1y`, '+1y'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo adding a strict recurrence of one year to due date and threshold date', () => { + createRecurringTodo(`x 2021-01-01 2021-01-01 taxes are due in one year t:2021-03-30 due:2021-04-30 rec:+1y`, '+1y'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(`${dateTodayString} taxes are due in one year t:2022-03-30 due:2022-04-30 rec:+1y`); }); - test('Should add a new todo adding a non-strict recurrence of one week to due date and threshold date', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Water plants @home +quick due:2021-07-19 t:2021-07-09 rec:1w`, '1w'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo adding a non-strict recurrence of one week to due date and threshold date', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Water plants @home +quick due:2021-07-19 t:2021-07-09 rec:1w`, '1w'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(`${dateTodayString} Water plants @home +quick due:${dateInOneWeekString} t:${dateInOneWeekMinus10String} rec:1w`); }); - test('Should add a new todo adding a strict recurrence of one day to threshold date. No due date should be created.', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:+1d t:2023-09-19`, '+1d'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo adding a strict recurrence of one day to threshold date. No due date should be created.', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:+1d t:2023-09-19`, '+1d'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(`${dateTodayString} Line 1 rec:+1d t:2023-09-20`); }); - test('Should add a new todo and preserve the priority in the pri extension, but should not set the priority (A) for the task.', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:1d pri:A`, '1d'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo and preserve the priority in the pri extension, but should not set the priority (A) for the task.', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Line 1 rec:1d pri:A`, '1d'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(`${dateTodayString} Line 1 rec:1d pri:A due:${dateTomorrowString}`); }); - test('Should add a new todo based on a daily recurrence and a threshold date set for today, without unwanted due date and priority labels', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} (A) Do something rec:d t:${dateTodayString} @SomeContext`, 'd'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo based on a daily recurrence and a threshold date set for today, without unwanted due date and priority labels', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} (A) Do something rec:d t:${dateTodayString} @SomeContext`, 'd'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(`${dateTodayString} (A) Do something rec:d t:${dateTomorrowString} @SomeContext`); }); - test('Should add a new todo based on a zero daily recurrence and no due date and no threshold date are set', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Do something rec:0d`, '0d'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo based on a zero daily recurrence and no due date and no threshold date are set', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Do something rec:0d`, '0d'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(`${dateTodayString} Do something rec:0d`); }); - test('Should add a new todo based on a zero daily recurrence and a due date of today is set', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Do something rec:0d due:1999-11-11`, '0d'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo based on a zero daily recurrence and a due date of today is set', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Do something rec:0d due:1999-11-11`, '0d'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(`${dateTodayString} Do something rec:0d due:${dateTodayString}`); }); - test('Should add a new todo based on a zero daily recurrence and a due date and a threshold date of today are set', async () => { - await createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Do something rec:0d due:1999-11-11 t:2010-03-05`, '0d'); - const fileContent = await fs.readFile('./src/__tests__/__mock__/recurrence.txt', 'utf8'); + test('Should add a new todo based on a zero daily recurrence and a due date and a threshold date of today are set', () => { + createRecurringTodo(`x ${dateTodayString} ${dateTodayString} Do something rec:0d due:1999-11-11 t:2010-03-05`, '0d'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/recurrence.txt', 'utf8'); expect(fileContent.split('\n').pop()).toEqual(`${dateTodayString} Do something rec:0d due:${dateTodayString} t:${dateTodayString}`); }); diff --git a/src/__tests__/main/Dialog.tsx b/src/__tests__/main/Dialog.tsx index 852cefb3..4b505429 100644 --- a/src/__tests__/main/Dialog.tsx +++ b/src/__tests__/main/Dialog.tsx @@ -1,7 +1,7 @@ import { dialog } from 'electron'; import { openFile, createFile } from '../../main/modules/File/Dialog'; import { addFile } from '../../main/modules/File/File'; -import fs from 'fs/promises'; +import fs from 'fs'; jest.mock('../../main/main', () => ({ mainWindow: jest.fn(), @@ -36,8 +36,8 @@ jest.mock('../../main/modules/File/File', () => ({ addFile: jest.fn(), })); -jest.mock('fs/promises', () => ({ - writeFile: jest.fn(), +jest.mock('fs', () => ({ + writeFileSync: jest.fn(), })); describe('openFile', () => { @@ -90,7 +90,7 @@ describe('createFile', () => { filters: [{ name: 'Text files', extensions: ['txt'] }, { name: 'All files', extensions: ['*'] }], }); - expect(fs.writeFile).toHaveBeenCalledWith('./src/__tests__/__mock__/fileDialog.txt', '', 'utf8'); + expect(fs.writeFileSync).toHaveBeenCalledWith('./src/__tests__/__mock__/fileDialog.txt', '', 'utf-8'); expect(addFile).toHaveBeenCalledWith('./src/__tests__/__mock__/fileDialog.txt', null); }); diff --git a/src/__tests__/main/Filters.tsx b/src/__tests__/main/Filters.tsx index 21918bb0..ebdb1e51 100644 --- a/src/__tests__/main/Filters.tsx +++ b/src/__tests__/main/Filters.tsx @@ -1,5 +1,11 @@ import { applyAttributes } from '../../main/modules/Filters/Filters'; +jest.mock('../../main/config', () => ({ + config: { + get: jest.fn() + }, +})); + describe('Should filter todos based on passed filters', () => { const todoObjects = [ { id: 1, body: 'Test', created: null, complete: false, completed: null, priority: null, contexts: null, projects: ['Project 1'], due: '2023-01-01', dueString: '2023-01-01', t: null, tString: null, rec: null, hidden: false, pm: null, visible: true, string: '' }, diff --git a/src/__tests__/main/ProcessTodoObjects.tsx b/src/__tests__/main/ProcessTodoObjects.tsx index 0e4c0f4b..cbfab1d2 100644 --- a/src/__tests__/main/ProcessTodoObjects.tsx +++ b/src/__tests__/main/ProcessTodoObjects.tsx @@ -1,7 +1,7 @@ -import fs from 'fs/promises'; +import fs from 'fs'; import { createTodoObjects } from '../../main/modules/ProcessDataRequest/CreateTodoObjects'; import { applySearchString } from '../../main/modules/Filters/Search'; -import { countTodoObjects, sortAndGroupTodoObjects, flattenTodoObjects } from '../../main/modules/ProcessDataRequest/ProcessTodoObjects'; +import { sortAndGroupTodoObjects, flattenTodoObjects } from '../../main/modules/ProcessDataRequest/ProcessTodoObjects'; jest.mock('../../main/config', () => ({ config: { @@ -73,56 +73,59 @@ let fileContent: string; describe('Process todo.txt objects', () => { - beforeAll(async() => { + beforeAll(() => { jest.clearAllMocks(); - fileContent = await fs.readFile('./src/__tests__/__mock__/todo.txt', 'utf8'); - todoObjects = await createTodoObjects(fileContent); + fileContent = fs.readFileSync('./src/__tests__/__mock__/todo.txt', 'utf8'); + todoObjects = createTodoObjects(fileContent); }); - beforeEach(async() => { - todoObjects = await createTodoObjects(fileContent); - }); - - test('Todo objects are counted correctly', async () => { - const headers: HeadersObject = countTodoObjects(todoObjects); - expect(headers.availableObjects).toEqual(7); - expect(headers.visibleObjects).toEqual(7); - expect(headers.completedObjects).toEqual(1); + beforeEach(() => { + todoObjects = createTodoObjects(fileContent); }); test('Search for "test3"', () => { const searchString: string = 'test3'; todoObjects = applySearchString(searchString, todoObjects); - const headers: HeadersObject = countTodoObjects(todoObjects); - expect(headers.visibleObjects).toEqual(4); + const visibleTodoObjects: TodoObject[] = todoObjects.filter((todoObject: TodoObject) => { + return todoObject.visible; + }); + expect(visibleTodoObjects.length).toEqual(4); }); test('Search for "lorem"', () => { const searchString: string = 'lorem'; todoObjects = applySearchString(searchString, todoObjects); - const headers: HeadersObject = countTodoObjects(todoObjects); - expect(headers.visibleObjects).toEqual(0); + const visibleTodoObjects: TodoObject[] = todoObjects.filter((todoObject: TodoObject) => { + return todoObject.visible; + }); + expect(visibleTodoObjects.length).toEqual(0); }); test('Advanced search for "+testProject4 or +testProject2"', () => { const searchString: string = '+testProject4 or +testProject2'; todoObjects = applySearchString(searchString, todoObjects); - const headers: HeadersObject = countTodoObjects(todoObjects); - expect(headers.visibleObjects).toEqual(2); + const visibleTodoObjects: TodoObject[] = todoObjects.filter((todoObject: TodoObject) => { + return todoObject.visible; + }); + expect(visibleTodoObjects.length).toEqual(2); }); test('Advanced search for "+testProject4 and +testProject2" result in 0 found objects', () => { const searchString:string = '+testProject4 and +testProject2'; todoObjects = applySearchString(searchString, todoObjects); - const headers: HeadersObject = countTodoObjects(todoObjects); - expect(headers.visibleObjects).toEqual(0); + const visibleTodoObjects: TodoObject[] = todoObjects.filter((todoObject: TodoObject) => { + return todoObject.visible; + }); + expect(visibleTodoObjects.length).toEqual(0); }); test('Advanced search for "+testProject4 and !+testProject2" result in 1 found objects', () => { const searchString:string = '+testProject4 and !+testProject2'; todoObjects = applySearchString(searchString, todoObjects); - const headers: HeadersObject = countTodoObjects(todoObjects); - expect(headers.visibleObjects).toEqual(1); + const visibleTodoObjects: TodoObject[] = todoObjects.filter((todoObject: TodoObject) => { + return todoObject.visible; + }); + expect(visibleTodoObjects.length).toEqual(1); }); test('Function creates 3 top level groups (A, B, C)', () => { diff --git a/src/__tests__/main/Write.tsx b/src/__tests__/main/Write.tsx index 42c353e3..f9d397a2 100644 --- a/src/__tests__/main/Write.tsx +++ b/src/__tests__/main/Write.tsx @@ -40,126 +40,121 @@ describe('Writing to file', () => { test('should write a new line when id is not provided', () => { prepareContentForWriting(-1, 'New line'); - //const fileContent = fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - fs.readFile('./src/__tests__/__mock__/test.txt', (error, data) => { - if (error) throw error; - console.log(data) - //expect(data).toEqual('Line 1\nLine 2\nLine 3\nNew line'); - //console.log(data); - }); + const data = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf-8'); + expect(data).toEqual('Line 1\nLine 2\nLine 3\nNew line'); }); - // test('should write a new line when id is not provided and append a creation date', async () => { - // const originalGet = config.get; - // config.get = (key: string) => { - // if(key === 'appendCreationDate') { - // return true; - // } - // return originalGet.call(config, key); - // }; - // await prepareContentForWriting(-1, 'New line with creation date'); - // const fileContent = await fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - // expect(fileContent).toEqual(`Line 1\nLine 2\nLine 3\nNew line\n${date} New line with creation date`); - // config.get = originalGet; - // }); - - // test('should write a new line when id is not provided and convert a relative (speaking) date to an absolute date', async () => { - // await prepareContentForWriting(-1, 'New line with relative threshold date t:June 3rd, 2005'); - // const fileContent = await fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - // expect(fileContent).toEqual(`Line 1\nLine 2\nLine 3\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:2005-06-03`); - // }); - - // test('should overwrite a line when id is provided and NOT convert a relative (speaking) date to an absolute date', async () => { - // const originalGet = config.get; - // config.get = (key: string) => { - // if(key === 'convertRelativeToAbsoluteDates') { - // return false; - // } - // return originalGet.call(config, key); - // }; - // await prepareContentForWriting(5, 'New line with relative threshold date t:June 3rd, 2005'); - // const fileContent = await fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - // expect(fileContent).toEqual(`Line 1\nLine 2\nLine 3\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:June 3rd, 2005`); - // config.get = originalGet; - // }); - - // test('should overwrite a line when id is provided', async () => { - // await prepareContentForWriting(1, 'Edited line'); - // const fileContent = await fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - // expect(fileContent).toEqual(`Line 1\nEdited line\nLine 3\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:June 3rd, 2005`); - // }); - - // test('should delete a line when remove is true', async () => { - // removeLineFromFile(2); - // const fileContent = await fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - // expect(fileContent).toEqual(`Line 1\nEdited line\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:June 3rd, 2005`); - // }); - - // test('should append 3 new lines at the end of the file', async () => { - // const originalGet = config.get; - // config.get = (key: string) => { - // if(key === 'bulkTodoCreation') { - // return true; - // } - // return originalGet.call(config, key); - // }; - - // const content = 'Line4\nLine5\nLine6'; - - // await prepareContentForWriting(-1, content); - // const fileContent = await fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - // expect(fileContent).toEqual(`Line 1\nEdited line\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:June 3rd, 2005\nLine4\nLine5\nLine6`); - // config.get = originalGet; - // }); - - // test('should update a specific line and append 2 lines to the updated line', async () => { - // const originalGet = config.get; - // config.get = (key: string) => { - // if(key === 'bulkTodoCreation') { - // return true; - // } - // return originalGet.call(config, key); - // }; - - // const content = 'Updated line\nAppend 1\nAppend 2'; - - // await prepareContentForWriting(3, content); - // const fileContent = await fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - // expect(fileContent).toEqual(`Line 1\nEdited line\nNew line\nUpdated line\nAppend 1\nAppend 2\nNew line with relative threshold date t:June 3rd, 2005\nLine4\nLine5\nLine6`); - // config.get = originalGet; - // }); - - // test('should append a multi line todo', async () => { - // const originalGet = config.get; - // config.get = (key: string) => { - // if(key === 'bulkTodoCreation') { - // return false; - // } - // return originalGet.call(config, key); - // }; - - // const content = 'Multi line 1\nMulti line 2\nMulti line 3'; - - // await prepareContentForWriting(-1, content); - // const fileContent = await fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - // expect(fileContent).toEqual(`Line 1\nEdited line\nNew line\nUpdated line\nAppend 1\nAppend 2\nNew line with relative threshold date t:June 3rd, 2005\nLine4\nLine5\nLine6\nMulti line 1Multi line 2Multi line 3`); - // config.get = originalGet; - // }); - - // test('should update line with a multi line todo', async () => { - // const originalGet = config.get; - // config.get = (key: string) => { - // if(key === 'bulkTodoCreation') { - // return false; - // } - // return originalGet.call(config, key); - // }; - - // const content = 'Multi line 1\nMulti line 2\nMulti line 3'; - - // await prepareContentForWriting(2, content); - // const fileContent = await fs.readFile('./src/__tests__/__mock__/test.txt', 'utf8'); - // expect(fileContent).toEqual(`Line 1\nEdited line\nMulti line 1Multi line 2Multi line 3\nUpdated line\nAppend 1\nAppend 2\nNew line with relative threshold date t:June 3rd, 2005\nLine4\nLine5\nLine6\nMulti line 1Multi line 2Multi line 3`); - // config.get = originalGet; - // }); + test('should write a new line when id is not provided and append a creation date', () => { + const originalGet = config.get; + config.get = (key: string) => { + if(key === 'appendCreationDate') { + return true; + } + return originalGet.call(config, key); + }; + prepareContentForWriting(-1, 'New line with creation date'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf8'); + expect(fileContent).toEqual(`Line 1\nLine 2\nLine 3\nNew line\n${date} New line with creation date`); + config.get = originalGet; + }); + + test('should write a new line when id is not provided and convert a relative (speaking) date to an absolute date', () => { + prepareContentForWriting(-1, 'New line with relative threshold date t:June 3rd, 2005'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf8'); + expect(fileContent).toEqual(`Line 1\nLine 2\nLine 3\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:2005-06-03`); + }); + + test('should overwrite a line when id is provided and NOT convert a relative (speaking) date to an absolute date', () => { + const originalGet = config.get; + config.get = (key: string) => { + if(key === 'convertRelativeToAbsoluteDates') { + return false; + } + return originalGet.call(config, key); + }; + prepareContentForWriting(5, 'New line with relative threshold date t:June 3rd, 2005'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf8'); + expect(fileContent).toEqual(`Line 1\nLine 2\nLine 3\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:June 3rd, 2005`); + config.get = originalGet; + }); + + test('should overwrite a line when id is provided', () => { + prepareContentForWriting(1, 'Edited line'); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf8'); + expect(fileContent).toEqual(`Line 1\nEdited line\nLine 3\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:June 3rd, 2005`); + }); + + test('should delete a line when remove is true', () => { + removeLineFromFile(2); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf8'); + expect(fileContent).toEqual(`Line 1\nEdited line\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:June 3rd, 2005`); + }); + + test('should append 3 new lines at the end of the file', () => { + const originalGet = config.get; + config.get = (key: string) => { + if(key === 'bulkTodoCreation') { + return true; + } + return originalGet.call(config, key); + }; + + const content = 'Line4\nLine5\nLine6'; + + prepareContentForWriting(-1, content); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf8'); + expect(fileContent).toEqual(`Line 1\nEdited line\nNew line\n${date} New line with creation date\nNew line with relative threshold date t:June 3rd, 2005\nLine4\nLine5\nLine6`); + config.get = originalGet; + }); + + test('should update a specific line and append 2 lines to the updated line', () => { + const originalGet = config.get; + config.get = (key: string) => { + if(key === 'bulkTodoCreation') { + return true; + } + return originalGet.call(config, key); + }; + + const content = 'Updated line\nAppend 1\nAppend 2'; + + prepareContentForWriting(3, content); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf8'); + expect(fileContent).toEqual(`Line 1\nEdited line\nNew line\nUpdated line\nAppend 1\nAppend 2\nNew line with relative threshold date t:June 3rd, 2005\nLine4\nLine5\nLine6`); + config.get = originalGet; + }); + + test('should append a multi line todo', async () => { + const originalGet = config.get; + config.get = (key: string) => { + if(key === 'bulkTodoCreation') { + return false; + } + return originalGet.call(config, key); + }; + + const content = 'Multi line 1\nMulti line 2\nMulti line 3'; + + prepareContentForWriting(-1, content); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf8'); + expect(fileContent).toEqual(`Line 1\nEdited line\nNew line\nUpdated line\nAppend 1\nAppend 2\nNew line with relative threshold date t:June 3rd, 2005\nLine4\nLine5\nLine6\nMulti line 1Multi line 2Multi line 3`); + config.get = originalGet; + }); + + test('should update line with a multi line todo', async () => { + const originalGet = config.get; + config.get = (key: string) => { + if(key === 'bulkTodoCreation') { + return false; + } + return originalGet.call(config, key); + }; + + const content = 'Multi line 1\nMulti line 2\nMulti line 3'; + + prepareContentForWriting(2, content); + const fileContent = fs.readFileSync('./src/__tests__/__mock__/test.txt', 'utf8'); + expect(fileContent).toEqual(`Line 1\nEdited line\nMulti line 1Multi line 2Multi line 3\nUpdated line\nAppend 1\nAppend 2\nNew line with relative threshold date t:June 3rd, 2005\nLine4\nLine5\nLine6\nMulti line 1Multi line 2Multi line 3`); + config.get = originalGet; + }); }); diff --git a/src/main/config.tsx b/src/main/config.tsx index c9354b5b..094f7832 100644 --- a/src/main/config.tsx +++ b/src/main/config.tsx @@ -8,7 +8,7 @@ import { writeToFile } from './modules/File/Write'; import { createTray } from './modules/Tray'; import { processDataRequest, searchString } from './modules/ProcessDataRequest/ProcessDataRequest'; import handleTheme from './modules/Theme'; -import { getChannel } from './util'; +import { getChannel, handleError } from './util'; import crypto from 'crypto'; Store.initRenderer(); @@ -138,20 +138,22 @@ if(!fs.existsSync(notifiedTodoObjectsPath)) { writeToFile(JSON.stringify(defaultNotifiedTodoObjectsData), notifiedTodoObjectsPath, null) } -filter.onDidChange('attributes', async () => { +filter.onDidChange('attributes', () => { try { - await processDataRequest(searchString); - } catch(error: any) { - console.error(error); + const requestedData = processDataRequest(searchString); + mainWindow!.webContents.send('requestData', requestedData); + } catch(error: Error) { + handleError(error); } }); -config.onDidAnyChange(async(settings) => { +config.onDidAnyChange((settings) => { try { - await processDataRequest(searchString); + const requestedData = processDataRequest(searchString); + mainWindow!.webContents.send('requestData', requestedData); mainWindow!.webContents.send('settingsChanged', settings); - } catch(error: any) { - console.error(error); + } catch(error: Error) { + handleError(error); } }); @@ -160,8 +162,8 @@ config.onDidChange('files', (newValue: FileObject[] | undefined) => { if (newValue !== undefined) { createFileWatcher(newValue); } - } catch (error: any) { - console.error(error); + } catch(error: Error) { + handleError(error); } }); @@ -170,8 +172,8 @@ config.onDidChange('colorTheme', (colorTheme) => { if(colorTheme === 'system' || colorTheme === 'light' || colorTheme === 'dark') { nativeTheme.themeSource = colorTheme; } - } catch (error: any) { - console.error(error); + } catch(error: Error) { + handleError(error); } }); diff --git a/src/main/main.tsx b/src/main/main.tsx index 1790fcfe..32165713 100644 --- a/src/main/main.tsx +++ b/src/main/main.tsx @@ -183,9 +183,10 @@ const handleBeforeQuit = () => { app.releaseSingleInstanceLock(); } -const handleOpenFile = (path: string) => { - if(path) addFile(path, null); -}; +// const handleOpenFile = (path) => { +// console.log(typeof path) +// if(path) addFile(path, null); +// }; app .whenReady().then(() => { @@ -193,14 +194,14 @@ app eventListeners.handleCreateWindow = handleCreateWindow; eventListeners.handleWindowAllClosed = handleWindowAllClosed; eventListeners.handleBeforeQuit = handleBeforeQuit; - eventListeners.handleOpenFile = handleOpenFile; + //eventListeners.handleOpenFile = handleOpenFile; }) .catch(console.error); app .on('window-all-closed', handleWindowAllClosed) .on('before-quit', handleBeforeQuit) - .on('activate', handleCreateWindow) - .on('open-file', () => handleOpenFile(path)); + .on('activate', handleCreateWindow); + //.on('open-file', () => handleOpenFile(path)); export { mainWindow, handleCreateWindow, eventListeners }; diff --git a/src/main/modules/File/Archive.tsx b/src/main/modules/File/Archive.tsx index 69c592af..abb447ad 100644 --- a/src/main/modules/File/Archive.tsx +++ b/src/main/modules/File/Archive.tsx @@ -11,7 +11,7 @@ function handleRequestArchive(): void { mainWindow!.webContents.send('triggerArchiving', Boolean(activeFile?.doneFilePath)); } -async function readFilteredFileContent(filePath: string, bookmark: string | null, complete: boolean): Promise { +function readFilteredFileContent(filePath: string, bookmark: string | null, complete: boolean): string { const filterStrings = (fileContent: string, complete: boolean): string => { const arrayOfStrings = fileContent.split('\n'); const filteredArrayOfStrings = arrayOfStrings.filter(string => { @@ -19,15 +19,15 @@ async function readFilteredFileContent(filePath: string, bookmark: string | null }); return filteredArrayOfStrings.join('\n'); }; - const fileContent: string | null = await readFileContent(filePath, bookmark); - if(fileContent) { + const fileContent: string | Error = readFileContent(filePath, bookmark); + if(typeof fileContent === 'string') { return filterStrings(fileContent, complete); } else { return ''; } } -async function archiveTodos(): Promise { +function archiveTodos(): string { const activeFile: FileObject | null = getActiveFile(); if(!activeFile) { throw new Error('Todo file is not defined'); @@ -37,19 +37,19 @@ async function archiveTodos(): Promise { return 'Archiving file is not defined'; } - const completedTodos: string = await readFilteredFileContent(activeFile.todoFilePath, activeFile.todoFileBookmark, true); + const completedTodos: string = readFilteredFileContent(activeFile.todoFilePath, activeFile.todoFileBookmark, true); if(!completedTodos) { return 'No completed todos found'; } - const uncompletedTodos: string = await readFilteredFileContent(activeFile.todoFilePath, activeFile.todoFileBookmark, false); + const uncompletedTodos: string = readFilteredFileContent(activeFile.todoFilePath, activeFile.todoFileBookmark, false); - const todosFromDoneFile: string | null = await readFileContent(activeFile.doneFilePath, activeFile.doneFileBookmark); + const todosFromDoneFile: string | Error = readFileContent(activeFile.doneFilePath, activeFile.doneFileBookmark); - await writeToFile(todosFromDoneFile + '\n' + completedTodos, activeFile.doneFilePath, activeFile.doneFileBookmark); + writeToFile(todosFromDoneFile + '\n' + completedTodos, activeFile.doneFilePath, activeFile.doneFileBookmark); - await writeToFile(uncompletedTodos, activeFile.todoFilePath, activeFile.todoFileBookmark); + writeToFile(uncompletedTodos, activeFile.todoFilePath, activeFile.todoFileBookmark); return 'Successfully archived'; } diff --git a/src/main/modules/File/Dialog.tsx b/src/main/modules/File/Dialog.tsx index dd8f8ae2..be3f67ee 100644 --- a/src/main/modules/File/Dialog.tsx +++ b/src/main/modules/File/Dialog.tsx @@ -2,6 +2,7 @@ import { app, dialog, OpenDialogReturnValue, SaveDialogReturnValue } from 'elect import path from 'path'; import { addFile, addDoneFile } from './File'; import { writeToFile } from './Write'; +import { handleError } from '../../util'; const dialogFilters = [ { @@ -24,14 +25,10 @@ async function openFile(setDoneFile: boolean): Promise { const filePath: string = result.filePaths[0]; const bookmark: string | null = result.bookmarks?.[0] || null; - try { - if(setDoneFile) { - addDoneFile(filePath, bookmark); - } else { - addFile(filePath, bookmark); - } - } catch(error: any) { - console.error(error); + if(setDoneFile) { + addDoneFile(filePath, bookmark); + } else { + addFile(filePath, bookmark); } } } @@ -50,14 +47,10 @@ async function createFile(setDoneFile: boolean): Promise { writeToFile('', filePath, bookmark) - try { - if(setDoneFile) { - addDoneFile(filePath, bookmark); - } else { - addFile(filePath, bookmark); - } - } catch(error: any) { - console.error(error); + if(setDoneFile) { + addDoneFile(filePath, bookmark); + } else { + addFile(filePath, bookmark); } } } diff --git a/src/main/modules/File/File.tsx b/src/main/modules/File/File.tsx index 92b8105b..5c3afa4e 100644 --- a/src/main/modules/File/File.tsx +++ b/src/main/modules/File/File.tsx @@ -6,16 +6,14 @@ import { createMenu } from '../Menu'; import path from 'path'; import { mainWindow } from '../../main'; -async function readFileContent(filePath: string, bookmark: string | null): Promise { - let fileContent; +function readFileContent(filePath: string, bookmark: string | null): string | Error { + const stopAccessingSecurityScopedResource = (process.mas && bookmark) ? app.startAccessingSecurityScopedResource(bookmark) : null; + const fileContent = fs.readFileSync(filePath, 'utf8'); - if(process.mas && bookmark) { - const stopAccessingSecurityScopedResource = app.startAccessingSecurityScopedResource(bookmark); - fileContent = await fs.promises.readFile(filePath, 'utf8'); - stopAccessingSecurityScopedResource() - } else { - fileContent = await fs.promises.readFile(filePath, 'utf8'); + if (stopAccessingSecurityScopedResource && process.mas && bookmark) { + stopAccessingSecurityScopedResource(); } + return fileContent; } diff --git a/src/main/modules/File/Watcher.tsx b/src/main/modules/File/Watcher.tsx index f5b8d996..cbd285f2 100644 --- a/src/main/modules/File/Watcher.tsx +++ b/src/main/modules/File/Watcher.tsx @@ -1,7 +1,8 @@ import chokidar, { FSWatcher } from 'chokidar'; import { processDataRequest, searchString } from '../ProcessDataRequest/ProcessDataRequest'; import { config } from '../../config'; -import { eventListeners } from '../../main'; +import { handleError } from '../../util'; +import { mainWindow, eventListeners } from '../../main'; let watcher: FSWatcher | null = null; @@ -23,12 +24,13 @@ function createFileWatcher(files: FileObject[]): void { .on('add', (file) => { console.log(`Watching new file: ${file}`); }) - .on('change', async (file) => { + .on('change', (file) => { try { - await processDataRequest(searchString); + const requestedData = processDataRequest(searchString); + mainWindow!.webContents.send('requestData', requestedData); console.log(`${file} has been changed`); - } catch(error: any) { - console.error(error.message); + } catch(error: Error) { + handleError(error); } }) .on('unlink', (file) => { diff --git a/src/main/modules/File/Write.tsx b/src/main/modules/File/Write.tsx index cfe2bcba..c5755128 100644 --- a/src/main/modules/File/Write.tsx +++ b/src/main/modules/File/Write.tsx @@ -8,23 +8,22 @@ import { replaceSpeakingDatesWithAbsoluteDates } from '../Date'; function writeToFile(string: string, filePath: string, bookmark: string | null) { const stopAccessingSecurityScopedResource = (process.mas && bookmark) ? app.startAccessingSecurityScopedResource(bookmark) : null; - fs.writeFile(filePath, string, (error) => { - if (error) return error; - console.info('Written to file'); - if(stopAccessingSecurityScopedResource) stopAccessingSecurityScopedResource() - }); + + fs.writeFileSync(filePath, string, 'utf-8'); + + if (stopAccessingSecurityScopedResource && process.mas && bookmark) { + stopAccessingSecurityScopedResource(); + } } -function removeLineFromFile(lineNumber: number): string { - const activeFile: FileObject | null = getActiveFile(); +function removeLineFromFile(lineNumber: number) { + let activeFile: FileObject | null = getActiveFile(); if(!activeFile) { throw new Error('No active file found'); - } else if(typeof lineNumber !== 'number') { - throw new Error(`No line number passed, can't delete without it`); + } else if(lineNumber >= 0) { + linesInFile.splice(lineNumber, 1); + writeToFile(linesInFile.join('\n'), activeFile.todoFilePath, activeFile.todoFileBookmark); } - linesInFile.splice(lineNumber, 1); - writeToFile(linesInFile.join('\n'), activeFile.todoFilePath, activeFile.todoFileBookmark); - return `Line ${lineNumber} removed from file`; } function prepareContentForWriting(lineNumber: number, string: string) { @@ -68,4 +67,4 @@ function prepareContentForWriting(lineNumber: number, string: string) { writeToFile(linesInFile.join('\n'), activeFile.todoFilePath, activeFile.todoFileBookmark); } -export { prepareContentForWriting, removeLineFromFile, writeToFile }; +export { prepareContentForWriting, removeLineFromFile, writeToFile }; \ No newline at end of file diff --git a/src/main/modules/Filters/Filters.tsx b/src/main/modules/Filters/Filters.tsx index 75851941..62e44393 100644 --- a/src/main/modules/Filters/Filters.tsx +++ b/src/main/modules/Filters/Filters.tsx @@ -35,15 +35,13 @@ function applyAttributes(todoObjects: TodoObject[], filters: Filters | null): To }); } -function handleCompletedTodoObjects(todoObjects: TodoObject[]): TodoObject[] | false { +function handleCompletedTodoObjects(todoObjects: TodoObject[]): TodoObject[] { const showCompleted: boolean = config.get('showCompleted'); - return todoObjects.map((todoObject: TodoObject) => { - if(todoObject.complete && !showCompleted) { - return false; - } else { - return todoObject; - } - }); + if (!showCompleted) { + return todoObjects.filter((todoObject: TodoObject) => !todoObject.complete); + } else { + return todoObjects; + } } function handleHiddenTodoObjects(todoObjects: TodoObject[]): TodoObject[] { diff --git a/src/main/modules/IpcMain.tsx b/src/main/modules/IpcMain.tsx index 952f77ff..e0c9abfe 100644 --- a/src/main/modules/IpcMain.tsx +++ b/src/main/modules/IpcMain.tsx @@ -1,69 +1,61 @@ -import { shell } from 'electron'; -import { ipcMain, app, IpcMainEvent, clipboard } from 'electron'; +import { ipcMain, app, IpcMainEvent, clipboard, shell } from 'electron'; import { processDataRequest } from './ProcessDataRequest/ProcessDataRequest'; import { changeCompleteState } from './ProcessDataRequest/ChangeCompleteState'; import { prepareContentForWriting, removeLineFromFile } from './File/Write'; import { archiveTodos, handleRequestArchive } from './File/Archive'; import { config, filter, notifiedTodoObjectsStorage } from '../config'; +import { handleConfig } from '../util'; import { addFile, setFile, removeFile } from './File/File'; import { openFile, createFile } from './File/Dialog'; import { createTodoObject } from './ProcessDataRequest/CreateTodoObjects'; -async function handleDataRequest(event: IpcMainEvent, searchString: string): Promise { +function handleDataRequest(event: IpcMainEvent, searchString: string) { try { - await processDataRequest(searchString) - } catch(error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + const requestedData = processDataRequest(searchString); + event.reply('requestData', requestedData); + } catch(error: Error) { + handleError(error); } } -function handleUpdateAttributeFields(event: IpcMainEvent, index: number, string: string): void { +function handleUpdateAttributeFields(event: IpcMainEvent, index: number, string: string) { try { const todoObject = createTodoObject(index, string); event.reply('updateAttributeFields', todoObject); - } catch(error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } -function handleUpdateTodoObject(event: IpcMainEvent, index: number, string: string, attributeType: string, attributeValue: string): void { +function handleUpdateTodoObject(event: IpcMainEvent, index: number, string: string, attributeType: string, attributeValue: string) { try { const todoObject = createTodoObject(index, string, attributeType, attributeValue); event.reply('updateTodoObject', todoObject); - } catch(error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); - } + } catch(error: Error) { + handleError(error); + } } -async function handleWriteTodoToFile(event: IpcMainEvent, index: number, string: string, state: boolean, attributeType: string, attributeValue: string): Promise { +function handleWriteTodoToFile(event: IpcMainEvent, index: number, string: string, state: boolean, attributeType: string, attributeValue: string) { try { if(attributeType && attributeValue) { const todoObject = createTodoObject(index, string, attributeType, attributeValue); - //const response = await prepareContentForWriting(index, todoObject.string); - await prepareContentForWriting(index, todoObject.string); - //event.reply('writeTodoToFile', response); + prepareContentForWriting(index, todoObject.string); } else { let updatedString: string | null = string; - if(state !== undefined && index >= 0) updatedString = await changeCompleteState(string, state) - //const response = await prepareContentForWriting(index, updatedString); - await prepareContentForWriting(index, updatedString); - //event.reply('writeTodoToFile', response); + if(state !== undefined && index >= 0) updatedString = changeCompleteState(string, state) + prepareContentForWriting(index, updatedString); } - } catch(error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } -function handleStoreGetConfig(event: IpcMainEvent, value: string): void { +function handleStoreGetConfig(event: IpcMainEvent, value: string) { try { event.returnValue = config.get(value); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } @@ -71,118 +63,105 @@ function handleStoreSetConfig(event: IpcMainEvent, key: string, value: any) { try { config.set(key, value); console.log(`Set ${key} to ${value}`); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } function handleStoreSetFilters(event: IpcMainEvent, key: string, value: any): void { try { filter.set(key, value); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } function handleStoreGetFilters(event: IpcMainEvent, value: string): void { try { event.returnValue = filter.get(value); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } function handleStoreSetNotifiedTodoObjects(event: IpcMainEvent, value: any): void { try { notifiedTodoObjectsStorage.set('notifiedTodoObjects', value); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } function handleSetFile(event: IpcMainEvent, index: number): void { try { setFile(index); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } function handleRemoveFile(event: IpcMainEvent, index: number): void { try { removeFile(index); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } function handleAddFile(event: IpcMainEvent, filePath: string): void { try { addFile(filePath, null); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } function handleDroppedFile(event: IpcMainEvent, filePath: string): void { try { addFile(filePath, null); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } function handleRevealInFileManager(event: IpcMainEvent, pathToReveal: string): void { try { shell.showItemInFolder(pathToReveal); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } async function handleOpenFile(event: IpcMainEvent, setDoneFile: boolean): Promise { try { - await openFile(setDoneFile); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + openFile(setDoneFile); + } catch(error: Error) { + handleError(error); } } async function handleCreateFile(event: IpcMainEvent, setDoneFile: boolean): Promise { try { await createFile(setDoneFile); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } function handleRemoveLineFromFile(event: IpcMainEvent, index: number) { try { removeLineFromFile(index); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } -async function handleArchiveTodos(event: IpcMainEvent): Promise { +function handleArchiveTodos(event: IpcMainEvent): Promise { try { - const archivingResult = await archiveTodos(); + const archivingResult = archiveTodos(); event.reply('responseFromMainProcess', archivingResult); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } @@ -190,18 +169,16 @@ function handleSaveToClipboard(event: IpcMainEvent, string: string): void { try { clipboard.writeText(string); event.reply('responseFromMainProcess', 'Copied to clipboard: ' + string); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } async function handleOpenInBrowser(event: IpcMainEvent, url: string): Promise { try { await shell?.openExternal(url); - } catch (error: any) { - console.error(error); - event.reply('responseFromMainProcess', error); + } catch(error: Error) { + handleError(error); } } diff --git a/src/main/modules/ProcessDataRequest/ChangeCompleteState.tsx b/src/main/modules/ProcessDataRequest/ChangeCompleteState.tsx index 51bcf565..2b512308 100644 --- a/src/main/modules/ProcessDataRequest/ChangeCompleteState.tsx +++ b/src/main/modules/ProcessDataRequest/ChangeCompleteState.tsx @@ -33,4 +33,4 @@ function changeCompleteState(string: string, state: boolean): string { return JsTodoTxtObject.toString().replaceAll(' [LB] ', '\n'); } -export { changeCompleteState }; +export { changeCompleteState }; \ No newline at end of file diff --git a/src/main/modules/ProcessDataRequest/CreateTodoObjects.tsx b/src/main/modules/ProcessDataRequest/CreateTodoObjects.tsx index f72580e6..9d1369f3 100644 --- a/src/main/modules/ProcessDataRequest/CreateTodoObjects.tsx +++ b/src/main/modules/ProcessDataRequest/CreateTodoObjects.tsx @@ -64,17 +64,17 @@ function createTodoObject(index: number, string: string, attributeType?: string, }; } -async function createTodoObjects(fileContent: string | null): Promise { - if(!fileContent) { +function createTodoObjects(fileContent: string | null): TodoObject[] | [] { + if (!fileContent) { linesInFile = []; return []; } badge.count = 0; linesInFile = fileContent.split(/[\r\n]+/).filter(line => line.trim() !== ''); const excludeLinesWithPrefix: string[] = config.get('excludeLinesWithPrefix') || []; - - const todoObjects: TodoObject[] = await Promise.all(linesInFile.map(async (line, i) => { - if(excludeLinesWithPrefix.some(prefix => line.startsWith(prefix))) { + + const todoObjects: TodoObject[] = linesInFile.map((line, i) => { + if (excludeLinesWithPrefix.some(prefix => line.startsWith(prefix))) { return null; } @@ -85,7 +85,7 @@ async function createTodoObjects(fileContent: string | null): Promise objects.filter(Boolean) as TodoObject[]); + }).filter(Boolean) as TodoObject[]; app.setBadgeCount(badge.count); diff --git a/src/main/modules/ProcessDataRequest/ProcessDataRequest.tsx b/src/main/modules/ProcessDataRequest/ProcessDataRequest.tsx index d45d358f..eea99b6c 100644 --- a/src/main/modules/ProcessDataRequest/ProcessDataRequest.tsx +++ b/src/main/modules/ProcessDataRequest/ProcessDataRequest.tsx @@ -6,11 +6,16 @@ import { applyAttributes, handleHiddenTodoObjects, handleCompletedTodoObjects, h import { updateAttributes, attributes } from '../Attributes'; import { createTodoObjects } from './CreateTodoObjects'; import { mainWindow } from '../../main'; -import { sortAndGroupTodoObjects, flattenTodoObjects, countTodoObjects } from './ProcessTodoObjects'; +import { sortAndGroupTodoObjects, flattenTodoObjects } from './ProcessTodoObjects'; let searchString: string; +let headers: HeadersObject = { + availableObjects: 0, + visibleObjects: 0 +} +let todoObjects: TodoObject[]; -async function processDataRequest(search?: string): Promise { +function processDataRequest(search?: string): RequestedData { searchString = search || ''; const activeFile: FileObject | null = getActiveFile(); @@ -22,9 +27,20 @@ async function processDataRequest(search?: string): Promise { const fileSorting: boolean = config.get('fileSorting'); const filters: Filters = filter.get('attributes'); - const fileContent = await readFileContent(activeFile.todoFilePath, activeFile.todoFileBookmark); - let todoObjects: TodoObject[] | [] = await createTodoObjects(fileContent); + const fileContent = readFileContent(activeFile.todoFilePath, activeFile.todoFileBookmark); + + todoObjects = createTodoObjects(fileContent); + + headers.availableObjects = todoObjects.length; + todoObjects = handleTodoObjectsDates(todoObjects); + + const completedTodoObjects: TodoObject[] = todoObjects.filter((todoObject: TodoObject) => { + return todoObject.complete; + }); + + headers.completedObjects = completedTodoObjects.length; + todoObjects = handleCompletedTodoObjects(todoObjects); updateAttributes(todoObjects, sorting, true); @@ -37,7 +53,11 @@ async function processDataRequest(search?: string): Promise { updateAttributes(todoObjects, sorting, false); - const headers: HeadersObject = countTodoObjects(todoObjects); + const visibleTodoObjects: TodoObject[] = todoObjects.filter((todoObject: TodoObject) => { + return todoObject.visible; + }); + + headers.visibleObjects = visibleTodoObjects.length; if(fileSorting) { todoObjects = flattenTodoObjects(todoObjects, ''); @@ -53,7 +73,7 @@ async function processDataRequest(search?: string): Promise { filters, }; - mainWindow!.webContents.send('requestData', requestedData); + return requestedData; } export { processDataRequest, searchString }; diff --git a/src/main/modules/ProcessDataRequest/ProcessTodoObjects.tsx b/src/main/modules/ProcessDataRequest/ProcessTodoObjects.tsx index 68f4f6b9..54440438 100644 --- a/src/main/modules/ProcessDataRequest/ProcessTodoObjects.tsx +++ b/src/main/modules/ProcessDataRequest/ProcessTodoObjects.tsx @@ -1,19 +1,3 @@ -function countTodoObjects(todoObjects: TodoObject[]): HeadersObject { - const filteredObjects: TodoObject[] = todoObjects.filter((todoObject: TodoObject) => { - return todoObject.visible; - }); - - const completedObjects: TodoObject[] = todoObjects.filter((todoObject: TodoObject) => { - if(todoObject.complete) return todoObject.complete; - }); - - return { - availableObjects: todoObjects.length, - visibleObjects: filteredObjects.length, - completedObjects: completedObjects.length - }; -} - function sortAndGroupTodoObjects(todoObjects: TodoObject[], sorting: Sorting[]): TodoObject[] { function compareValues(a: any, b: any, invert: boolean): number { const comparison = String(a).localeCompare(String(b), undefined, { sensitivity: 'base' }); @@ -91,6 +75,5 @@ function flattenTodoObjects(todoObjects: TodoObject[], topLevelGroup: string): T export { flattenTodoObjects, - sortAndGroupTodoObjects, - countTodoObjects, + sortAndGroupTodoObjects }; \ No newline at end of file diff --git a/src/main/util.tsx b/src/main/util.tsx index eb9f41d9..5bfa0341 100644 --- a/src/main/util.tsx +++ b/src/main/util.tsx @@ -1,6 +1,7 @@ import { URL } from 'url'; import { app } from 'electron'; import path from 'path'; +import { mainWindow } from './main'; const RESOURCES_PATH = app.isPackaged ? path.join(process.resourcesPath, 'assets') @@ -40,4 +41,9 @@ function getChannel(): string { } } -export { getAssetPath, resolveHtmlPath, getChannel } \ No newline at end of file +function handleError(error: Error) { + console.error(error); + mainWindow!.webContents.send('responseFromMainProcess', error); +} + +export { getAssetPath, resolveHtmlPath, getChannel, handleError } \ No newline at end of file diff --git a/src/renderer/SplashScreen.tsx b/src/renderer/SplashScreen.tsx index eccd489d..0718a884 100644 --- a/src/renderer/SplashScreen.tsx +++ b/src/renderer/SplashScreen.tsx @@ -43,7 +43,7 @@ const SplashScreen: FC = memo(({ return (
- {settings.files?.length > 0 && headers?.visibleObjects === 0 && headers?.availableObjects > 0 && ( + {settings.files?.length > 0 && headers?.availableObjects > 0 && headers?.visibleObjects === 0 && ( <>

{t('splashscreen.noTodosVisible.text')}

diff --git a/src/types.tsx b/src/types.tsx index 2c242999..646da05c 100644 --- a/src/types.tsx +++ b/src/types.tsx @@ -84,6 +84,9 @@ declare global { channel: string; chokidarOptions: object; menuBarVisibility: boolean; + fileWatcherAtomic: boolean; + fileWatcherPolling: boolean; + fileWatcherPollingInterval: boolean; __internal__: { migrations: { version: string }}; } diff --git a/yarn.lock b/yarn.lock index 32067b1e..76fafd7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1191,7 +1191,7 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== -"@emotion/is-prop-valid@^1.2.1": +"@emotion/is-prop-valid@^1.2.2": version "1.2.2" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz#d4175076679c6a26faa92b03bb786f9e52612337" integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw== @@ -1217,10 +1217,10 @@ "@emotion/weak-memoize" "^0.3.1" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.3.tgz#84b77bfcfe3b7bb47d326602f640ccfcacd5ffb0" - integrity sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA== +"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3", "@emotion/serialize@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.4.tgz#fc8f6d80c492cfa08801d544a05331d1cc7cd451" + integrity sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ== dependencies: "@emotion/hash" "^0.9.1" "@emotion/memoize" "^0.8.1" @@ -1234,14 +1234,14 @@ integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== "@emotion/styled@^11.11.0": - version "11.11.0" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" - integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== + version "11.11.5" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.5.tgz#0c5c8febef9d86e8a926e663b2e5488705545dfb" + integrity sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ== dependencies: "@babel/runtime" "^7.18.3" "@emotion/babel-plugin" "^11.11.0" - "@emotion/is-prop-valid" "^1.2.1" - "@emotion/serialize" "^1.1.2" + "@emotion/is-prop-valid" "^1.2.2" + "@emotion/serialize" "^1.1.4" "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" "@emotion/utils" "^1.2.1" @@ -2168,9 +2168,9 @@ "@types/estree" "*" "@types/eslint@*": - version "8.56.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.6.tgz#d5dc16cac025d313ee101108ba5714ea10eb3ed0" - integrity sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A== + version "8.56.7" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.7.tgz#c33b5b5a9cfb66881beb7b5be6c34aa3e81d3366" + integrity sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -2314,9 +2314,11 @@ "@types/unist" "*" "@types/mime@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" - integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-4.0.0.tgz#b5f8a75697ac775ecf1daaea9bfb91cde065b397" + integrity sha512-5eEkJZ/BLvTE3vXGKkWlyTSUVZuzj23Wj8PoyOq2lt5I3CYbiLBOPb3XmCW6QcuOibIUE6emHXHt9E/F/rCa6w== + dependencies: + mime "*" "@types/mime@^1": version "1.3.5" @@ -2341,9 +2343,9 @@ "@types/node" "*" "@types/node@*": - version "20.11.30" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.30.tgz#9c33467fc23167a347e73834f788f4b9f399d66f" - integrity sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw== + version "20.12.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.2.tgz#9facdd11102f38b21b4ebedd9d7999663343d72e" + integrity sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ== dependencies: undici-types "~5.26.4" @@ -2355,9 +2357,9 @@ undici-types "~5.26.4" "@types/node@^18.11.18": - version "18.19.26" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.26.tgz#18991279d0a0e53675285e8cf4a0823766349729" - integrity sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw== + version "18.19.28" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.28.tgz#c64a2c992c8ebbf61100a4570e4eebc1934ae030" + integrity sha512-J5cOGD9n4x3YGgVuaND6khm5x07MMdAKkRyXnjVR6KFhLMNh2yONGiP7Z+4+tBOt5mK+GvDTiacTOVGGpqiecw== dependencies: undici-types "~5.26.4" @@ -2435,9 +2437,9 @@ "@types/react" "*" "@types/react@*", "@types/react@^18.0.26", "@types/react@^18.2.64": - version "18.2.73" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.73.tgz#0579548ad122660d99e00499d22e33b81e73ed94" - integrity sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA== + version "18.2.74" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.74.tgz#2d52eb80e4e7c4ea8812c89181d6d590b53f958c" + integrity sha512-9AEqNZZyBx8OdZpxzQlaFEVCSFUM2YXJH46yPOiOpm078k6ZLOCcuAzGum/zK8YBwY+dbahVNbHrbgrAwIRlqw== dependencies: "@types/prop-types" "*" csstype "^3.0.2" @@ -3449,9 +3451,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001587: - version "1.0.30001600" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz#93a3ee17a35aa6a9f0c6ef1b2ab49507d1ab9079" - integrity sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ== + version "1.0.30001605" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz#ca12d7330dd8bcb784557eb9aa64f0037870d9d6" + integrity sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ== ccount@^2.0.0: version "2.0.1" @@ -4574,14 +4576,14 @@ electron-store@^8.2.0: type-fest "^2.17.0" electron-to-chromium@^1.4.668: - version "1.4.719" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.719.tgz#22a94ce7a5150511ba88e900836039e159efe22c" - integrity sha512-FbWy2Q2YgdFzkFUW/W5jBjE9dj+804+98E4Pup78JBPnbdb3pv6IneY2JCPKdeKLh3AOKHQeYf+KwLr7mxGh6Q== + version "1.4.723" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.723.tgz#827da30c96b316684d352c3d81430029df01bb8e" + integrity sha512-rxFVtrMGMFROr4qqU6n95rUi9IlfIm+lIAt+hOToy/9r6CDv0XiEcQdC3VP71y1pE5CFTzKV0RvxOGYCPWWHPw== electron@^28.2.6: - version "28.2.8" - resolved "https://registry.yarnpkg.com/electron/-/electron-28.2.8.tgz#b83d70ca00c0e767f0125fcec85f39aafe39ee4c" - integrity sha512-VgXw2OHqPJkobIC7X9eWh3atptjnELaP+zlbF9Oz00ridlaOWmtLPsp6OaXbLw35URpMr0iYesq8okKp7S0k+g== + version "28.2.9" + resolved "https://registry.yarnpkg.com/electron/-/electron-28.2.9.tgz#7c94a4901b1cb40993906f060a14a108039ac817" + integrity sha512-6b6G6jq4ypKxdCRNjULmqWEott4GJe2kaAykLonaTaeFqoFFHbzOu4k6pAzurseFhv452aUob9DAH6eI7UlOUw== dependencies: "@electron/get" "^2.0.0" "@types/node" "^18.11.18" @@ -7109,9 +7111,9 @@ media-typer@0.3.0: integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== memfs@^4.6.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.8.0.tgz#0ea1ecb137219883c2e7c5139f4fa109935f7e39" - integrity sha512-fcs7trFxZlOMadmTw5nyfOwS3il9pr3y+6xzLfXNwmuR/D0i4wz6rJURxArAbcJDGalbpbMvQ/IFI0NojRZgRg== + version "4.8.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.8.1.tgz#1e02c15c4397212a9a1b037fa4324c6f7dd45b47" + integrity sha512-7q/AdPzf2WpwPlPL4v1kE2KsJsHl7EF4+hAeVzlyanr2+YnR21NVn9mDqo+7DEaKDRsQy8nvxPlKH4WqMtiO0w== dependencies: tslib "^2.0.0" @@ -7428,6 +7430,11 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, dependencies: mime-db "1.52.0" +mime@*: + version "4.0.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.1.tgz#ad7563d1bfe30253ad97dedfae2b1009d01b9470" + integrity sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA== + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -7653,9 +7660,9 @@ no-case@^3.0.4: tslib "^2.0.3" node-abi@^3.45.0: - version "3.56.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.56.0.tgz#ca807d5ff735ac6bbbd684ae3ff2debc1c2a40a7" - integrity sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q== + version "3.57.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.57.0.tgz#d772cb899236c0aa46778d0d25256917cf15eb15" + integrity sha512-Dp+A9JWxRaKuHP35H77I4kCKesDy5HUDEmScia2FyncMTOXASMyg251F5PhFoDA5uqBrDDffiLpbqnrZmNXW+g== dependencies: semver "^7.3.5" @@ -9630,9 +9637,9 @@ terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.9: terser "^5.26.0" terser@^5.10.0, terser@^5.26.0: - version "5.30.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.30.0.tgz#64cb2af71e16ea3d32153f84d990f9be0cdc22bf" - integrity sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw== + version "5.30.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.30.2.tgz#79fc2222c241647cea54ab928ac987ffbe8ce9e2" + integrity sha512-vTDjRKYKip4dOFL5VizdoxHTYDfEXPdz5t+FbxCC5Rp2s+KbEO8w5wqMDPgj7CtFKZuzq7PXv28fZoXfqqBVuw== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -10175,9 +10182,9 @@ webpack-cli@^5.1.1: webpack-merge "^5.7.3" webpack-dev-middleware@^7.1.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-7.1.1.tgz#29aefd73720a03889e1c5c8dd7e552c4d333d572" - integrity sha512-NmRVq4AvRQs66dFWyDR4GsFDJggtSi2Yn38MXLk0nffgF9n/AIP4TFBg2TQKYaRAN4sHuKOTiz9BnNCENDLEVA== + version "7.2.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-7.2.1.tgz#2af00538b6e4eda05f5afdd5d711dbebc05958f7" + integrity sha512-hRLz+jPQXo999Nx9fXVdKlg/aehsw1ajA9skAneGmT03xwmyuhvF93p6HUKKbWhXdcERtGTzUCtIQr+2IQegrA== dependencies: colorette "^2.0.10" memfs "^4.6.0"