Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(GIST-97): replace patch by put #40

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/app/(gistLayout)/mygist/[gistId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"use client"
import React from "react"
import MyGistIdPage from "./page-ui"
import { useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries"
import { useEditGist, useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries"
import { useToast } from "@/components/shadcn/use-toast"
import { getRawGistURL } from "@/lib/utils"
import { useMe } from "@/lib/queries/user.queries"

interface MyGistIdFeaturePageProps {
params: {
Expand All @@ -15,8 +16,9 @@
const { gistId } = params
const { data } = useGist(gistId)
const { toast } = useToast()
const { data: me } = useMe()

const { mutate: updateName } = usePatchGistName({

Check warning on line 21 in src/app/(gistLayout)/mygist/[gistId]/page.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'updateName' is assigned a value but never used
onSuccess: () => {
toast({
title: "Gist Saved",
Expand All @@ -25,22 +27,35 @@
},
})

const { mutate: updateContent } = usePatchGistContent({

Check warning on line 30 in src/app/(gistLayout)/mygist/[gistId]/page.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'updateContent' is assigned a value but never used
onSuccess: () => {},
})

const { mutate: edit } = useEditGist({
onSuccess: () => {
toast({
title: "Gist Saved",
description: "Your gist has been saved successfully",
})
},
})
const onDownload = () => {
toast({
title: "Gist Downloaded",
description: "Your gist has been downloaded successfully",
})
}
const onSave = (name: string, code: string) => {
updateContent({ id: gistId, content: code })
updateName({ id: gistId, name })
toast({
title: "Gist Saved",
description: "Your gist has been saved successfully",
console.log("save")
edit({
id: gistId,
name,
content: code,
description: "",
visibility: "public",
org_id: null,
language: "plaintext",
owner_id: me?.id || "",
})
}

Expand Down
12 changes: 10 additions & 2 deletions src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client"
import { useToast } from "@/components/shadcn/use-toast"
import GistDetails from "@/components/ui/gist-details"
import { useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries"
import { useEditGist, useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries"
import { useOrg } from "@/lib/queries/orgs.queries"
import { getRawGistURL } from "@/lib/utils"
import React from "react"
Expand Down Expand Up @@ -31,6 +31,15 @@
onSuccess: () => {},
})

const { mutate: edit } = useEditGist({

Check warning on line 34 in src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'edit' is assigned a value but never used
onSuccess: () => {
toast({
title: "Gist Saved",
description: "Your gist has been saved successfully",
})
},
})

const onDownload = () => {
toast({
title: "Gist Downloaded",
Expand All @@ -55,8 +64,7 @@
})
}

const onDelete = (id: string) => {

Check warning on line 67 in src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'id' is defined but never used
console.log(`Deleting gist with ID: ${id}`)
toast({
title: "Gist Deleted",
description: "Your gist has been deleted successfully",
Expand Down
1 change: 0 additions & 1 deletion src/components/contexts/pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
offset: 0,
limit: 9,
nb_pages: 0,
setOffset: (offset: number) => {},

Check warning on line 18 in src/components/contexts/pagination.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'offset' is defined but never used
setLimit: (limit: number) => {},

Check warning on line 19 in src/components/contexts/pagination.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'limit' is defined but never used
setNbPages: (nb_pages: number) => {},

Check warning on line 20 in src/components/contexts/pagination.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'nb_pages' is defined but never used
}

export const PaginationContext = createContext<PaginationContextContent>(PaginationInitialState)
Expand Down Expand Up @@ -58,7 +58,6 @@
if (searchParams.has("page")) {
const page = parseInt(searchParams.get("page") as string)
const offset = (page - 1) * limit
console.log("offset", offset)
if (!checkOffset(offset)) return
setOffset(offset)
}
Expand Down
16 changes: 12 additions & 4 deletions src/components/ui/gist-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import {
Trash2Icon,
} from "lucide-react"
import Link from "next/link"
import { useState } from "react"
import { useEffect, useState } from "react"
import { Codearea } from "../shadcn/codearea"
import { getLanguage } from "@/lib/language"
import TooltipShortcut, { TooltipShortcutTrigger } from "./tooltip-shortcut"
import { getBackendURL, getRawGistURL } from "@/lib/utils"
import { getRawGistURL } from "@/lib/utils"
import { SidebarTrigger } from "../shadcn/sidebar"
import { Button } from "../shadcn/button"

Expand Down Expand Up @@ -46,6 +46,15 @@ export default function GistDetails({
const [gistId] = useState(gist.id)
const [gistName, setGistName] = useState(gist.name)
const [gistCode, setGistCode] = useState(gist.code)
const [needSync, setNeedSync] = useState(false)

useEffect(() => {
if (gist.name !== gistName || gist.code !== gistCode) {
setNeedSync(true)
} else {
setNeedSync(false)
}
}, [gistName, gistCode])

const gistState: Gist = {
id: gistId,
Expand All @@ -54,7 +63,6 @@ export default function GistDetails({
}

const onOpenPlainText = (gistID: string) => {
// if production go to https://raw.gists.app/{gistID}
console.log(process.env.NODE_ENV)
window.open(getRawGistURL(gistID), "_blank")
}
Expand Down Expand Up @@ -117,7 +125,7 @@ export default function GistDetails({
</TooltipShortcut>
<TooltipShortcut tooltip="Save" shortcuts={["Ctrl", "S"]}>
<TooltipShortcutTrigger>
<MenuButton onClick={() => onSave(gistName, gistCode)} variant={"menu"}>
<MenuButton onClick={() => onSave(gistName, gistCode)} variant={"menu"} disabled={!needSync}>
<span>Save</span>
</MenuButton>
</TooltipShortcutTrigger>
Expand Down
102 changes: 86 additions & 16 deletions src/lib/queries/gists.queries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import ky from "ky"
import { getBackendURL } from "../utils"
import { Gist } from "@/types"
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
import { keepPreviousData, useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"

Check warning on line 5 in src/lib/queries/gists.queries.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'keepPreviousData' is defined but never used
import { useEffect } from "react"
import { useGistStorage } from "../storage/gists"

Check warning on line 7 in src/lib/queries/gists.queries.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'useGistStorage' is defined but never used

//types

Expand All @@ -11,6 +13,9 @@
name: string
content: string
owner_id: string
language: string
description: string
visibility: string
org_id: string | null
}

Expand Down Expand Up @@ -131,17 +136,35 @@
//hooks

export const useGists = ({ offset, limit }: { offset?: number; limit?: number }) => {
const { data, error, isPending } = useQuery({
queryKey: ["gists", offset?.toString(), limit?.toString()],
queryFn: () =>
fetchGists({
offset: offset || 0,
const { data, error, isFetching, fetchNextPage, fetchPreviousPage } = useInfiniteQuery({
queryKey: ["gists"],
queryFn: ({ pageParam }) => fetchGists(pageParam),
initialPageParam: {
offset: offset || 0,
limit: limit || 50,
},
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
return {
offset: offset || 0 + (limit || 50),
limit: limit || 50,
}),
staleTime: 5000,
}
},
})

return { data: data?.gists, nb_pages: data?.nb_pages, error, isPending }
const currentPage = Math.trunc((offset || 0) / (limit || 50))

useEffect(() => {
fetchNextPage() //prefetch
}, [offset, limit])

return {
data: data?.pages[currentPage]?.gists,
nb_pages: data?.pages[0].nb_pages,
error,
isPending: isFetching,
fetchNextPage,
fetchPreviousPage,
}
}

export const useGist = (gistId: string) => {
Expand All @@ -160,10 +183,14 @@
return fetchCreateGist(gist)
},
onSuccess: (newGist) => {
queryClient.setQueryData(["gists"], (oldData: any) => {
// Assuming oldData is an array, you might need to adjust this based on your actual data structure
return [...(oldData || []), newGist]
})
//invalidate
queryClient.invalidateQueries({ queryKey: ["gists"] })
// queryClient.setQueryData(["gists"], (oldData: any) => {
// // Assuming oldData is an array, you might need to adjust this based on your actual data structure
//
//
// return [...(oldData || []), newGist]
// })

// Call the onSuccess callback if provided
if (onSuccess) {
Expand Down Expand Up @@ -228,12 +255,55 @@
return fetchDeleteGist(id)
},
onSuccess: (gistID) => {
queryClient.setQueryData(["gists"], (oldData: any) => {
return oldData.filter((gist: Gist) => gist.id !== gistID.toString())
})
// queryClient.setQueryData(["gists"], (oldData: any) => {
// return oldData.filter((gist: Gist) => gist.id !== gistID.toString())
// })
queryClient.invalidateQueries({ queryKey: ["gists"] })
onSuccess(gistID.toString())
},
})

return { mutate, error, data, isPending }
}

const fetchUpdateGist = async (payload: ApiGist): Promise<Gist> => {
const json = await ky
.put(`${getBackendURL()}/gists/${payload.id}`, {
credentials: "include",
json: {
name: payload.name,
content: payload.content,
description: payload.description,
visibility: payload.visibility,
org_id: payload.org_id,
},
})
.json<ApiGist>()
console.log(json)
return {
id: json.id,
name: json.name,
code: json.content,
}
}

export const useEditGist = ({ onSuccess }: { onSuccess: () => void }) => {
const queryClient = useQueryClient() // Access the Query Client

const { mutate, error, data, isPending } = useMutation({
mutationFn: (payload: ApiGist) => {
return fetchUpdateGist(payload)
},
onError(error, variables, context) {
console.log(error)
},
onSuccess: (newGist) => {
queryClient.invalidateQueries({ queryKey: ["gists"] })
queryClient.invalidateQueries({ queryKey: ["gists", newGist.id] })
if (onSuccess) {
onSuccess()
}
},
})
return { mutate, error, data, isPending }
}
12 changes: 12 additions & 0 deletions src/lib/storage/gists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Gist } from "@/types"
import DataStorage from "./storage"
import { set } from "react-hook-form"

const globalGistStorage = new DataStorage<Gist>()

export const useGistStorage = () => {
return {
set: globalGistStorage.set.bind(globalGistStorage),
getItems: globalGistStorage.getItems.bind(globalGistStorage),
}
}
20 changes: 20 additions & 0 deletions src/lib/storage/storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"use client"
interface ItemWithID {
id: string
}

class DataStorage<T extends ItemWithID> {
private data: Map<string, T> = new Map()
set(data: T) {
this.data.set(data.id, data)
}
getItems(offset?: number, limit?: number): T[] {
if (offset !== undefined && limit !== undefined) {
return Array.from(this.data.values()).slice(offset, offset + limit)
}

return Array.from(this.data.values())
}
}

export default DataStorage
Loading