Skip to content

Commit b5ec228

Browse files
committed
Refactor file initialization and add new task
category feature
1 parent 28beafe commit b5ec228

File tree

6 files changed

+72
-14
lines changed

6 files changed

+72
-14
lines changed

src-tauri/src/libs/filehelper.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ use tauri::Env;
66

77
pub const ENV_FILE: &str = "../.env.local";
88

9+
pub const USERS_FILES: [&str; 4] = ["access_token.db", "auth_code.db", "tasks.json", "user_profile.json"];
10+
11+
12+
13+
14+
pub fn initialize_user_files() {
15+
for file in USERS_FILES.iter() {
16+
let file_path = get_app_local_data_dir(file);
17+
println!("file path: {}", file_path);
18+
}
19+
}
920

1021
// const PATHS =
1122
pub fn get_app_local_data_dir(file_name: &str) -> String {
@@ -19,13 +30,18 @@ pub fn get_app_local_data_dir(file_name: &str) -> String {
1930
Some(BaseDirectory::AppLocalData),
2031
).expect("failed to resolve path");
2132
let path = path.to_str().unwrap().to_string();
33+
println!("path: {} \n file name: {} \n", path, file_name);
2234
// check if file exists
2335
if !std::path::Path::new(file_name).exists() {
2436
println!("File does not exist, creating file {} for {}", file_name, path);
2537
// create file
26-
let mut file = std::fs::File::create(file_name).unwrap();
27-
// write empty array to file
28-
file.write_all("".as_bytes()).unwrap();
38+
let mut file = std::fs::File::create(&path).unwrap();
39+
// if a json file, write empty json
40+
if file_name.ends_with(".json") {
41+
println!("writing empty json");
42+
file.write_all(b"{}").unwrap();
43+
}
44+
2945
}
3046
path
3147
}

src-tauri/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ mod libs;
55

66
use tauri_plugin_log::{LogTarget};
77
use libs::tauri_actions::{save_access_token,load_access_token, greet, test_command, save_code, load_code};
8-
use libs::filehelper::{ENV_FILE};
8+
use libs::filehelper::{ENV_FILE, initialize_user_files};
99

1010

