gitalk-react 1.0.0-beta.4 → 1.0.0-beta.6

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/lib/gitalk.tsx CHANGED
@@ -46,7 +46,13 @@ import logger from "./utils/logger";
46
46
  import { parseSearchQuery, stringifySearchQuery } from "./utils/query";
47
47
 
48
48
  export interface GitalkProps
49
- extends Omit<React.HTMLAttributes<HTMLDivElement>, "id" | "title"> {
49
+ extends Omit<
50
+ React.DetailedHTMLProps<
51
+ React.HTMLAttributes<HTMLDivElement>,
52
+ HTMLDivElement
53
+ >,
54
+ "id" | "title"
55
+ > {
50
56
  /**
51
57
  * GitHub Application Client ID.
52
58
  */
@@ -113,7 +119,7 @@ export interface GitalkProps
113
119
  perPage?: number;
114
120
  /**
115
121
  * Comment sorting direction.
116
- * Available values are last and first.
122
+ * Available values are `last` and `first`.
117
123
  *
118
124
  * @default "last"
119
125
  */
@@ -261,7 +267,7 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
261
267
  () => (propsPerPage > 100 ? 100 : propsPerPage < 0 ? 10 : propsPerPage),
262
268
  [propsPerPage],
263
269
  );
264
- const [commentsLoaded, setCommentsLoaded] = useState<boolean>(false);
270
+ /** Current sort order, have effect when user is logged */
265
271
  const [commentsPagerDirection, setCommentsPagerDirection] =
266
272
  useState(pagerDirection);
267
273
  const defaultUser = useMemo(
@@ -484,6 +490,7 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
484
490
  const {
485
491
  data: comments = [],
486
492
  mutate: setComments,
493
+ run: runGetComments,
487
494
  loading: getCommentsLoading,
488
495
  } = useRequest(
489
496
  async (): Promise<CommentType[]> => {
@@ -494,7 +501,7 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
494
501
  if (user) {
495
502
  // Get comments via GraphQL, witch requires being logged and able to sort
496
503
  const query = getIssueCommentsQL({
497
- pagerDirection,
504
+ pagerDirection: commentsPagerDirection,
498
505
  });
499
506
 
500
507
  const getIssueCommentsRes: IssueCommentsQLResponse =
@@ -534,11 +541,14 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
534
541
  _comments,
535
542
  );
536
543
 
537
- if (_comments.length < commentsPerPage) {
538
- setCommentsLoaded(true);
539
- }
544
+ const commentsPageInfo =
545
+ getIssueCommentsRes.repository.issue.comments.pageInfo;
546
+ const commentsPageCursor =
547
+ commentsPageInfo.startCursor || commentsPageInfo.endCursor || "";
548
+ setCommentsCursor(commentsPageCursor);
540
549
 
541
- if (pagerDirection === "last") return [..._comments, ...comments];
550
+ if (commentsPagerDirection === "last")
551
+ return [..._comments, ...comments];
542
552
  else return [...comments, ..._comments];
543
553
  } else {
544
554
  setAlert(
@@ -583,9 +593,7 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
583
593
  _comments,
584
594
  );
585
595
 
586
- if (_comments.length < commentsPerPage) {
587
- setCommentsLoaded(true);
588
- }
596
+ setCommentsPage((prev) => prev + 1);
589
597
 
590
598
  return [...comments, ..._comments];
591
599
  } else {
@@ -602,8 +610,8 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
602
610
  return comments;
603
611
  },
604
612
  {
605
- ready: !!owner && !!repo && !!issue && !getUserLoading && !commentsLoaded,
606
- refreshDeps: [commentsPage, issue, user, pagerDirection],
613
+ manual: true,
614
+ ready: !!owner && !!repo && !!issue && !getUserLoading,
607
615
  },
608
616
  );
609
617
 
@@ -643,6 +651,8 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
643
651
  logger.s(`Create issue comment successfully.`);
644
652
 
645
653
  setInputComment("");
654
+ setCommentsCount((prev) => prev + 1);
655
+
646
656
  onCreateComment?.(createdIssueComment);
647
657
 
648
658
  return localComments.concat([createdIssueComment]);
@@ -660,34 +670,50 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
660
670
 
661
671
  useEffect(() => {
662
672
  setComments([]);
663
- setCommentsCount(0);
673
+ setCommentsCount(issue?.comments ?? 0);
664
674
  setCommentsCursor("");
665
675
  setCommentsPage(1);
666
- setCommentsLoaded(false);
667
676
  setLocalComments([]);
668
677
 
669
- if (issue) {
670
- setCommentsCount(issue.comments);
671
- }
672
- }, [issue, user, pagerDirection, setComments, setLocalComments]);
678
+ setTimeout(() => {
679
+ runGetComments();
680
+ });
681
+ }, [issue, runGetComments, setComments, setLocalComments]);
682
+
683
+ useEffect(() => {
684
+ setComments([]);
685
+ setCommentsCursor("");
686
+ setCommentsPage(1);
687
+
688
+ setTimeout(() => {
689
+ runGetComments();
690
+ });
691
+ }, [user, commentsPagerDirection, setComments, runGetComments]);
673
692
 
