1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
"use client"
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { createSupabaseBrowserClient } from "@/lib/supabase/client"
import { queryKeys } from "./query-keys"
import { notify } from "@/lib/notify"
interface CreateHighlightParameters {
entryIdentifier: string
highlightedText: string
textOffset: number
textLength: number
textPrefix: string
textSuffix: string
note?: string | null
color?: string
}
export function useCreateHighlight() {
const supabaseClient = createSupabaseBrowserClient()
const queryClient = useQueryClient()
return useMutation({
mutationFn: async (parameters: CreateHighlightParameters) => {
const {
data: { user },
} = await supabaseClient.auth.getUser()
if (!user) throw new Error("not authenticated")
const { data, error } = await supabaseClient
.from("user_highlights")
.insert({
user_id: user.id,
entry_id: parameters.entryIdentifier,
highlighted_text: parameters.highlightedText,
text_offset: parameters.textOffset,
text_length: parameters.textLength,
text_prefix: parameters.textPrefix,
text_suffix: parameters.textSuffix,
note: parameters.note ?? null,
color: parameters.color ?? "yellow",
})
.select("id")
.single()
if (error) throw error
return data.id as string
},
onSuccess: (_data, variables) => {
queryClient.invalidateQueries({
queryKey: queryKeys.highlights.forEntry(variables.entryIdentifier),
})
queryClient.invalidateQueries({ queryKey: queryKeys.highlights.all })
queryClient.invalidateQueries({ queryKey: queryKeys.userProfile.all })
notify("text highlighted")
},
onError: (error: Error) => {
notify(
error.message.includes("limit")
? "highlight limit reached for your plan"
: "failed to create highlight"
)
},
})
}
export function useUpdateHighlightNote() {
const supabaseClient = createSupabaseBrowserClient()
const queryClient = useQueryClient()
return useMutation({
mutationFn: async ({
highlightIdentifier,
note,
}: {
highlightIdentifier: string
note: string | null
entryIdentifier: string
}) => {
const { error } = await supabaseClient
.from("user_highlights")
.update({ note })
.eq("id", highlightIdentifier)
if (error) throw error
},
onSuccess: (_data, variables) => {
queryClient.invalidateQueries({
queryKey: queryKeys.highlights.forEntry(variables.entryIdentifier),
})
queryClient.invalidateQueries({ queryKey: queryKeys.highlights.all })
notify("note updated")
},
onError: () => {
notify("failed to update note")
},
})
}
export function useDeleteHighlight() {
const supabaseClient = createSupabaseBrowserClient()
const queryClient = useQueryClient()
return useMutation({
mutationFn: async ({
highlightIdentifier,
}: {
highlightIdentifier: string
entryIdentifier: string
}) => {
const { error } = await supabaseClient
.from("user_highlights")
.delete()
.eq("id", highlightIdentifier)
if (error) throw error
},
onSuccess: (_data, variables) => {
queryClient.invalidateQueries({
queryKey: queryKeys.highlights.forEntry(variables.entryIdentifier),
})
queryClient.invalidateQueries({ queryKey: queryKeys.highlights.all })
queryClient.invalidateQueries({ queryKey: queryKeys.userProfile.all })
notify("highlight removed")
},
onError: () => {
notify("failed to remove highlight")
},
})
}
|