1111
fn main() {
1212
dotenv::from_filename(ENV_FILE).ok();
13+
initialize_user_files();
1314
tauri::Builder::default()
1415
.plugin(tauri_plugin_context_menu::init())
1516
.plugin(tauri_plugin_oauth::init())

src/components/ui/AddCategory.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
import { IconButton, Button, FormControl, FormLabel, Input, ButtonGroup, Box, Popover, useDisclosure, PopoverTrigger, PopoverContent, FocusLock, PopoverArrow, PopoverCloseButton, Stack} from '@chakra-ui/react'
22
import { CheckIcon } from '@chakra-ui/icons'
3-
import React, { useRef } from 'react'
3+
import { useRef } from 'react'
4+
import { useRecoilValue , useSetRecoilState} from 'recoil'
5+
import { taskObjectSelector, taskCategoriesListState } from '../../config/states'
46

57

68

79
const Form = ({categoryNameRef, onCancel}: {categoryNameRef: React.RefObject<HTMLInputElement>, onCancel: () => void}) => {
10+
11+
const taskObject = useRecoilValue(taskObjectSelector)
12+
const setTaskCategories = useSetRecoilState(taskCategoriesListState)
13+
814
const addNewCategory = () => {
9-
console.log('adding new category', categoryNameRef.current?.value)
15+
if (!categoryNameRef.current || categoryNameRef.current.value === '') return;
16+
taskObject.addNewTaskCategory(categoryNameRef.current?.value || '')
17+
.then((d) => { if (!d) return console.log('category not added') })
18+
.then(() => {
19+
taskObject.getTaskCategories().then((data) => {
20+
console.log('data', data)
21+
setTaskCategories(data)
22+
// clear input
23+
categoryNameRef.current!.value = ''
24+
})
25+
})
1026
}
1127

1228
return (

src/components/ui/TaskItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useRecoilValue, useSetRecoilState } from "recoil";
66
import { taskObjectState, taskCategoriesListSelector, activeTaskCategorySelector, activeCategoryTasksState, messageState } from "../../config/states";
77

88

9-
export default function TaskItem({ task, key }: { task: task, key: number }) {
9+
export default function TaskItem({ task }: { task: task }) {
1010
const [isHovered, setIsHovered] = useState(false);
1111
const Taskobject = useRecoilValue(taskObjectState)
1212
const taskCategoryList: taskCategory[] = useRecoilValue<taskCategory[]>(taskCategoriesListSelector)
@@ -44,7 +44,7 @@ export default function TaskItem({ task, key }: { task: task, key: number }) {
4444
}
4545

4646
return (
47-
<Box p="2" key={key} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
47+
<Box p="2" onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
4848
<Flex >
4949
<Checkbox isChecked={task.completed} onChange={() => handleTaskCheck(task)} paddingRight="1">
5050
<Box w="90%" as="span" textDecoration={task.completed ? "line-through" : "none"}>

src/config/states.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@ const taskObjectSelector = selector({
104104
key: 'taskObjectSelector',
105105
get: ({ get }) => {
106106
const taskObject = get(taskObjectState);
107-
const accessToken = get(accessTokenState);
108-
taskObject.setAccessToken(accessToken!);
109107
return taskObject;
110108
},
111109
});

src/helpers/task.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,21 @@ export class Task {
233233

234234
async getTasksFromFile(): Promise<taskCategory[]> {
235235
const tasks = await readTextFile(TASKS_FILE, { dir: DEFAULT_DIRECTORY });
236-
return JSON.parse(tasks);
236+
// check if a valid json
237+
try {
238+
return JSON.parse(tasks);
239+
} catch (error) {
240+
console.error("Error parsing tasks:", error);
241+
return [];
242+
}
237243
}
238244

239245
/// newly refactored
240246
async getTasksByCategoryPosition(position: number) {
241247
try {
242248
const tasks = await this.retrieveTasksByCategoryPosition(position);
243249
this.updateTaskCategoryList(position, tasks);
244-
await this.saveTasksToFileIfNeeded(!tasks); // Save to file if tasks are not retrieved
250+
await this.saveTasksToFileIfNeeded(tasks.length > 0);
245251
return tasks;
246252
} catch (error) {
247253
console.error("Error getting tasks by category position:", (error as Error).message);
@@ -347,7 +353,7 @@ export class Task {
347353
* @returns {task[]} - The list of tasks.
348354
*/
349355
async getTasksByCategoryPositionFromFile(position: number): Promise<task[]> {
350-
const tasks = await readTextFile(`tasks.json`, { dir: DEFAULT_DIRECTORY });
356+
const tasks = await readTextFile(TASKS_FILE, { dir: DEFAULT_DIRECTORY });
351357
const taskCategories = JSON.parse(tasks);
352358
return taskCategories[position].tasks;
353359
}
@@ -412,7 +418,7 @@ export class Task {
412418
}
413419

414420
async getTaskByIdFromFile(categoryID: string): Promise<task[]> {
415-
const tasks = await readTextFile(`tasks.json`, { dir: DEFAULT_DIRECTORY });
421+
const tasks = await readTextFile(TASKS_FILE, { dir: DEFAULT_DIRECTORY });
416422
const taskCategories = JSON.parse(tasks);
417423
return taskCategories.find((taskCategory: taskCategory) => taskCategory.id === categoryID).tasks;
418424
}
@@ -479,6 +485,27 @@ export class Task {
479485
}
480486
}
481487

488+
async addNewTaskCategory(title: string) {
489+
try {
490+
if (!navigator.onLine) throw new Error("No internet connection");
491+
const url = `${this.baseUrl}/users/@me/lists`
492+
const response = await axios.post(url, {
493+
title,
494+
}, {
495+
headers: {
496+
Authorization: `Bearer ${this.accessToken}`,
497+
},
498+
});
499+
// console.log(response.data, "add task");
500+
return response.data;
501+
} catch (error) {
502+
console.error(error);
503+
this.errorHandler(error as Error);
504+
return null;
505+
}
506+
}
507+
508+
482509
async clearPositionCache(position: number) {
483510
console.log("clearing cache", position);
484511
this.tasksCategoryList.clearCache(position);

0 commit comments

Comments
 (0)