diff --git a/app/src/api/fetcher.ts b/app/src/api/fetcher.ts deleted file mode 100644 index 3eecaa9..0000000 --- a/app/src/api/fetcher.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { pb } from "./pb"; -import { ListsResponse, TasksResponse } from "./pocketbase-types"; - -export interface ListData { - id: string; - name: string; - parentId: string | null; - lists: Array<{ - id: string; - name: string; - listCount: number; - taskCount: number; - }>; - tasks: Array; -} - -export async function listFetcher(id: string): Promise { - type Expand = { "lists(parent)": unknown[]; "tasks(list)": unknown[] }; - type ListsResponseExpand = ListsResponse; - if (id === "all") { - const lists = await pb - .collection("lists") - .getList(0, 50, { - filter: pb.filter("parent = null"), - expand: "lists(parent),tasks(list)", - }); - const tasks = await pb.collection("tasks").getList(0, 50, { - filter: pb.filter("list = null"), - }); - return { - id, - name: "Lists", - parentId: null, - lists: lists.items.map((l) => ({ - id: l.id, - name: l.name, - listCount: l.expand?.["lists(parent)"]?.length || 0, - taskCount: l.expand?.["tasks(list)"]?.length || 0, - })), - tasks: tasks.items, - }; - } - - const list = await pb.collection("lists").getOne(id); - const lists = await pb - .collection("lists") - .getList(0, 50, { - filter: pb.filter("parent = {:id}", { id }), - expand: "lists(parent),tasks(list)", - }); - const tasks = await pb.collection("tasks").getList(0, 50, { - filter: pb.filter("list = {:id}", { id }), - }); - return { - id, - name: list.name, - parentId: list.parent, - lists: lists.items.map((l) => ({ - id: l.id, - name: l.name, - listCount: l.expand?.["lists(parent)"]?.length || 0, - taskCount: l.expand?.["tasks(list)"]?.length || 0, - })), - tasks: tasks.items, - }; -} - -export interface TaskData extends TasksResponse { - listId: string; - imageSource: string; -} - -export async function taskFetcher(id: string): Promise { - const task = await pb.collection("tasks").getOne(id); - const icon = await pb.collection("icons").getOne(task.icon); - const imageSource = pb.getFileUrl(icon, icon.image, { - thumb: "300x300", - }); - return { - ...task, - listId: task.list, - imageSource, - }; -} - -export interface RandomTaskData { - id: string; - name: string; -} - -export async function randomTask(parent: string | null) { - return await pb.send(`/api/extras/random/${parent}`, {}); -} diff --git a/app/src/api/pb.ts b/app/src/api/index.ts similarity index 69% rename from app/src/api/pb.ts rename to app/src/api/index.ts index 33c1bf0..c07ccaf 100644 --- a/app/src/api/pb.ts +++ b/app/src/api/index.ts @@ -2,4 +2,3 @@ import PocketBase from "pocketbase"; import type { TypedPocketBase } from "./pocketbase-types"; export const pb = new PocketBase("https://musclecat.pi.korz.tech") as TypedPocketBase; -//export const pb = new PocketBase("http://localhost:8090") as TypedPocketBase; diff --git a/app/src/screens/List.tsx b/app/src/screens/List.tsx index f470151..9d39d44 100644 --- a/app/src/screens/List.tsx +++ b/app/src/screens/List.tsx @@ -5,42 +5,27 @@ import { useWindowDimensions, Image, } from "react-native"; -import { Appbar, Text, Avatar, Card, List, useTheme, Button } from "react-native-paper"; +import { Appbar, Text, Avatar, Card, List, useTheme } from "react-native-paper"; import { StackHeaderProps, createStackNavigator, } from "@react-navigation/stack"; import RenderHtml from "react-native-render-html"; import { HomeScreenNavigationProp } from "./types"; -import useSWR, { preload } from "swr"; +import useSWR from "swr"; +import { pb } from "../api"; import { getHeaderTitle } from "@react-navigation/elements"; -import { useEffect } from "react"; -import { ListData, listFetcher, randomTask, taskFetcher } from "../api/fetcher"; - -function ListItem(props: { data: ListData["lists"][0]; onPress(): void }) { - const { name, listCount, taskCount } = props.data; - let subtitle = ""; - if (listCount) { - subtitle += `${listCount} lists`; - } - if (listCount && taskCount) { - subtitle += " • " - } - if (taskCount) { - subtitle += `${taskCount} tasks`; - } - if (!listCount && !taskCount) { - subtitle += "Empty"; - } +import { useEffect, useLayoutEffect } from "react"; +function ListItem(props: { name: string; onPress(): void }) { return ( } /*right={(props) => ( {}} /> @@ -50,23 +35,64 @@ function ListItem(props: { data: ListData["lists"][0]; onPress(): void }) { ); } -function TaskItem(props: { data: ListData["tasks"][0]; onPress(): void }) { - const { id, name, schedule } = props.data; - const date = new Date(schedule); - const now = new Date(); - const ready = date <= now; - +function TaskItem(props: { name: string; onPress(): void }) { return ( } onPress={props.onPress} - onPressIn={() => preload(id, taskFetcher)} /> ); } +interface ListResponse { + id: string; + name: string; + parentId: string | null; + lists: Array<{ + id: string; + name: string; + }>; + tasks: Array<{ + id: string; + name: string; + }>; +} + +async function listFetcher(id: string): Promise { + if (id === "all") { + const lists = await pb.collection("lists").getList(0, 50, { + filter: pb.filter("parent = null"), + }); + const tasks = await pb.collection("tasks").getList(0, 50, { + filter: pb.filter("list = null"), + }); + return { + id, + name: "Lists", + parentId: null, + lists: lists.items.map((l) => ({ id: l.id, name: l.name })), + tasks: tasks.items.map((l) => ({ id: l.id, name: l.name })), + }; + } + + const list = await pb.collection("lists").getOne(id); + const lists = await pb.collection("lists").getList(0, 50, { + filter: pb.filter("parent = {:id}", { id }), + }); + const tasks = await pb.collection("tasks").getList(0, 50, { + filter: pb.filter("list = {:id}", { id }), + }); + return { + id, + name: list.name, + parentId: list.parent, + lists: lists.items.map((l) => ({ id: l.id, name: l.name })), + tasks: tasks.items.map((l) => ({ id: l.id, name: l.name })), + }; +} + function ListContent({ route, navigation }: HomeScreenNavigationProp<"List">) { const theme = useTheme(); const { listId, listName } = route.params ?? {}; @@ -111,10 +137,8 @@ function ListContent({ route, navigation }: HomeScreenNavigationProp<"List">) { {lists.map((l) => ( - navigation.push("List", { listId: l.id, listName: l.name }) - } + name={l.name} + onPress={() => navigation.push("List", { listId: l.id, listName: l.name })} /> ))} {tasks.length > 0 && ( @@ -123,10 +147,8 @@ function ListContent({ route, navigation }: HomeScreenNavigationProp<"List">) { {tasks.map((t) => ( - navigation.push("Task", { taskId: t.id, taskName: t.name }) - } + name={t.name} + onPress={() => navigation.push("Task", { taskId: t.id, taskName: t.name })} /> ))} @@ -135,6 +157,29 @@ function ListContent({ route, navigation }: HomeScreenNavigationProp<"List">) { ); } +interface TaskResponse { + id: string; + name: string; + description: string; + listId: string; + imageSource: string; +} + +async function taskFetcher(id: string): Promise { + const task = await pb.collection("tasks").getOne(id); + const icon = await pb.collection("icons").getOne(task.icon); + const imageSource = pb.getFileUrl(icon, icon.image, { + thumb: "300x300", + }); + return { + id, + name: task.name, + description: task.description, + listId: task.list, + imageSource, + }; +} + function TaskContent({ route, navigation }: HomeScreenNavigationProp<"Task">) { const dimensions = useWindowDimensions(); const theme = useTheme(); @@ -166,15 +211,12 @@ function TaskContent({ route, navigation }: HomeScreenNavigationProp<"Task">) { - Something went wrong: {error?.toString()} + Something went wrong: {error.toString()} ); } - const { name, description, schedule, imageSource } = data; - const date = new Date(schedule); - const now = new Date(); - const ready = date <= now; + const { name, description, imageSource } = data; return ( ) { fontSize: "1.1em", }} /> - ); } @@ -204,24 +245,14 @@ function ListNavigationBar({ options, back, }: StackHeaderProps) { - const params = route.params as any | undefined; - const title = getHeaderTitle(options, params?.listName || route.name); + const title = getHeaderTitle(options, (route.params as any)?.listName || route.name); return ( - {(back || params?.listId) ? (back ? navigation.pop() : navigation.replace("List"))} - /> : null} + {back ? navigation.pop()} /> : null} - - randomTask(params?.listId || null).then((data) => - navigation.push("Task", { taskId: data.id, taskName: data.name }), - ) - } - /> - {/* {}} />*/} + {}} /> + {}} /> ); } @@ -232,10 +263,7 @@ function TaskNavigationBar({ options, back, }: StackHeaderProps) { - const title = getHeaderTitle( - options, - (route.params as any)?.taskName || route.name, - ); + const title = getHeaderTitle(options, (route.params as any)?.taskName || route.name); return ( @@ -243,8 +271,8 @@ function TaskNavigationBar({ onPress={() => (back ? navigation.pop() : navigation.replace("List"))} /> - {/* {}} />*/} - {/* {}} />*/} + {}} /> + {}} /> ); } @@ -253,7 +281,9 @@ const Stack = createStackNavigator(); export function ScreenList() { return ( - + { - const result = new DynamicModel({ - "id": "", - "name": "", - }); - - const query = `WITH RECURSIVE descendants(id) AS ( - VALUES({:parent}) UNION ALL - SELECT l.id FROM lists l JOIN descendants d ON d.id = l.parent - ) SELECT t.id, t.name FROM tasks t JOIN descendants d ON t.list = d.id WHERE t.schedule <= DATE('now') ORDER BY RANDOM() LIMIT 1`; - const queryNull = `SELECT id, name FROM tasks WHERE schedule <= DATE('now') ORDER BY RANDOM() LIMIT 1`; - const parent = c.pathParam("parent"); - - $app.dao().db() - .newQuery(parent === "null" ? queryNull : query) - .bind({ parent }) - .one(result) - - return c.json(200, result) -}) - diff --git a/pb_migrations/1704322685_updated_tasks.js b/pb_migrations/1704322685_updated_tasks.js deleted file mode 100644 index dc052df..0000000 --- a/pb_migrations/1704322685_updated_tasks.js +++ /dev/null @@ -1,61 +0,0 @@ -/// -migrate((db) => { - const dao = new Dao(db) - const collection = dao.findCollectionByNameOrId("pf13z4hs1iubw41") - - // add - collection.schema.addField(new SchemaField({ - "system": false, - "id": "mxuameue", - "name": "reward", - "type": "number", - "required": false, - "presentable": false, - "unique": false, - "options": { - "min": 0, - "max": 10, - "noDecimal": false - } - })) - - // update - collection.schema.addField(new SchemaField({ - "system": false, - "id": "qjz9b0tm", - "name": "index4groupdefaultschedule", - "type": "date", - "required": false, - "presentable": false, - "unique": false, - "options": { - "min": "", - "max": "" - } - })) - - return dao.saveCollection(collection) -}, (db) => { - const dao = new Dao(db) - const collection = dao.findCollectionByNameOrId("pf13z4hs1iubw41") - - // remove - collection.schema.removeField("mxuameue") - - // update - collection.schema.addField(new SchemaField({ - "system": false, - "id": "qjz9b0tm", - "name": "schedule", - "type": "date", - "required": false, - "presentable": false, - "unique": false, - "options": { - "min": "", - "max": "" - } - })) - - return dao.saveCollection(collection) -}) diff --git a/pb_migrations/1704322700_updated_tasks.js b/pb_migrations/1704322700_updated_tasks.js deleted file mode 100644 index b9e37ed..0000000 --- a/pb_migrations/1704322700_updated_tasks.js +++ /dev/null @@ -1,42 +0,0 @@ -/// -migrate((db) => { - const dao = new Dao(db) - const collection = dao.findCollectionByNameOrId("pf13z4hs1iubw41") - - // update - collection.schema.addField(new SchemaField({ - "system": false, - "id": "qjz9b0tm", - "name": "schedule", - "type": "date", - "required": false, - "presentable": false, - "unique": false, - "options": { - "min": "", - "max": "" - } - })) - - return dao.saveCollection(collection) -}, (db) => { - const dao = new Dao(db) - const collection = dao.findCollectionByNameOrId("pf13z4hs1iubw41") - - // update - collection.schema.addField(new SchemaField({ - "system": false, - "id": "qjz9b0tm", - "name": "index4groupdefaultschedule", - "type": "date", - "required": false, - "presentable": false, - "unique": false, - "options": { - "min": "", - "max": "" - } - })) - - return dao.saveCollection(collection) -})