@bbki.ng/site 2.0.36 → 2.0.37

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
@@ -1,5 +1,7 @@
1
1
  # @bbki.ng/site
2
2
 
3
+ ## 2.0.37
4
+
3
5
  ## 2.0.36
4
6
 
5
7
  ## 2.0.35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbki.ng/site",
3
- "version": "2.0.36",
3
+ "version": "2.0.37",
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.9",
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[];
@@ -45,7 +45,7 @@ export const ArticlePage = (props: ArticlePageProps) => {
45
45
  </Article>
46
46
  <div className="p-16">
47
47
  <span>{<Tags tags={allTags} />}</span>
48
- <OpenHeartReaction title={title} />
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
+ marginTop: "1rem",
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
- };