674
693
  /** sorted all comments */
675
- const allComments = useMemo(() => {
676
- const _allComments = comments.concat(localComments);
694
+ const loadedComments = useMemo(() => {
695
+ const _loadedComments: CommentType[] = [];
696
+
697
+ // filter duplicate comments if exist
698
+ const commentIdsSet = new Set();
699
+ for (const comment of comments.concat(localComments)) {
700
+ if (!commentIdsSet.has(comment.id)) {
701
+ commentIdsSet.add(comment.id);
702
+ _loadedComments.push(comment);
703
+ }
704
+ }
677
705
 
678
- if (commentsPagerDirection === "last" && !!user) {
706
+ if (!!user && commentsPagerDirection === "last") {
679
707
  // sort comments by date DESC
680
- _allComments.reverse();
708
+ _loadedComments.reverse();
681
709
  }
682
710
 
683
- return _allComments;
711
+ return _loadedComments;
684
712
  }, [comments, commentsPagerDirection, localComments, user]);
685
713
 
686
- const allCommentsCount = commentsCount + (localComments ?? []).length;
687
-
688
714
  useEffect(() => {
689
- updateCountCallback?.(allCommentsCount);
690
- }, [allCommentsCount, updateCountCallback]);
715
+ updateCountCallback?.(commentsCount);
716
+ }, [commentsCount, updateCountCallback]);
691
717
 
692
718
  const {
693
719
  data: commentHtml = "",
@@ -1121,20 +1147,20 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
1121
1147
  return (
1122
1148
  <div className="gt-comments" key="comments">
1123
1149
  <FlipMove {...flipMoveOptions}>
1124
- {allComments.map((comment) => (
1150
+ {loadedComments.map((comment) => (
1125
1151
  <CommentWithForwardedRef key={comment.id} comment={comment} />
1126
1152
  ))}
1127
1153
  </FlipMove>
1128
- {!allCommentsCount && (
1154
+ {!commentsCount && (
1129
1155
  <p className="gt-comments-null">
1130
1156
  {polyglot.t("first-comment-person")}
1131
1157
  </p>
1132
1158
  )}
1133
- {!commentsLoaded && allCommentsCount ? (
1159
+ {commentsCount > loadedComments.length ? (
1134
1160
  <div className="gt-comments-controls">
1135
1161
  <Button
1136
1162
  className="gt-btn-loadmore"
1137
- onClick={() => setCommentsPage((prev) => prev + 1)}
1163
+ onClick={runGetComments}
1138
1164
  isLoading={getCommentsLoading}
1139
1165
  text={polyglot.t("load-more")}
1140
1166
  />
@@ -1153,8 +1179,8 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
1153
1179
  className="gt-counts"
1154
1180
  dangerouslySetInnerHTML={{
1155
1181
  __html: polyglot.t("counts", {
1156
- counts: `<a class="gt-link gt-link-counts" href="${issue?.html_url}" target="_blank" rel="noopener noreferrer">${allCommentsCount}</a>`,
1157
- smart_count: allCommentsCount,
1182
+ counts: `<a class="gt-link gt-link-counts" href="${issue?.html_url}" target="_blank" rel="noopener noreferrer">${commentsCount}</a>`,
1183
+ smart_count: commentsCount,
1158
1184
  }),
1159
1185
  }}
1160
1186
  />
@@ -1220,7 +1246,7 @@ const Gitalk: React.FC<GitalkProps> = (props) => {
1220
1246
  value={{ language, polyglot, dateFnsLocaleMap: DATE_FNS_LOCALE_MAP }}
1221
1247
  >
1222
1248
  <div
1223
- className={`gt-container ${isInputFocused ? "gt-input-focused" : ""} ${className}`}
1249
+ className={`gt-container${isInputFocused ? " gt-input-focused" : ""} ${className}`}
1224
1250
  {...restProps}
1225
1251
  >
1226
1252
  {alert && <div className="gt-error">{alert}</div>}
package/lib/i18n/index.ts CHANGED
@@ -13,7 +13,7 @@ import RU from "./ru.json";
13
13
  import ZHCN from "./zh-CN.json";
14
14
  import ZHTW from "./zh-TW.json";
15
15
 
16
- const i18nMap = {
16
+ export const i18nMap = {
17
17
  zh: ZHCN,
18
18
  "zh-CN": ZHCN,
19
19
  "zh-TW": ZHTW,
@@ -568,7 +568,6 @@ $gt-breakpoint-mobile: 479px;
568
568
 
569
569
  &::after {
570
570
  position: fixed;
571
- inset: 0 0 100%;
572
571
  content: '';
573
572
  opacity: 0;
574
573
  }
@@ -577,12 +576,11 @@ $gt-breakpoint-mobile: 479px;
577
576
  position: relative;
578
577
 
579
578
  &::after {
579
+ inset: 0;
580
580
  z-index: $gt-mask-z-index;
581
- background: #000;
582
- opacity: 0.6;
583
- transition:
584
- opacity 0.3s,
585
- bottom 0s;
581
+ background: #171717;
582
+ opacity: 0.8;
583
+ transition: opacity ease 0.3s;
586
584
  }
587
585
 
588
586
  .gt-header-comment {
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
package/package.json CHANGED
@@ -1,13 +1,17 @@
1
1
  {
2
2
  "name": "gitalk-react",
3
- "version": "1.0.0-beta.4",
3
+ "version": "1.0.0-beta.6",
4
4
  "private": false,
5
5
  "author": {
6
6
  "name": "LolipopJ",
7
7
  "email": "mail@towind.fun",
8
8
  "url": "https://github.com/LolipopJ"
9
9
  },
10
- "homepage": "https://github.com/LolipopJ/gitalk-react",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/LolipopJ/gitalk-react.git"
13
+ },
14
+ "homepage": "https://lolipopj.github.io/gitalk-react",
11
15
  "license": "MIT",
12
16
  "type": "module",
13
17
  "files": [
@@ -26,19 +30,22 @@
26
30
  "require": "./dist/gitalk.umd.cjs"
27
31
  },
28
32
  "./gitalk.css": "./dist/gitalk-light.css",
33
+ "./light.css": "./dist/gitalk-light.css",
29
34
  "./gitalk-light.css": "./dist/gitalk-light.css",
35
+ "./dark.css": "./dist/gitalk-dark.css",
30
36
  "./gitalk-dark.css": "./dist/gitalk-dark.css"
31
37
  },
32
38
  "types": "./dist/gitalk.d.ts",
33
39
  "scripts": {
34
- "dev": "vite",
35
- "build": "npm run build:ts && npm run build:scss",
40
+ "dev": "vite --config vite.config.preview.ts",
41
+ "build": "npm run build:lib && npm run build:preview",
42
+ "build:lib": "npm run build:ts && npm run build:scss",
36
43
  "build:ts": "tsc -b && vite build",
37
44
  "build:scss": "vite build --config vite.config.scss.ts",
45
+ "build:preview": "vite build --config vite.config.preview.ts",
38
46
  "lint": "npm run lint:ts && npm run lint:scss",
39
47
  "lint:ts": "eslint . --fix",
40
- "lint:scss": "stylelint lib/**/*.scss --fix",
41
- "preview": "vite preview"
48
+ "lint:scss": "stylelint **/*.scss --fix"
42
49
  },
43
50
  "dependencies": {
44
51
  "ahooks": "^3.0.0",