@bbki.ng/site 2.0.36 → 2.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bbki.ng/site",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.39",
|
|
4
4
|
"description": "code behind bbki.ng",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@extism/extism": "2.0.0-rc11",
|
|
20
|
-
"@bbki.ng/components": "workspace:2.6.
|
|
20
|
+
"@bbki.ng/components": "workspace:2.6.10",
|
|
21
21
|
"@supabase/supabase-js": "^1.35.4",
|
|
22
22
|
"classnames": "2.3.1",
|
|
23
23
|
"react": "^18.0.0",
|
|
@@ -4,7 +4,7 @@ import { ROUTES } from "@/constants";
|
|
|
4
4
|
import classNames from "classnames";
|
|
5
5
|
import { GlobalLoadingContext } from "@/context/global_loading_state_provider";
|
|
6
6
|
import { useSafeArticleLoading } from "@/hooks/use_safe_loading";
|
|
7
|
-
import { OpenHeartReaction } from "../oh_reaction";
|
|
7
|
+
import { OpenHeartReaction, Reaction } from "../reaction/oh_reaction";
|
|
8
8
|
|
|
9
9
|
export type ArticlePageProps = {
|
|
10
10
|
tags?: string[];
|
|
@@ -29,23 +29,23 @@ export const ArticlePage = (props: ArticlePageProps) => {
|
|
|
29
29
|
return props.children;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const articleCls = classNames("prose"
|
|
33
|
-
"mb-20": true,
|
|
34
|
-
});
|
|
32
|
+
const articleCls = classNames("prose");
|
|
35
33
|
|
|
36
34
|
return (
|
|
37
35
|
<>
|
|
38
36
|
<Article
|
|
39
37
|
title={title}
|
|
40
38
|
description={description}
|
|
41
|
-
className={props.className}
|
|
39
|
+
className={`${props.className} mb-128`}
|
|
42
40
|
loading={loading}
|
|
43
41
|
>
|
|
44
42
|
<article className={articleCls}>{props.children}</article>
|
|
43
|
+
<div className="mt-[1.25em] relative left-[-4px]">
|
|
44
|
+
{<Tags tags={allTags} />}
|
|
45
|
+
</div>
|
|
45
46
|
</Article>
|
|
46
|
-
<div className="
|
|
47
|
-
<
|
|
48
|
-
<OpenHeartReaction title={title} />
|
|
47
|
+
<div className="px-16">
|
|
48
|
+
<Reaction title={title} />
|
|
49
49
|
</div>
|
|
50
50
|
</>
|
|
51
51
|
);
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
const HEART_SIZE = 12;
|
|
5
|
+
|
|
6
|
+
export interface ReactionEmojiPair {
|
|
7
|
+
on: ReactNode;
|
|
8
|
+
off: ReactNode;
|
|
9
|
+
val: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const heart = (
|
|
13
|
+
<svg
|
|
14
|
+
data-testid="geist-icon"
|
|
15
|
+
height={HEART_SIZE}
|
|
16
|
+
width={HEART_SIZE}
|
|
17
|
+
stroke-linejoin="round"
|
|
18
|
+
className="text-gray-400 hover:text-red-400 transition-colors ease-in duration-200"
|
|
19
|
+
viewBox="0 0 16 16"
|
|
20
|
+
>
|
|
21
|
+
<path
|
|
22
|
+
fill-rule="evenodd"
|
|
23
|
+
clip-rule="evenodd"
|
|
24
|
+
d="M7.06463 3.20474C5.79164 1.93175 3.72772 1.93175 2.45474 3.20474C1.18175 4.47773 1.18175 6.54166 2.45474 7.81465L8 13.3599L13.5453 7.81465C14.8182 6.54166 14.8182 4.47773 13.5453 3.20474C12.2723 1.93175 10.2084 1.93175 8.93537 3.20474L8.53033 3.60979L8 4.14012L7.46967 3.60979L7.06463 3.20474ZM8 2.02321C6.13348 0.286219 3.21165 0.326509 1.39408 2.14408C-0.464694 4.00286 -0.464691 7.01653 1.39408 8.87531L7.46967 14.9509L8 15.4812L8.53033 14.9509L14.6059 8.87531C16.4647 7.01653 16.4647 4.00286 14.6059 2.14408C12.7884 0.326509 9.86653 0.286221 8 2.02321Z"
|
|
25
|
+
fill="currentColor"
|
|
26
|
+
></path>
|
|
27
|
+
</svg>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const heartFill = (
|
|
31
|
+
<svg
|
|
32
|
+
data-testid="geist-icon"
|
|
33
|
+
height={HEART_SIZE}
|
|
34
|
+
width={HEART_SIZE}
|
|
35
|
+
stroke-linejoin="round"
|
|
36
|
+
className="text-red-400"
|
|
37
|
+
viewBox={`0 0 16 16`}
|
|
38
|
+
>
|
|
39
|
+
<path
|
|
40
|
+
d="M1.39408 2.14408C3.21165 0.326509 6.13348 0.286219 8 2.02321C9.86652 0.286221 12.7884 0.326509 14.6059 2.14408C16.4647 4.00286 16.4647 7.01653 14.6059 8.87531L8 15.4812L1.39408 8.87531C-0.464691 7.01653 -0.464694 4.00286 1.39408 2.14408Z"
|
|
41
|
+
fill="currentColor"
|
|
42
|
+
></path>
|
|
43
|
+
</svg>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const happyFace = (
|
|
47
|
+
<svg
|
|
48
|
+
data-testid="geist-icon"
|
|
49
|
+
stroke-linejoin="round"
|
|
50
|
+
height={HEART_SIZE}
|
|
51
|
+
width={HEART_SIZE}
|
|
52
|
+
className="text-gray-400 hover:text-gray-600 transition-colors ease-in duration-200"
|
|
53
|
+
viewBox="0 0 16 16"
|
|
54
|
+
>
|
|
55
|
+
<path
|
|
56
|
+
fill-rule="evenodd"
|
|
57
|
+
clip-rule="evenodd"
|
|
58
|
+
d="M14.5 8C14.5 11.5899 11.5899 14.5 8 14.5C4.41015 14.5 1.5 11.5899 1.5 8C1.5 4.41015 4.41015 1.5 8 1.5C11.5899 1.5 14.5 4.41015 14.5 8ZM16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8ZM11.5249 10.8478L11.8727 10.3286L10.8342 9.6329L10.4863 10.1522C9.94904 10.9543 9.0363 11.4802 8.00098 11.4802C6.96759 11.4802 6.05634 10.9563 5.51863 10.1567L5.16986 9.63804L4.13259 10.3356L4.48137 10.8542C5.2414 11.9844 6.53398 12.7302 8.00098 12.7302C9.47073 12.7302 10.7654 11.9816 11.5249 10.8478ZM6.75 6.75C6.75 7.30228 6.30228 7.75 5.75 7.75C5.19772 7.75 4.75 7.30228 4.75 6.75C4.75 6.19772 5.19772 5.75 5.75 5.75C6.30228 5.75 6.75 6.19772 6.75 6.75ZM10.25 7.75C10.8023 7.75 11.25 7.30228 11.25 6.75C11.25 6.19772 10.8023 5.75 10.25 5.75C9.69771 5.75 9.25 6.19772 9.25 6.75C9.25 7.30228 9.69771 7.75 10.25 7.75Z"
|
|
59
|
+
fill="currentColor"
|
|
60
|
+
></path>
|
|
61
|
+
</svg>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const smileFace = (
|
|
65
|
+
<svg
|
|
66
|
+
height={HEART_SIZE}
|
|
67
|
+
width={HEART_SIZE}
|
|
68
|
+
data-testid="geist-icon"
|
|
69
|
+
className="text-gray-400"
|
|
70
|
+
stroke-linejoin="round"
|
|
71
|
+
viewBox="0 0 16 16"
|
|
72
|
+
>
|
|
73
|
+
<path
|
|
74
|
+
fill-rule="evenodd"
|
|
75
|
+
clip-rule="evenodd"
|
|
76
|
+
d="M14.5 8C14.5 11.5899 11.5899 14.5 8 14.5C4.41015 14.5 1.5 11.5899 1.5 8C1.5 4.41015 4.41015 1.5 8 1.5C11.5899 1.5 14.5 4.41015 14.5 8ZM16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8ZM4.5 8.97498H3.875V9.59998C3.875 11.4747 5.81046 12.8637 7.99817 12.8637C10.1879 12.8637 12.125 11.4832 12.125 9.59998V8.97498H11.5H4.5ZM7.99817 11.6137C6.59406 11.6137 5.63842 10.9482 5.28118 10.225H10.7202C10.3641 10.9504 9.40797 11.6137 7.99817 11.6137Z"
|
|
77
|
+
fill="currentColor"
|
|
78
|
+
></path>
|
|
79
|
+
<path
|
|
80
|
+
fill-rule="evenodd"
|
|
81
|
+
clip-rule="evenodd"
|
|
82
|
+
d="M6.15295 4.92093L5.375 3.5L4.59705 4.92093L3 5.21885L4.11625 6.39495L3.90717 8L5.375 7.30593L6.84283 8L6.63375 6.39495L7.75 5.21885L6.15295 4.92093ZM11.403 4.92093L10.625 3.5L9.84705 4.92093L8.25 5.21885L9.36625 6.39495L9.15717 8L10.625 7.30593L12.0928 8L11.8837 6.39495L13 5.21885L11.403 4.92093Z"
|
|
83
|
+
fill="var(--ds-amber-800)"
|
|
84
|
+
></path>
|
|
85
|
+
</svg>
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const unhappyFace = (
|
|
89
|
+
<svg
|
|
90
|
+
data-testid="geist-icon"
|
|
91
|
+
stroke-linejoin="round"
|
|
92
|
+
viewBox="0 0 16 16"
|
|
93
|
+
height={HEART_SIZE}
|
|
94
|
+
width={HEART_SIZE}
|
|
95
|
+
className="text-gray-400 hover:text-gray-600 transition-colors ease-in duration-200"
|
|
96
|
+
>
|
|
97
|
+
<path
|
|
98
|
+
fill-rule="evenodd"
|
|
99
|
+
clip-rule="evenodd"
|
|
100
|
+
d="M14.5 8C14.5 11.5899 11.5899 14.5 8 14.5C4.41015 14.5 1.5 11.5899 1.5 8C1.5 4.41015 4.41015 1.5 8 1.5C11.5899 1.5 14.5 4.41015 14.5 8ZM16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8ZM5.75 7.75C6.30228 7.75 6.75 7.30228 6.75 6.75C6.75 6.19772 6.30228 5.75 5.75 5.75C5.19772 5.75 4.75 6.19772 4.75 6.75C4.75 7.30228 5.19772 7.75 5.75 7.75ZM11.25 6.75C11.25 7.30228 10.8023 7.75 10.25 7.75C9.69771 7.75 9.25 7.30228 9.25 6.75C9.25 6.19772 9.69771 5.75 10.25 5.75C10.8023 5.75 11.25 6.19772 11.25 6.75ZM11.5249 11.2622L11.8727 11.7814L10.8342 12.4771L10.4863 11.9578C9.94904 11.1557 9.0363 10.6298 8.00098 10.6298C6.96759 10.6298 6.05634 11.1537 5.51863 11.9533L5.16986 12.4719L4.13259 11.7744L4.48137 11.2558C5.2414 10.1256 6.53398 9.37982 8.00098 9.37982C9.47073 9.37982 10.7654 10.1284 11.5249 11.2622Z"
|
|
101
|
+
fill="currentColor"
|
|
102
|
+
></path>
|
|
103
|
+
</svg>
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const sadFace = (
|
|
107
|
+
<svg
|
|
108
|
+
data-testid="geist-icon"
|
|
109
|
+
stroke-linejoin="round"
|
|
110
|
+
height={HEART_SIZE}
|
|
111
|
+
width={HEART_SIZE}
|
|
112
|
+
viewBox="0 0 16 16"
|
|
113
|
+
className="text-gray-400"
|
|
114
|
+
>
|
|
115
|
+
<path
|
|
116
|
+
fill-rule="evenodd"
|
|
117
|
+
clip-rule="evenodd"
|
|
118
|
+
d="M4 9V16H5.5V9H4ZM12 9V16H10.5V9H12Z"
|
|
119
|
+
fill="var(--ds-blue-700)"
|
|
120
|
+
></path>
|
|
121
|
+
<path
|
|
122
|
+
fill-rule="evenodd"
|
|
123
|
+
clip-rule="evenodd"
|
|
124
|
+
d="M1.5 8C1.5 4.41015 4.41015 1.5 8 1.5C11.5899 1.5 14.5 4.41015 14.5 8C14.5 9.57941 13.9367 11.0273 13 12.1536V14.2454C14.8289 12.7793 16 10.5264 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 10.5264 1.17107 12.7793 3 14.2454V12.1536C2.06332 11.0273 1.5 9.57941 1.5 8ZM8 14.5C8.51627 14.5 9.01848 14.4398 9.5 14.3261V15.8596C9.01412 15.9518 8.51269 16 8 16C7.48731 16 6.98588 15.9518 6.5 15.8596V14.3261C6.98152 14.4398 7.48373 14.5 8 14.5ZM3.78568 8.36533C4.15863 7.98474 4.67623 7.75 5.25 7.75C5.82377 7.75 6.34137 7.98474 6.71432 8.36533L7.78568 7.31548C7.14222 6.65884 6.24318 6.25 5.25 6.25C4.25682 6.25 3.35778 6.65884 2.71432 7.31548L3.78568 8.36533ZM10.75 7.75C10.1762 7.75 9.65863 7.98474 9.28568 8.36533L8.21432 7.31548C8.85778 6.65884 9.75682 6.25 10.75 6.25C11.7432 6.25 12.6422 6.65884 13.2857 7.31548L12.2143 8.36533C11.8414 7.98474 11.3238 7.75 10.75 7.75ZM6.25 12H9.75C9.75 11.0335 8.9665 10.25 8 10.25C7.0335 10.25 6.25 11.0335 6.25 12Z"
|
|
125
|
+
fill="currentColor"
|
|
126
|
+
></path>
|
|
127
|
+
</svg>
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
export const hearts: ReactionEmojiPair = {
|
|
131
|
+
on: heartFill,
|
|
132
|
+
off: heart,
|
|
133
|
+
val: "❤️",
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export const faces: ReactionEmojiPair = {
|
|
137
|
+
on: smileFace,
|
|
138
|
+
off: happyFace,
|
|
139
|
+
val: "🙂",
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export const sadFaces: ReactionEmojiPair = {
|
|
143
|
+
on: sadFace,
|
|
144
|
+
off: unhappyFace,
|
|
145
|
+
val: "😞",
|
|
146
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
ReactNode,
|
|
3
|
+
useContext,
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from "react";
|
|
8
|
+
import { GlobalLoadingContext } from "@/context/global_loading_state_provider";
|
|
9
|
+
import { BlinkDot } from "@bbki.ng/components";
|
|
10
|
+
import { faces, hearts, ReactionEmojiPair, sadFaces } from "./emojis";
|
|
11
|
+
|
|
12
|
+
declare global {
|
|
13
|
+
namespace JSX {
|
|
14
|
+
interface IntrinsicElements {
|
|
15
|
+
"open-heart": React.DetailedHTMLProps<
|
|
16
|
+
React.HTMLAttributes<HTMLElement> & {
|
|
17
|
+
href?: string;
|
|
18
|
+
emoji?: string;
|
|
19
|
+
ariaDisabled?: boolean;
|
|
20
|
+
onClick?: React.MouseEventHandler<HTMLElement>;
|
|
21
|
+
},
|
|
22
|
+
HTMLElement
|
|
23
|
+
>;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const useHeartSent = (val: string) => {
|
|
29
|
+
const [sent, setSent] = useState(false);
|
|
30
|
+
const { setIsLoading } = useContext(GlobalLoadingContext);
|
|
31
|
+
|
|
32
|
+
const handleSent = (evt: Event) => {
|
|
33
|
+
const targetVal = (evt.target as HTMLElement).getAttribute("emoji");
|
|
34
|
+
|
|
35
|
+
if (targetVal == val) setSent(true);
|
|
36
|
+
setIsLoading(false);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
addEventListener("open-heart", handleSent);
|
|
41
|
+
|
|
42
|
+
return () => {
|
|
43
|
+
removeEventListener("open-heart", handleSent);
|
|
44
|
+
};
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
return sent;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const OpenHeartReaction = (props: {
|
|
51
|
+
title: string;
|
|
52
|
+
emojiPair: ReactionEmojiPair;
|
|
53
|
+
}) => {
|
|
54
|
+
const { title, emojiPair = hearts } = props;
|
|
55
|
+
const sent = useHeartSent(emojiPair.val);
|
|
56
|
+
|
|
57
|
+
const { setIsLoading } = useContext(GlobalLoadingContext);
|
|
58
|
+
|
|
59
|
+
const ohRef = useRef<HTMLElement>(null);
|
|
60
|
+
|
|
61
|
+
const pressed = () => ohRef.current?.getAttribute("aria-pressed");
|
|
62
|
+
|
|
63
|
+
const handleHeartClick = () => {
|
|
64
|
+
if (sent || pressed()) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
setIsLoading(true);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<open-heart
|
|
73
|
+
style={{
|
|
74
|
+
display: "inline-flex",
|
|
75
|
+
padding: 4,
|
|
76
|
+
marginRight: "4px",
|
|
77
|
+
position: "relative",
|
|
78
|
+
}}
|
|
79
|
+
ref={ohRef}
|
|
80
|
+
href={`https://oh.bbking.workers.dev/?id=${title}`}
|
|
81
|
+
emoji={emojiPair.val}
|
|
82
|
+
onClick={handleHeartClick}
|
|
83
|
+
>
|
|
84
|
+
{sent || pressed() ? emojiPair.on : emojiPair.off}
|
|
85
|
+
</open-heart>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const Reaction = (props: { title: string }) => {
|
|
90
|
+
return (
|
|
91
|
+
<div>
|
|
92
|
+
<OpenHeartReaction title={props.title} emojiPair={hearts} />
|
|
93
|
+
<OpenHeartReaction title={props.title} emojiPair={faces} />
|
|
94
|
+
<OpenHeartReaction title={props.title} emojiPair={sadFaces} />
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
ReactNode,
|
|
3
|
-
useContext,
|
|
4
|
-
useEffect,
|
|
5
|
-
useRef,
|
|
6
|
-
useState,
|
|
7
|
-
} from "react";
|
|
8
|
-
import { BlinkDot } from "@bbki.ng/components";
|
|
9
|
-
import { GlobalLoadingContext } from "@/context/global_loading_state_provider";
|
|
10
|
-
|
|
11
|
-
declare global {
|
|
12
|
-
namespace JSX {
|
|
13
|
-
interface IntrinsicElements {
|
|
14
|
-
"open-heart": React.DetailedHTMLProps<
|
|
15
|
-
React.HTMLAttributes<HTMLElement> & {
|
|
16
|
-
href?: string;
|
|
17
|
-
emoji?: string;
|
|
18
|
-
ariaDisabled?: boolean;
|
|
19
|
-
onClick?: React.MouseEventHandler<HTMLElement>;
|
|
20
|
-
},
|
|
21
|
-
HTMLElement
|
|
22
|
-
>;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const HEART_SIZE = 12;
|
|
28
|
-
|
|
29
|
-
const heart = (
|
|
30
|
-
<svg
|
|
31
|
-
data-testid="geist-icon"
|
|
32
|
-
height={HEART_SIZE}
|
|
33
|
-
width={HEART_SIZE}
|
|
34
|
-
stroke-linejoin="round"
|
|
35
|
-
// style={{ color: "#fecaca" }}
|
|
36
|
-
className="text-gray-400 hover:text-red-400 transition-colors ease-in duration-200"
|
|
37
|
-
viewBox="0 0 16 16"
|
|
38
|
-
>
|
|
39
|
-
<path
|
|
40
|
-
fill-rule="evenodd"
|
|
41
|
-
clip-rule="evenodd"
|
|
42
|
-
d="M7.06463 3.20474C5.79164 1.93175 3.72772 1.93175 2.45474 3.20474C1.18175 4.47773 1.18175 6.54166 2.45474 7.81465L8 13.3599L13.5453 7.81465C14.8182 6.54166 14.8182 4.47773 13.5453 3.20474C12.2723 1.93175 10.2084 1.93175 8.93537 3.20474L8.53033 3.60979L8 4.14012L7.46967 3.60979L7.06463 3.20474ZM8 2.02321C6.13348 0.286219 3.21165 0.326509 1.39408 2.14408C-0.464694 4.00286 -0.464691 7.01653 1.39408 8.87531L7.46967 14.9509L8 15.4812L8.53033 14.9509L14.6059 8.87531C16.4647 7.01653 16.4647 4.00286 14.6059 2.14408C12.7884 0.326509 9.86653 0.286221 8 2.02321Z"
|
|
43
|
-
fill="currentColor"
|
|
44
|
-
></path>
|
|
45
|
-
</svg>
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
const heartFill = (
|
|
49
|
-
<svg
|
|
50
|
-
data-testid="geist-icon"
|
|
51
|
-
height={HEART_SIZE}
|
|
52
|
-
width={HEART_SIZE}
|
|
53
|
-
stroke-linejoin="round"
|
|
54
|
-
className="text-red-400"
|
|
55
|
-
viewBox={`0 0 16 16`}
|
|
56
|
-
>
|
|
57
|
-
<path
|
|
58
|
-
d="M1.39408 2.14408C3.21165 0.326509 6.13348 0.286219 8 2.02321C9.86652 0.286221 12.7884 0.326509 14.6059 2.14408C16.4647 4.00286 16.4647 7.01653 14.6059 8.87531L8 15.4812L1.39408 8.87531C-0.464691 7.01653 -0.464694 4.00286 1.39408 2.14408Z"
|
|
59
|
-
fill="currentColor"
|
|
60
|
-
></path>
|
|
61
|
-
</svg>
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
const useHeartSent = () => {
|
|
65
|
-
const [sent, setSent] = useState(false);
|
|
66
|
-
const { setIsLoading } = useContext(GlobalLoadingContext);
|
|
67
|
-
|
|
68
|
-
const handleSent = () => {
|
|
69
|
-
console.log("heart sent");
|
|
70
|
-
setSent(true);
|
|
71
|
-
setIsLoading(false);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
useEffect(() => {
|
|
75
|
-
addEventListener("open-heart", handleSent);
|
|
76
|
-
|
|
77
|
-
return () => {
|
|
78
|
-
removeEventListener("open-heart", handleSent);
|
|
79
|
-
};
|
|
80
|
-
}, []);
|
|
81
|
-
|
|
82
|
-
return sent;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
export const OpenHeartReaction = (props: { title: string }) => {
|
|
86
|
-
const { title } = props;
|
|
87
|
-
const sent = useHeartSent();
|
|
88
|
-
|
|
89
|
-
const { setIsLoading } = useContext(GlobalLoadingContext);
|
|
90
|
-
|
|
91
|
-
const ohRef = useRef<HTMLElement>(null);
|
|
92
|
-
|
|
93
|
-
const pressed = () => ohRef.current?.getAttribute("aria-pressed");
|
|
94
|
-
|
|
95
|
-
const handleHeartClick = () => {
|
|
96
|
-
if (sent || pressed()) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
setIsLoading(true);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
return (
|
|
104
|
-
<open-heart
|
|
105
|
-
style={{
|
|
106
|
-
display: "flex",
|
|
107
|
-
padding: 4,
|
|
108
|
-
marginTop: "1rem",
|
|
109
|
-
}}
|
|
110
|
-
ref={ohRef}
|
|
111
|
-
href={`https://oh.bbking.workers.dev/?id=${title}`}
|
|
112
|
-
emoji="❤️"
|
|
113
|
-
onClick={handleHeartClick}
|
|
114
|
-
>
|
|
115
|
-
{sent || pressed() ? heartFill : heart}
|
|
116
|
-
</open-heart>
|
|
117
|
-
);
|
|
118
|
-
};
|